comp.lang.ada
 help / color / mirror / Atom feed
* Compiler doesn't respect 'Size for atomic object
@ 2017-12-20 12:35 Simon Wright
  2017-12-20 19:23 ` Simon Clubley
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Wright @ 2017-12-20 12:35 UTC (permalink / raw)


The code below is an abstract of one for a Cortex-M processor; it
generates an external interrupt, useful for testing.

All released GNAT compilers I have access to and which accept the syntax
(GPL 2015+, FSF GCC 5+) produce the result that the hardware needs and
that I intended, i.e. 16#1#.

GCC 8, which is still under development, produces 16#FFFFFF01#, i.e. has
only written the least significant byte.

I'm pretty sure this is an error, rather than an unhelpful
interpretation: can anyone confirm one way or the other, before I raise
a bug, please?

========================================================================
with Ada.Text_IO;
with Interfaces;

procedure Full_Word is

   Register : Interfaces.Unsigned_32;

   type Interrupt_ID is range 0 .. 44;

   procedure Trigger_Interrupt (IRQ : Interrupt_ID) is
      --  The Software Trigger Interrupt Register.
      NVIC_STIR : Interrupt_ID
      with
        Import,
        Atomic,
        Size    => 32,
        Address => Register'Address;

   begin
      NVIC_STIR := IRQ;                   -- h/w requires 32-bit write
   end Trigger_Interrupt;

   package Unsigned_32_IO
     is new Ada.Text_IO.Modular_IO (Interfaces.Unsigned_32);

begin
   Register := 16#ffff_ffff#;
   Trigger_Interrupt (1);
   Unsigned_32_IO.Put (Register, Base => 16);
   Ada.Text_IO.New_Line;
end Full_Word;


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-20 12:35 Compiler doesn't respect 'Size for atomic object Simon Wright
@ 2017-12-20 19:23 ` Simon Clubley
  2017-12-20 20:19   ` Simon Wright
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Clubley @ 2017-12-20 19:23 UTC (permalink / raw)


On 2017-12-20, Simon Wright <simon@pushface.org> wrote:
> The code below is an abstract of one for a Cortex-M processor; it
> generates an external interrupt, useful for testing.
>
> All released GNAT compilers I have access to and which accept the syntax
> (GPL 2015+, FSF GCC 5+) produce the result that the hardware needs and
> that I intended, i.e. 16#1#.
>
> GCC 8, which is still under development, produces 16#FFFFFF01#, i.e. has
> only written the least significant byte.
>
> I'm pretty sure this is an error, rather than an unhelpful
> interpretation: can anyone confirm one way or the other, before I raise
> a bug, please?
>

And an old friend (for various values of "friend" :-)) has raised
its head again.

A skim through AI12-0128 might be useful although my AI only
refers to components within an atomic composite object.

My instinct is that this is a compiler problem although I don't
know if something is going on due to you extending the underlying
data type to 32 bits.

If you use a naturally 32-bit variable instead of your Interrupt_ID
data type, does it work ok ?

Simon.

>========================================================================
> with Ada.Text_IO;
> with Interfaces;
>
> procedure Full_Word is
>
>    Register : Interfaces.Unsigned_32;
>
>    type Interrupt_ID is range 0 .. 44;
>
>    procedure Trigger_Interrupt (IRQ : Interrupt_ID) is
>       --  The Software Trigger Interrupt Register.
>       NVIC_STIR : Interrupt_ID
>       with
>         Import,
>         Atomic,
>         Size    => 32,
>         Address => Register'Address;
>
>    begin
>       NVIC_STIR := IRQ;                   -- h/w requires 32-bit write
>    end Trigger_Interrupt;
>
>    package Unsigned_32_IO
>      is new Ada.Text_IO.Modular_IO (Interfaces.Unsigned_32);
>
> begin
>    Register := 16#ffff_ffff#;
>    Trigger_Interrupt (1);
>    Unsigned_32_IO.Put (Register, Base => 16);
>    Ada.Text_IO.New_Line;
> end Full_Word;


-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-20 19:23 ` Simon Clubley
@ 2017-12-20 20:19   ` Simon Wright
  2017-12-20 20:45     ` Simon Clubley
  2017-12-20 21:20     ` Simon Wright
  0 siblings, 2 replies; 12+ messages in thread
From: Simon Wright @ 2017-12-20 20:19 UTC (permalink / raw)


Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:

> If you use a naturally 32-bit variable instead of your Interrupt_ID
> data type, does it work ok ?

Yes. My workround is to declare the atomic object as Integer, and
convert the Interrupt_ID to Integer (the ARM says only that Interrupt_ID
is discrete, but that's a bridge to cross when we come to it; it's
naturally an Integer on Cortex-M).

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-20 20:19   ` Simon Wright
@ 2017-12-20 20:45     ` Simon Clubley
  2017-12-21  7:10       ` Randy Brukardt
  2017-12-20 21:20     ` Simon Wright
  1 sibling, 1 reply; 12+ messages in thread
From: Simon Clubley @ 2017-12-20 20:45 UTC (permalink / raw)


On 2017-12-20, Simon Wright <simon@pushface.org> wrote:
> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:
>
>> If you use a naturally 32-bit variable instead of your Interrupt_ID
>> data type, does it work ok ?
>
> Yes. My workround is to declare the atomic object as Integer, and
> convert the Interrupt_ID to Integer (the ARM says only that Interrupt_ID
> is discrete, but that's a bridge to cross when we come to it; it's
> naturally an Integer on Cortex-M).

Unless Randy and company come up with something around the use of
Size to extend the size of the base data type[*], I would consider
this to be a compiler bug.

[*] That qualifier is there because I seem to have a vague
recollection of previous discussions around problems that
occurred when Size was used to extend a data type but I can't
remember the details.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-20 20:19   ` Simon Wright
  2017-12-20 20:45     ` Simon Clubley
@ 2017-12-20 21:20     ` Simon Wright
  2017-12-21  5:55       ` Robert Eachus
  1 sibling, 1 reply; 12+ messages in thread
From: Simon Wright @ 2017-12-20 21:20 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:
>
>> If you use a naturally 32-bit variable instead of your Interrupt_ID
>> data type, does it work ok ?
>
> Yes. My workround is to declare the atomic object as Integer, and
> convert the Interrupt_ID to Integer (the ARM says only that Interrupt_ID
> is discrete, but that's a bridge to cross when we come to it; it's
> naturally an Integer on Cortex-M).

I meant, naturally an integral type. The RM description of the NVIC's
STIR indicates that the IRQ fits in 8 bits; the top 24 bits are reserved
(write as 0).

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-20 21:20     ` Simon Wright
@ 2017-12-21  5:55       ` Robert Eachus
  2017-12-21 14:02         ` Simon Wright
  2017-12-21 22:02         ` Simon Wright
  0 siblings, 2 replies; 12+ messages in thread
From: Robert Eachus @ 2017-12-21  5:55 UTC (permalink / raw)


On Wednesday, December 20, 2017 at 4:20:22 PM UTC-5, Simon Wright wrote:

> I meant, naturally an integral type. The RM description of the NVIC's
> STIR indicates that the IRQ fits in 8 bits; the top 24 bits are reserved
> (write as 0).

A language lawyer reading:  If the hardware specifies that those bit must be zero?  Then it is definitely a bug.  But if all the hardware says is that the positions are reserved, I would expect the compiler to pass whatever junk happened to be in the register.  (In other words, move the IRQ as eight-bits to a register, then pass the register to the hardware.)

Should the address of Register in your example be set to 16#E000EF00#? Also should your type Interrupt_ID be given a size?  If so I would expect the new behavior with Interrupt_ID'Size set to 8, and the old behavior when it is set to 32.

I am certainly not an expert on the Cortex-M CPUs, but as I read the documentation, the STIR is write-only, and the upper 24-bits of the value written there are ignored.  If so, no bug, but probably worth a comment IF the behavior of the compiler has changed, not just the bits you are passing..

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-20 20:45     ` Simon Clubley
@ 2017-12-21  7:10       ` Randy Brukardt
  2017-12-21 14:08         ` Simon Wright
  0 siblings, 1 reply; 12+ messages in thread
