comp.lang.ada
 help / color / mirror / Atom feed
From: awdorrin <awdorrin@gmail.com>
Subject: Re: GNAT 4.4.5 Record Bit_Order Endian issues
Date: Thu, 17 Jan 2013 07:32:42 -0800 (PST)
Date: 2013-01-17T07:32:42-08:00	[thread overview]
Message-ID: <9961f0a1-aa2c-47d5-be84-77e495ea2a0f@googlegroups.com> (raw)
In-Reply-To: <85bocoqxis.fsf@stephe-leake.org>

On Wednesday, January 16, 2013 10:49:31 PM UTC-5, Stephen Leake wrote:

> 
> The best explanation I have seen is in
> http://www.ada-auth.org/ai-files/grab_bag/bitorder.pdf
> That introduces the concept of "machine scalar", which helps a lot.
> 
> The problem is what does "the first twelve bits" mean, when the
> "natural" size of a chunk of memory is 8 bits?

This is where the confusion comes from.

> 
> In this code:
> 
>    TRACK_ID at 0 range 0 .. 11;
>    TRACK_ID_CNT at 1 range 4 .. 9;
> 
> if Storage_Unit = 8, the two fields overlap. I can't figure out a
> storage arrangement that makes these fields contiguous; can you draw a
> picture? Changing to a compiler/target with a different Storage_Size
> changes the meaning.

The code in question was originally developed on a Motorola (Big Endian) CPU, So, given the Motorola 'Bit Order' being 'High_Order_First':

Byte: 0        1        2        3
Bits: 01234567 01234567 01234567 01234567

      00000000 00111111 11112222 22222233
      01234567 89012345 67890123 45678901
     
For a picture using the definition of:
 TRACK_ID at 0 range 0 .. 11;
 TRACK_ID_CNT at 1 range 4 .. 9;

Track Id starts at 'Byte 0, Bit 0 and extends to the 11th bit'

Byte:|0       |1        |2
Bits:|01234567|0123 4567|01234567
     |00000000|0011 1111|11112222
     |01234567|8901 2345|67890123
     |Track ID     |
              |0000 0000 00|11111|
              |0123 4567 89|01234|
                   |Track  |
                   |Id Cnt |


> 
> In this code: 
>       TRACK_ID     at 0 range  0 .. 11;
>       TRACK_ID_CNT at 0 range 12 .. 17;
>
> it's obvious that the fields are contiguous, and it's up to the compiler
> to ensure that happens.

I agree that this notation makes more sense, given Big Endian notation. But the question I have is, when can you start at a byte other than 0?


> Note that gnat agrees with me:
>
> > OP's way:
> > awdorrin.ads:13:26: info: reverse bit order in machine scalar of length 16
> > awdorrin.ads:13:26: info: little-endian range for component "Track_Id" is 4 .. 15
> > awdorrin.ads:15:06: component "Track_Id_Cnt" overlaps "Track_Id" at line 13
> > awdorrin.ads:15:30: info: reverse bit order in machine scalar of length 16
> > awdorrin.ads:15:30: info: little-endian range for component "Track_Id_Cnt" is 6 .. 11
> > gnatmake: "awdorrin.ads" compilation error
> 
> This says that the first code specifies overlapping fields, which is not
> what you want.
> 
> > Your way:
> > awdorrin.ads:13:26: info: reverse bit order in machine scalar of length 32
> > awdorrin.ads:13:26: info: little-endian range for component "Track_Id" is 20 .. 31
> > awdorrin.ads:14:30: info: reverse bit order in machine scalar of length 32
> > awdorrin.ads:14:30: info: little-endian range for component "Track_Id_Cnt" is 14 .. 19
> 
> This says the two fields occupy the 16 bits numbered 31 .. 19, and are
> consecutive.

As I just discovered after upgrading my system from Debian 6/GNAT 4.4.5 to Debian 7/GNAT 4.6; the GNAT 4.6 compiler produces the 'overlaps' error messages and will not compile. 

GNAT 4.4.5 does not produce this error, and compiles the definition into an overlapping field on an Intel/Little Endian target.

>
> Why do you say this is buggy?
>

The first issue is that GNAT 4.4.5 compiles the code without error and overlaps the fields, this is a bug in the 4.4.5 compiler (which I am glad has been caught with the 4.6 compiler.)

Given:
   TRACK_ID     at 0 range 0 .. 11;
   TRACK_ID_CNT at 1 range 4 .. 9; 

And this:
    TRACK_ID     at 0 range  0 .. 11;
    TRACK_ID_CNT at 0 range 12 .. 17; 

The 'Bit_Order = High_Order_First' means that the starting point from the left hand side is Byte 0, Bit 0, so I would expect the above two examples to produce the same code, based on the byte offsets acting as an index into the memory space.

Meaning that the following statements all define the same bit location, from a big endian/High order first notation:

'at 0 range  8.. 8' = 'at 1 range 0..0'
'at 0 range 32..32' = 'at 5 range 0..0'

Now, if the standard wants to say 'all data fields that span a group of bytes must be defined from the same starting byte', that would make sense to me. 

For example:
    TRACK_ID     at 0 range  0 .. 11;
    TRACK_ID_CNT at 0 range 12 .. 17;
    VAR1         at 0 range 18 .. 20;
    VAR2         at 0 range 21 .. 23;
    Byte1        at 3 range  0 .. 7;
    Int32Var     at 4 range  0 .. 31;

As for the 'A Proposal for Endian-Portable Record Representation Clauses' document, I take the proposal to mean that we should be defining the records as a multiple of a 'machine scalar' - which the document states could be 8-bit, 16-bit or 32-bit.

After further thought, I understand this to mean that our record definitions should fit the least common multiple that fits the span.

So, given my above example, defining 'Byte1' at starting at byte 3, would be wrong, since the first 'group' is 3 bytes (24-bits) and instead should be an even multiple (ie. 32-bits), so:

    TRACK_ID     at 0 range  0 .. 11;
    TRACK_ID_CNT at 0 range 12 .. 17;
    VAR1         at 0 range 18 .. 20;
    VAR2         at 0 range 21 .. 23;
    Byte1        at 0 range 24 .. 31;
    Int32Var     at 4 range  0 .. 31;

I would assume, that if the record needed the 'Byte1' and 'Int32Var' elements swapped physically that the definition would need to be bumped from a '32-bit' base, to a 64-bit base:

    TRACK_ID     at 0 range  0 .. 11;
    TRACK_ID_CNT at 0 range 12 .. 17;
    VAR1         at 0 range 18 .. 20;
    VAR2         at 0 range 21 .. 23;
    Int32Var     at 0 range 24 .. 55;
    Byte1        at 0 range 56 .. 63;
    Int32Var2    at 8 range  0 .. 31;

While I understand the rationale of defining the records using this methodology, it requires that the programmer knows that the 'starting byte' has restrictions.

Rather than put this expectation on the programmer, it seems like something best left to the compiler to work out.

So if I write 'Track_ID_Cnt at 1 range 4 .. 7' the compiler should be able to translate that for me to: 'Track_Id_Cnt at 0 range 12 .. 17' (etc)

-Al



  reply	other threads:[~2013-01-17 15:32 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-14 17:43 GNAT 4.4.5 Record Bit_Order Endian issues awdorrin
2013-01-15  0:38 ` Randy Brukardt
2013-01-15  1:57 ` Adam Beneschan
2013-01-15 16:57 ` AdaMagica
2013-01-15 22:24 ` Stephen Leake
2013-01-16 10:44   ` Simon Wright
2013-01-16 19:00     ` AdaMagica
2013-01-16 21:34       ` Simon Wright
2013-01-16 23:14     ` Randy Brukardt
2013-01-17  3:49     ` Stephen Leake
2013-01-17 15:32       ` awdorrin [this message]
2013-01-18  9:49         ` Stephen Leake
2013-01-18 13:04           ` Robert A Duff
2013-01-19  1:43             ` Stephen Leake
2013-01-19 12:48               ` AdaMagica
2013-01-22  0:14                 ` Randy Brukardt
2013-01-17 17:28       ` Simon Wright
2013-01-18  9:56         ` Stephen Leake
2013-01-17 18:04 ` awdorrin
2013-01-17 19:50   ` awdorrin
2013-01-18  9:58     ` Stephen Leake
2013-01-17 20:58   ` Simon Wright
2013-01-17 21:29     ` awdorrin
2013-01-17 22:16       ` awdorrin
2013-01-18  6:15         ` J-P. Rosen
2013-01-18 15:28           ` Niklas Holsti
2013-01-18  9:37         ` Stephen Leake
2013-01-18 12:24         ` awdorrin
2013-01-18 15:11           ` awdorrin
2013-01-19  1:48             ` Stephen Leake
2013-01-18 17:19           ` Simon Wright
2013-01-22  9:49           ` quinot
2013-01-28 13:39             ` quinot
  -- strict thread matches above, loose matches on Subject: below --
2013-01-22  3:21 Stephen Leake
2013-01-22  5:14 ` Jeffrey Carter
2013-01-23  1:29   ` Stephen Leake
2013-01-22 22:40 ` Randy Brukardt
2013-01-23  1:38   ` Stephen Leake
2013-01-23 10:58     ` Simon Wright
replies disabled

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