From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by sourceware.org (Postfix) with ESMTPS id D509B3858D35 for ; Mon, 13 Sep 2021 08:44:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D509B3858D35 Received: by mail-wm1-x32c.google.com with SMTP id j17-20020a05600c1c1100b002e754875260so5999009wms.4 for ; Mon, 13 Sep 2021 01:44:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=RpBl//o3HtGuYQEGQwg10SiYbHoRaQbteTz5l3Ewi9I=; b=VVLSJ5lP2ApATWy1Em4Gw/MA2g0kfa3JlbGAwKf/04ptxEdFOWORBZ5ie5oMRNklao xL1cv1hu0QmPKl4TZWSSmKEFI8eMooh+tOM5bXFbq5D0oVPh/H4JKhSNbArAzhhGtcJX O0Z9MS1BAKbDOT82IEWcNdbc6oUavwoXlFCFC/tLfFnfRaMkfBrwXeUpZ0B4YDq1Y8p0 C7eRd3DCGkbevKysSf9s+sHUlZcSCE+MPppV+VfsQ2cxRIKPmuPcWVXmETOPau8Lfj+9 z5f8OYU6xqb/TqACYuYMEz7RS1mgw5gMVdqyyH/jxe9bFR2wiFhqIePHx6ZZw1aemtkl YqwQ== X-Gm-Message-State: AOAM530ss5eK3s7PSO+48jbHS1hMvwakAPBgRmmRwCSAphYD71UC08EN nBoD03S2xmY7dPuY87gWJJ0Jaju5QCWxeGwKhHTYOKSJ X-Google-Smtp-Source: ABdhPJyL8Fuqb6q1LW0iSX45rQOGeTFOrEg4Ar5+E2DEHvmjH3CSXxARrBeSTMV61jjGPGsT1pWuYc3n/h7kLk2bCDY= X-Received: by 2002:a7b:c3d0:: with SMTP id t16mr9966628wmj.169.1631522695796; Mon, 13 Sep 2021 01:44:55 -0700 (PDT) MIME-Version: 1.0 References: <34090ee9-8554-9c35-ed2a-3ded1369a4dc@ztk-rp.eu> In-Reply-To: <34090ee9-8554-9c35-ed2a-3ded1369a4dc@ztk-rp.eu> From: Jonathan Wakely Date: Mon, 13 Sep 2021 09:44:44 +0100 Message-ID: Subject: Re: a feature to the wishlist To: =?UTF-8?Q?Rafa=C5=82_Pietrak?= Cc: "gcc@gcc.gnu.org" Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=no autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Sep 2021 08:44:58 -0000 On Mon, 13 Sept 2021 at 07:55, Rafa=C5=82 Pietrak via Gcc = wrote: > > Hi everybody, > > I've been using GCC for a varety of ARM micro controller project. With > embedded systems, one often has to access specific memory locations, > which contain hardware registers, that control device behavior. > "traditionally" or "commonly" that's codded by programmers using > "#define", thus relaying on preprocessor to put specific compiler > constructs, that do the job. > > IMHO, this is wrong exactly because of the involvement of preprocessor. > Taking as an example exerpts from libopencm3, like: > >> USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID) > one can understand, that such "code" can actually translate to quite > anything. > > Getting to the point, here is code exerpt of by own STM32 usart driver: > ------------------------------------------------------------------ > #define USART_RE 11 > #define USART_RENEIE 8 > #define USART_TE 10 > #define USART_TXEIE 6 > #define USART_UE 0 > > extern struct usart_s { > uint sr; > uint dr; // offset 0x04 > uint brr; // offset 0x08 > volatile union { uint cr1; // offset 0x0C > struct cr_s { uint sbk:1, rwu:1, > re:1, te:1, idleie:1, rxneie:1, > tcie:1, txeie:1, peie:1, ps:1, > pce:1, wake:1, m:1, ue:1;} cr1_s; > }; > } USART1; > > static void EXIT(void *tty) { > volatile struct usart_s *d =3D &USART1; > > #if VARIANT_TRADITIONAL > d->cr1 &=3D ~(1 << USART_RE) & ~(1 << USART_RXNEIE) > & ~(1 << USART_TE) & ~(1 << USART_TXEIE) > & ~(1 << USART_UE); > #elif VARIANT_WORKING > struct cr_s a =3D (struct cr_s) { > .re =3D 1, > .te =3D 1, > .rxneie =3D 1, > .txeie =3D 1, > .ue =3D 1 }; > int *b =3D (int *) &a; > d->cr1 &=3D ~(*b); This is a strict aliasing violation. You should either use a union or memcpy to get the value as an int. > #elif VARIANT_BETTER > (union cr_u) d->cr1 &=3D ~ { > .re =3D 1, > .te =3D 1, > .rxneie =3D 1, > .txeie =3D 1, > .ue =3D 1 }; > #elif VARIANT_THE_BEST > d->cr1_s &=3D ~ { .re =3D 1, > .te =3D 1, > .rxneie =3D 1, > .txeie =3D 1, > .ue =3D 1 }; > #endif > } > ---------------------------------------------------------------- > > In function EXIT, you can see four variants of "the same code". First > fragment is codded just like todays common practice is. This is BAD > coding, because debugger has no way of presenting "the real thing". Have you tried -ggdb3 which does preserve macro information? > Using gcc-8-branch revision 273027 (arm-none-eabi-gcc linux cross > compiler) I was able to code the very same thing by VARIANT_WORKING, > which is far better to read (IMHO). The disadvantage is, that I had to > use variable "b" to fool gcc syntax parser. No direct multiple "type > overwrite" worked for me. > > Then again, it would be even better (and easier to read the code), > should gcc syntax parser recognised VARIANT_BETTER or VARIANT_THE_BEST > as "syntactic sugar" to generate code, that currently gets issued by > VARIANT_WORKING (being the same as issued by VARIANT_TRADITIONAL, which > is very OK). You can define an inline function that initializes the struct, then returns the negation of the int value. I very much doubt GCC will add an extension to make ~ work on structs. What would it even mean if sizeof(struct cr_s) =3D=3D 3 or =3D=3D 1024?