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=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,7b60a2e8329f4e64 X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit X-Received: by 10.224.175.65 with SMTP id w1mr3380142qaz.7.1358436762683; Thu, 17 Jan 2013 07:32:42 -0800 (PST) X-Received: by 10.49.35.77 with SMTP id f13mr1259853qej.4.1358436762589; Thu, 17 Jan 2013 07:32:42 -0800 (PST) Path: k2ni675qap.0!nntp.google.com!p13no1020716qai.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Thu, 17 Jan 2013 07:32:42 -0800 (PST) In-Reply-To: <85bocoqxis.fsf@stephe-leake.org> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=192.91.171.42; posting-account=YkFdLgoAAADpWnfCBA6ZXMWTz2zHNd0j NNTP-Posting-Host: 192.91.171.42 References: <20bda3de-b033-4b4e-8298-2ac47701b814@googlegroups.com> <85hamiulsn.fsf@stephe-leake.org> <85bocoqxis.fsf@stephe-leake.org> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <9961f0a1-aa2c-47d5-be84-77e495ea2a0f@googlegroups.com> Subject: Re: GNAT 4.4.5 Record Bit_Order Endian issues From: awdorrin Injection-Date: Thu, 17 Jan 2013 15:32:42 +0000 Content-Type: text/plain; charset=ISO-8859-1 Date: 2013-01-17T07:32:42-08:00 List-Id: 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