From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.236.92.69 with SMTP id i45mr4141030yhf.20.1404244346157; Tue, 01 Jul 2014 12:52:26 -0700 (PDT) X-Received: by 10.182.98.136 with SMTP id ei8mr20587obb.39.1404244346042; Tue, 01 Jul 2014 12:52:26 -0700 (PDT) Path: buffer2.nntp.dca1.giganews.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!i13no5016597qae.1!news-out.google.com!gf2ni2855igb.0!nntp.google.com!uq10no604141igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Tue, 1 Jul 2014 12:52:25 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=90.219.105.227; posting-account=qa2LvwoAAADwbTxJVBI5rHWSlh3aClXp NNTP-Posting-Host: 90.219.105.227 References: <0e0b9ac2-e793-4cc5-8d8d-d3441ca28a58@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: Forcing GNAT to use 32-bit load/store instructions on ARM? From: daniel.dmk@googlemail.com Injection-Date: Tue, 01 Jul 2014 19:52:26 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Xref: number.nntp.dca.giganews.com comp.lang.ada:187316 Date: 2014-07-01T12:52:25-07:00 List-Id: Thank you everyone for your suggestions and comments.=20 On Tuesday, 1 July 2014 13:03:30 UTC+1, Simon Clubley wrote: >=20 > In the general case, you need to initialise those reserved bits to known >=20 > values; to not do this is too dangerous. I always do this in C and if I >=20 > was doing embedded code in Ada I would do the same thing in Ada as well. Thanks for this suggestion, I'll define the reserved bits in the register, = and use static checks to enforce that they are not modified from their rese= t value in the code. > > However, this makes it more "clunky" to use in my opinion. I would pref= er to >=20 > > be able to modify the bits directly, and have the compiler always use 3= 2-bit >=20 > > load/store instructions. >=20 > > >=20 > > Does anyone else have any ideas that I could try? >=20 > > >=20 >=20 >=20 > Pragma Atomic _should_ have given you the guarantee you needed. >=20 > Are you double checked how it's being used in the code ? So I've set up a project to demonstrate only this problem. I've created a p= ackage called "Test" which contains the structure definition, and the defin= ition of the register itself at the fixed address: with System; package Test is type Bits_1 is mod 2**1 with Size =3D> 1; type Bits_2 is mod 2**2 with Size =3D> 2; type Bits_28 is mod 2**28 with Size =3D> 28; =20 type CR_Register is record Reserved_1 : Bits_2; RNGEN : Bits_1; IE : Bits_1; Reserved_2 : Bits_28; end record; for CR_Register use record Reserved_1 at 0 range 0 .. 1; RNGEN at 0 range 2 .. 2; IE at 0 range 3 .. 3; Reserved_2 at 0 range 4 .. 31; end record; for CR_Register'Size use 32; CR : CR_Register with Volatile, Atomic, Address =3D> System'To_Address(16#5006_0800#); end Test; So I've now defined the reserved bits in the register, and I have added "At= omic" to the CR register. In my main procedure I have the following: with System; with Test; procedure Main with SPARK_Mode =3D> On is pragma Priority(System.Priority'First); =20 begin =20 Test.CR.RNGEN :=3D 1; =20 loop null; end loop; end Main; The line where I assign the RNGEN bit produces the following assembly code = (using no optimization: -O0): mov.w r3, #2048 ; 0x800 movt r3, #20486 ; 0x5006 ldrb r2, [r3, #0] orr.w r2, r2, #4 strb r2, [r3, #0] As you can see, it is using byte load/store instructions. So even when using Atomic, and when defining the other bits in the register= it is still using the byte load/store instructions. The same assmebly code= is generated at all optimization levels. For reference, here's the code when I use a temporary copy of the register: declare Temp : Test.CR_Register; begin Temp :=3D Test.CR; Temp.RNGEN :=3D 1; Test.CR :=3D Temp; end; produces the following assembly code (the 3 segements of asm correspond to = each of the 3 lines of code): mov.w r3, #2048 ; 0x800 movt r3, #20486 ; 0x5006 ldr r3, [r3, #0] str r3, [r7, #4] =20 ldr r3, [r7, #4] orr.w r3, r3, #4 str r3, [r7, #4] =20 mov.w r3, #2048 ; 0x800 movt r3, #20486 ; 0x5006 ldr r2, [r7, #4] str r2, [r3, #0] In this case, it is always using the word load/store instructions (ldr and = str). Here is the same code when optimization is enabled (-O1): mov.w r3, #2048 ; 0x800 movt r3, #20486 ; 0x5006 ldr r2, [r3, #0] orr.w r2, r2, #4 str r2, [r3, #0] So could there be a problem with GNAT's Atomic on ARM? I think the approach that I will take for the time being is to always use a= temporary when reading/writing the registers. I can hide the registers beh= ind procedures to enforce this access, and to also add pre/post conditions = to enforce that the reserved bits are not modified from their reset value. I would like to avoid machine code insertions if possible, since I would li= ke to remain inside SPARK 2014 as much as possible (machine code insertions= are not in SPARK 2014).