From: Randy Brukardt @ 2017-12-21  7:10 UTC (permalink / raw)


"Simon Clubley" <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote in 
message news:p1ei5v$fqc$1@dont-email.me...
> On 2017-12-20, Simon Wright <simon@pushface.org> wrote:
>> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:
>>
>>> If you use a naturally 32-bit variable instead of your Interrupt_ID
>>> data type, does it work ok ?
>>
>> Yes. My workround is to declare the atomic object as Integer, and
>> convert the Interrupt_ID to Integer (the ARM says only that Interrupt_ID
>> is discrete, but that's a bridge to cross when we come to it; it's
>> naturally an Integer on Cortex-M).
>
> Unless Randy and company come up with something around the use of
> Size to extend the size of the base data type[*], I would consider
> this to be a compiler bug.

I tend to agree. The reason is 13.1(7/2). The extra bits in this case are 
defined to be "padding bits", and 13.1(7/2) says that "padding bits are 
normally read and updated along with the others".

AI12-0128-1 adds some rules for non-atomic subcomponents of atomic objects, 
but it shouldn't change the behavior of an *elementary* atomic object, like 
this one. Perhaps GNAT is treating this like a record type with two 
components, the actual integer value, and some padding bits. Then it would 
be right. (But that's not how the language defines this object.)

Still, you'll always have less issues if you avoid padding bits and have the 
subtype Object_Size (this is now in Ada 2020, so we can talk about it) be 
32.

Which is something you (Simon Wright, not Simon Clubley) might try, since 
Object_Size can be specified for any subtype. So try declaring:

    subype Simons_Interrupt_Id is Interrupt_Id with Object_Size => 32;

and declare your object of that subtype. Then there are no padding bits (as 
defined  by 13.1(7.2)).

                            Randy.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-21  5:55       ` Robert Eachus
@ 2017-12-21 14:02         ` Simon Wright
  2017-12-21 22:02         ` Simon Wright
  1 sibling, 0 replies; 12+ messages in thread
From: Simon Wright @ 2017-12-21 14:02 UTC (permalink / raw)


Robert Eachus <rieachus@comcast.net> writes:

> On Wednesday, December 20, 2017 at 4:20:22 PM UTC-5, Simon Wright wrote:
>
>> I meant, naturally an integral type. The RM description of the NVIC's
>> STIR indicates that the IRQ fits in 8 bits; the top 24 bits are reserved
>> (write as 0).

> Should the address of Register in your example be set to 16#E000EF00#?
> Also should your type Interrupt_ID be given a size?  If so I would
> expect the new behavior with Interrupt_ID'Size set to 8, and the old
> behavior when it is set to 32.

This was an example to demo the behaviour on the desktop, mimicing the
real code as far as possible; I wouldn't expect the compiler to behave
differently as far as assign-to-atomic is converned between arm-eabi &
x86_64-apple-darwin. STIR is indeed at 16#E000EF00#.

Looking at Adacore's RTS ravenscar-sfp-stm32f4 in GNAT GPL 2017, I see
(after delving through several layers of package) in
System.BB.Parameters

   subtype Interrupt_Range is Integer
     range -1 .. MCU_Parameters.Number_Of_Interrupts;

so if I'd followed this style Interrupt_ID would have been 32-bits from
the start.

In my defence, in e.g. GNAT GPL 2015 I see in System.Interrupts

   type Ada_Interrupt_ID is range 0 .. System.OS_Interface.Max_Interrupt;

> I am certainly not an expert on the Cortex-M CPUs, but as I read the
> documentation, the STIR is write-only, and the upper 24-bits of the
> value written there are ignored.  If so, no bug, but probably worth a
> comment IF the behavior of the compiler has changed, not just the bits
> you are passing..

I was taught that if the specification says a bit is reserved you
need to ensure that you never write a 1 to it (in case some later
revision should assign a meaning to that).

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-21  7:10       ` Randy Brukardt
@ 2017-12-21 14:08         ` Simon Wright
  0 siblings, 0 replies; 12+ messages in thread
From: Simon Wright @ 2017-12-21 14:08 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> Still, you'll always have less issues if you avoid padding bits and
> have the subtype Object_Size (this is now in Ada 2020, so we can talk
> about it) be 32.
>
> Which is something you (Simon Wright, not Simon Clubley) might try,
> since Object_Size can be specified for any subtype. So try declaring:
>
>     subype Simons_Interrupt_Id is Interrupt_Id with Object_Size => 32;
>
> and declare your object of that subtype. Then there are no padding
> bits (as defined by 13.1(7.2)).

Works a treat! Thanks!

(and Object_Size is available in GNAT back to at least 2015)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-21  5:55       ` Robert Eachus
  2017-12-21 14:02         ` Simon Wright
@ 2017-12-21 22:02         ` Simon Wright
  2017-12-22  4:51           ` Robert Eachus
  1 sibling, 1 reply; 12+ messages in thread
From: Simon Wright @ 2017-12-21 22:02 UTC (permalink / raw)


Robert Eachus <rieachus@comcast.net> writes:

> I am certainly not an expert on the Cortex-M CPUs, but as I read the
> documentation, the STIR is write-only, and the upper 24-bits of the
> value written there are ignored.

It turns out that declaring NVIC_STIR as Unsigned_32 and writing

      NVIC_STIR := 16#ffff_ff00# or Interfaces.Unsigned_32 (IRQ);

doesn't generate an interrupt.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-21 22:02         ` Simon Wright
@ 2017-12-22  4:51           ` Robert Eachus
  2017-12-22 10:21             ` Simon Wright
  0 siblings, 1 reply; 12+ messages in thread
From: Robert Eachus @ 2017-12-22  4:51 UTC (permalink / raw)


On Thursday, December 21, 2017 at 5:02:07 PM UTC-5, Simon Wright wrote:
> Robert Eachus <rieachus@comcast.net> writes:

> It turns out that declaring NVIC_STIR as Unsigned_32 and writing
> 
>       NVIC_STIR := 16#ffff_ff00# or Interfaces.Unsigned_32 (IRQ);
> 
> doesn't generate an interrupt.

It took me a while to figure out what you were saying.  I really need to find a way to post here that will allow things like boldfacing Ada reserved words.  After I parsed the or as Ada not English, I still have a problem. that I don't know the value passed as IRQ.  I assume it is a valid interrupt number for an unprivileged program.

You should report this to Ada Core as a bug.  I'm just not convinced it is an Ada bug or a compiler front end bug, not a Cortex-M code generator bug.  


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Compiler doesn't respect 'Size for atomic object
  2017-12-22  4:51           ` Robert Eachus
@ 2017-12-22 10:21             ` Simon Wright
  0 siblings, 0 replies; 12+ messages in thread
From: Simon Wright @ 2017-12-22 10:21 UTC (permalink / raw)


Robert Eachus <rieachus@comcast.net> writes:

> On Thursday, December 21, 2017 at 5:02:07 PM UTC-5, Simon Wright wrote:
>> Robert Eachus <rieachus@comcast.net> writes:
>
>> It turns out that declaring NVIC_STIR as Unsigned_32 and writing
>> 
>>       NVIC_STIR := 16#ffff_ff00# or Interfaces.Unsigned_32 (IRQ);
>> 
>> doesn't generate an interrupt.
>
> It took me a while to figure out what you were saying.  I really need
> to find a way to post here that will allow things like boldfacing Ada
> reserved words.  After I parsed the or as Ada not English, I still
> have a problem. that I don't know the value passed as IRQ.  I assume
> it is a valid interrupt number for an unprivileged program.

In the example I posted upthread,

   type Interrupt_ID is range 0 .. 44;

> You should report this to Ada Core as a bug.  I'm just not convinced
> it is an Ada bug or a compiler front end bug, not a Cortex-M code
> generator bug.

Reported (via GCC bugzilla, since we're talking GCC 8); accepted; fixed
(r255958).

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-12-22 10:21 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-20 12:35 Compiler doesn't respect 'Size for atomic object Simon Wright
2017-12-20 19:23 ` Simon Clubley
2017-12-20 20:19   ` Simon Wright
2017-12-20 20:45     ` Simon Clubley
2017-12-21  7:10       ` Randy Brukardt
2017-12-21 14:08         ` Simon Wright
2017-12-20 21:20     ` Simon Wright
2017-12-21  5:55       ` Robert Eachus
2017-12-21 14:02         ` Simon Wright
2017-12-21 22:02         ` Simon Wright
2017-12-22  4:51           ` Robert Eachus
2017-12-22 10:21             ` Simon Wright

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox