From: Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP>
Subject: Re: Forcing GNAT to use 32-bit load/store instructions on ARM?
Date: Tue, 1 Jul 2014 20:40:31 +0000 (UTC)
Date: 2014-07-01T20:40:31+00:00 [thread overview]
Message-ID: <lov6bu$j0s$1@dont-email.me> (raw)
In-Reply-To: ca6f05d3-c469-4abc-92df-54aa605f41ba@googlegroups.com
On 2014-07-01, daniel.dmk@googlemail.com <daniel.dmk@googlemail.com> wrote:
> Thank you everyone for your suggestions and comments.
>
> On Tuesday, 1 July 2014 13:03:30 UTC+1, Simon Clubley wrote:
>>
>> Pragma Atomic _should_ have given you the guarantee you needed.
>>
>> 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 package called "Test" which contains the structure definition, and the definition of the register itself at the fixed address:
>
> with System;
>
> package Test is
> type Bits_1 is mod 2**1 with Size => 1;
> type Bits_2 is mod 2**2 with Size => 2;
> type Bits_28 is mod 2**28 with Size => 28;
>
> 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 => System'To_Address(16#5006_0800#);
> end Test;
>
> So I've now defined the reserved bits in the register, and I have added "Atomic" to the CR register.
>
> In my main procedure I have the following:
>
> with System;
> with Test;
>
> procedure Main
> with SPARK_Mode => On
> is
> pragma Priority(System.Priority'First);
>
> begin
>
> Test.CR.RNGEN := 1;
>
> 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]
>
This is the exact same issue I encountered when I tried to use bitfields
in C instead of bitmasks. The difference here is that Ada's Atomic pragma
is supposed to stop this type of code from being generated.
> 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 := Test.CR;
> Temp.RNGEN := 1;
> Test.CR := 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]
>
> ldr r3, [r7, #4]
> orr.w r3, r3, #4
> str r3, [r7, #4]
>
> mov.w r3, #2048 ; 0x800
> movt r3, #20486 ; 0x5006
> ldr r2, [r7, #4]
> str r2, [r3, #0]
>
This is exactly the kind of ARM code I would expect to see generated.
> 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?
>
Yes, big time.
The Atomic pragma is making a guarantee which is not being honoured by
the gcc ARM code generator.
> 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 behind
> 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.
>
You would need to use a temporary variable anyway if you need to update
multiple bitfields at the same time as part of an atomic register update.
> I would like to avoid machine code insertions if possible, since I would like
> to remain inside SPARK 2014 as much as possible (machine code insertions are
> not in SPARK 2014).
If you need to do things like manipulate the CPSR or the ARM coprocessor
registers, then this might not be possible.
Simon.
--
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world
next prev parent reply other threads:[~2014-07-01 20:40 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-30 22:11 Forcing GNAT to use 32-bit load/store instructions on ARM? daniel.dmk
2014-06-30 23:41 ` Jeffrey Carter
2014-07-01 12:06 ` Simon Clubley
2014-07-01 15:44 ` Niklas Holsti
2014-07-01 17:26 ` Simon Clubley
2014-07-01 17:18 ` Simon Wright
2014-07-01 19:43 ` Simon Wright
2014-07-01 17:28 ` Jeffrey Carter
2014-07-01 0:55 ` anon
2014-07-01 4:30 ` Niklas Holsti
2014-07-01 8:11 ` Dmitry A. Kazakov
2014-07-01 12:09 ` Simon Clubley
2014-07-01 12:20 ` Dmitry A. Kazakov
2014-07-01 17:00 ` Simon Clubley
2014-07-01 19:36 ` Dmitry A. Kazakov
2014-07-01 20:08 ` Simon Clubley
2014-07-02 22:24 ` Randy Brukardt
2014-07-06 20:40 ` MatthiasR
2014-07-07 0:25 ` Simon Clubley
2014-07-07 22:38 ` Randy Brukardt
2014-07-08 6:51 ` Simon Wright
2014-07-10 11:47 ` Simon Wright
2014-07-10 13:06 ` Simon Clubley
2014-07-11 18:05 ` Simon Wright
2014-07-11 20:22 ` Simon Clubley
2014-07-08 8:50 ` Brian Drummond
2014-07-08 12:12 ` Simon Clubley
2014-07-08 13:26 ` G.B.
2014-07-08 17:13 ` Simon Clubley
2014-07-08 15:36 ` Adam Beneschan
2014-07-08 15:40 ` Adam Beneschan
2014-07-08 20:34 ` Randy Brukardt
2014-07-09 7:31 ` Dmitry A. Kazakov
2014-07-10 0:11 ` Simon Clubley
2014-07-20 11:35 ` MatthiasR
2014-07-20 15:49 ` Simon Clubley
2014-07-26 11:05 ` MatthiasR
2014-08-10 11:20 ` MatthiasR
2014-07-01 12:03 ` Simon Clubley
2014-07-01 19:52 ` daniel.dmk
2014-07-01 20:40 ` Simon Clubley [this message]
2014-07-01 20:55 ` Simon Clubley
2014-07-01 21:01 ` Niklas Holsti
2014-07-01 21:20 ` Simon Clubley
2014-07-01 22:38 ` Niklas Holsti
2014-07-02 16:49 ` Simon Clubley
2014-07-01 21:55 ` daniel.dmk
2014-07-02 7:30 ` Simon Wright
2014-07-02 18:52 ` daniel.dmk
2014-07-04 23:51 ` Niklas Holsti
2014-07-05 0:18 ` Niklas Holsti
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox