CVS difference for ais/ai-00133.txt

Differences between 1.8 and version 1.9
Log of other versions for file ais/ai-00133.txt

--- ais/ai-00133.txt	2003/12/07 05:00:29	1.8
+++ ais/ai-00133.txt	2004/03/02 04:44:58	1.9
@@ -854,3 +854,434 @@
 case bit order makes perfectly good sense.
 
 ****************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, February 25, 2004  5:31 PM
+
+> Is this AI waiting for someone to do some further work?
+> My understanding is that Norm Cohen wrote up a good solution
+> several years ago, but nothing much seems to have happened since then.
+
+I remember Norm describing how to control bit ordering within
+the current language, but I do not remember any suggestions of
+language features.
+
+What customers want of course is some magic incantation to allow
+their big endian dependent apps to run on little endian machines
+without any change. They are not going to get this :-)
+
+There are some things that would be useful, though whether we
+should mandate them, I don't know.
+
+It would be useful to be able to apply Bit_Order to a bit packed
+array to number the bits in opposite order. Perhaps this could be
+a more general feature of indexing arrays backwards (interface to
+Fortran-2 anyone? :-)
+
+It might also be useful to be able to apply Bit_Order to a discrete
+type meaning that you allow Little-endian integers for example on
+a big-endian machine. Note that bit order and byte order must always
+be consistent, so controlling the bit order as a way of talking about
+controlling byte order is fine.
+
+It is definitely mysterious to people that if they declare a record
+
+    type R is record
+       A, B : Integer;
+    end record;
+
+    for R'Bit_Order use ...
+
+the Bit_Order spec has no effect at all. In fact this is sufficiently
+odd that in GNAT we warn that the pragma has no effect on fields A
+and B.
+
+****************************************************************
+
+From: Dan Eilers
+Sent: Thursday, February 25, 2004  12:30 PM
+
+
+Robert Dewar wrote:
+> I remember Norm describing how to control bit ordering within
+> the current language, but I do not remember any suggestions of
+> language features.
+>
+> What customers want of course is some magic incantation to allow
+> their big endian dependent apps to run on little endian machines
+> without any change. They are not going to get this :-)
+
+AI-133 points out that there are two different things a user might
+want, one of which is as you describe, wanting an app running on
+a little endian machine to magically do some sort of byte flipping
+so that it can deal with data represented in big-endian order.
+And yes, they are not going to get this.
+
+The other thing that a user might want is to be able to write a
+record rep clause, for example describing the layout of an
+IEEE 32-bit float, or other "machine scalar" type, and want
+to specify the record layout in little-endian format using the
+existing Ada95 bit-order attribute, and be able to compile such a
+program on either a big- or little- endian machine and be able to
+use such record type to extract the bit fields of such an object.
+In this case, there is no byte flipping going on.
+
+Norm Cohen's paper, which was added to the AI in June, 1999,
+(see http://www.ada-auth.org/ai-files/grab_bag/bitorder.pdf)
+shows that it is reasonable to expect a compiler to support
+endian-independent record rep clauses for machine scalar types,
+using a corrected definition of the existing bit-order attribute.
+
+> It would be useful to be able to apply Bit_Order to a bit packed
+> array to number the bits in opposite order. Perhaps this could be
+> a more general feature of indexing arrays backwards (interface to
+> Fortran-2 anyone? :-)
+
+Yes, this would also be useful (VHDL does this, for example).
+But that would be a separate AI.
+
+****************************************************************
+
+From: Dan Eilers
+Sent: Monday, March  1, 2004  12:57 PM
+
+
+AI-133 has a note:
+> [Author's note: Randy, would it be possible to run a compiler survey to see
+> what compilers do with Bit_Order clauses that specify the nondefault bit
+> ordering? I suppose that you could use the above example of the IEEE 32-bit
+> format.]
+
+
+Here is a proposed test program:
+
+
+
+with system;
+with unchecked_conversion;
+with text_io; use text_io;
+procedure ai133 is
+
+   type flt is digits 6;
+   for flt'size use 32;
+
+   type IEEE_32_big_endian is
+      record
+         Sign : Integer range 0 .. 1;
+         Exponent : Integer range 0 .. 2**8 - 1;
+         Mantissa : Integer range 0 .. 2**23 - 1;
+      end record;
+
+   for IEEE_32_big_endian'bit_order use system.high_order_first;
+   for IEEE_32_big_endian use
+      record
+         Sign at 0 range 0 .. 0;
+         Exponent at 0 range 1 .. 8;
+         Mantissa at 0 range 9 .. 31;
+      end record;
+
+   type IEEE_32_little_endian is
+      record
+         Sign : Integer range 0 .. 1;
+         Exponent : Integer range 0 .. 2**8 - 1;
+         Mantissa : Integer range 0 .. 2**23 - 1;
+      end record;
+
+   for IEEE_32_little_endian'bit_order use system.low_order_first;
+   for IEEE_32_little_endian use
+      record
+         Sign at 0 range 31 .. 31;
+         Exponent at 0 range 23 .. 30;
+         Mantissa at 0 range 0 .. 22;
+      end record;
+
+   function conv is new unchecked_conversion(flt, IEEE_32_big_endian);
+   function conv is new unchecked_conversion(flt, IEEE_32_little_endian);
+
+   data: constant array(integer range <>) of flt :=
+           (0.0, 0.0005, -1.0, 2.5, -37.25, 12345.75);
+   ok: boolean := true;
+
+begin
+   for i in data'range loop
+      declare
+         x: flt := data(i);
+         y_b: IEEE_32_big_endian := conv(x);
+         y_l: IEEE_32_little_endian := conv(x);
+      begin
+         if y_b.sign /= y_l.sign then
+            put_line("FAILED, problem with sign");
+            ok := false;
+         end if;
+         if y_b.exponent /= y_l.exponent then
+            put_line("FAILED, problem with exponent");
+            put_line(integer'image(y_b.exponent));
+            put_line(integer'image(y_l.exponent));
+            ok := false;
+         end if;
+         if y_b.mantissa /= y_l.mantissa then
+            put_line("FAILED, problem with mantissa");
+            ok := false;
+         end if;
+         if flt'exponent(x)+126 /= y_b.exponent and not
+            (y_b.exponent = 0 and flt'exponent(x) = 0) then
+            put_line("FAILED, wrong exponent");
+            ok := false;
+         end if;
+         if (y_b.sign = 0 and flt'fraction(x) < 0.0) or
+            (y_b.sign = 1 and flt'fraction(x) >= 0.0) then
+            put_line("FAILED, wrong sign");
+            ok := false;
+         end if;
+       end;
+   end loop;
+   if ok then put_line("PASSED"); end if;
+end;
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, March  1, 2004  6:04 PM
+
+GNAT says
+
+gcc -c ai133.adb
+ai133.adb:20:19: attempt to specify non-contiguous field not permitted
+ai133.adb:20:19: (caused by non-standard Bit_Order specified)
+ai133.adb:21:19: attempt to specify non-contiguous field not permitted
+ai133.adb:21:19: (caused by non-standard Bit_Order specified)
+gnatmake: "ai133.adb" compilation error
+
+This is as we expect. The RM specifically does not require support of
+non-contiguous fields, and this seems like a reasonable choice to me!
+
+****************************************************************
+
+From: Dan Eilers
+Sent: Monday, March  1, 2004  6:13 PM
+
+The AI does _not_ call for support of non-contiguous fields!
+It calls for "proper" interpretation of component clauses in
+non-default bit order, such that consecutive bitoffsets are
+contiguous.  Thus results in useful endian-independent rep clauses
+rather than un-useful errors about supposed attempts to specify
+non-contiguous fields.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, March  1, 2004  6:59 PM
+
+OK, but GNAT implements the current definition in the RM, and the test
+program you have clearly tries to make non-contiguous fields according
+to that definition if you have a byte addressed machine.
+
+So if you have some other meaning in mind, it would definitely be
+seriously incompatible (we find lots of our customers using bit order
+clauses with the meaning in the RM, so if this is changed, I would want
+to be very sure that there is not some serious incompatibility
+introduced.
+
+****************************************************************
+
+From: Dan Eilers
+Sent: Monday, March  1, 2004  7:58 PM
+
+I haven't found any incompatibility problem.
+GNAT rejects non-default order rep clauses where fields span a
+byte boundary (as in the test case I sent), so these aren't a
+compatibility concern.
+
+When the fields don't cross byte boundaries, as in the following
+example, GNAT interprets the component clauses consistent with AI-133.
+
+
+
+with system;
+with unchecked_conversion;
+with text_io; use text_io;
+procedure ai133b is
+
+   type uint32 is range 0..2**32-1;
+   for uint32'size use 32;
+
+   type byte is range 0..255;
+   for byte'size use 8;
+
+   type rec is record
+     a,b,c,d: byte;
+   end record;
+   for rec'size use 32;
+
+   type rec_big_endian is
+      record
+         a,b,c,d: byte;
+      end record;
+
+   for rec_big_endian'bit_order use system.high_order_first;
+   for rec_big_endian use
+      record
+         a at 0 range 0 .. 7;
+         b at 0 range 8 ..15;
+         c at 0 range 16..23;
+         d at 0 range 24..31;
+      end record;
+
+   type rec_little_endian is
+      record
+         a,b,c,d: byte;
+      end record;
+
+   for rec_little_endian'bit_order use system.low_order_first;
+   for rec_little_endian use
+      record
+         a at 0 range 24..31;
+         b at 0 range 16..23;
+         c at 0 range  8..15;
+         d at 0 range  0.. 7;
+      end record;
+
+   function conv is new unchecked_conversion(uint32, rec_big_endian);
+   function conv is new unchecked_conversion(uint32, rec_little_endian);
+
+   ok: boolean := true;
+
+   x: uint32 := 3*(1+2**8+2**16+2**24);
+   y_b: rec_big_endian := conv(x);
+   y_l: rec_little_endian := conv(x);
+begin
+   if y_b.a /= y_l.a then
+      put_line("FAILED, problem with a");
+      ok := false;
+   end if;
+   if y_b.b /= y_l.b then
+      put_line("FAILED, problem with b");
+      ok := false;
+   end if;
+   if y_b.c /= y_l.c then
+      put_line("FAILED, problem with c");
+      ok := false;
+   end if;
+   if y_b.d /= y_l.d then
+      put_line("FAILED, problem with d");
+      ok := false;
+   end if;
+
+   if ok then put_line("PASSED"); end if;
+end;
+
+****************************************************************
+
+From: Dan Eilers
+Sent: Monday, March  1, 2004  8:12 PM
+
+I spoke too soon.
+There _is_ a compatibility problem for GNAT when the fields don't
+cross byte boundaries.  My example just didn't expose it.
+This one does.
+
+
+
+with system;
+with unchecked_conversion;
+with text_io; use text_io;
+procedure ai133c is
+
+   type uint32 is range 0..2**32-1;
+   for uint32'size use 32;
+
+   type byte is range 0..255;
+   for byte'size use 8;
+
+   type rec is record
+     a,b,c,d: byte;
+   end record;
+   for rec'size use 32;
+
+   type rec_big_endian is
+      record
+         a,b,c,d: byte;
+      end record;
+
+   for rec_big_endian'bit_order use system.high_order_first;
+   for rec_big_endian use
+      record
+         a at 0 range 0 .. 7;
+         b at 0 range 8 ..15;
+         c at 0 range 16..23;
+         d at 0 range 24..31;
+      end record;
+
+   type rec_little_endian is
+      record
+         a,b,c,d: byte;
+      end record;
+
+   for rec_little_endian'bit_order use system.low_order_first;
+   for rec_little_endian use
+      record
+         a at 0 range 24..31;
+         b at 0 range 16..23;
+         c at 0 range  8..15;
+         d at 0 range  0.. 7;
+      end record;
+
+   function conv is new unchecked_conversion(uint32, rec_big_endian);
+   function conv is new unchecked_conversion(uint32, rec_little_endian);
+
+   ok: boolean := true;
+
+   x: uint32 := 1+3*2**8+5*2**16+7*2**24;
+   y_b: rec_big_endian := conv(x);
+   y_l: rec_little_endian := conv(x);
+begin
+   if y_b.a /= y_l.a then
+      put_line("FAILED, problem with a");
+      ok := false;
+   end if;
+   if y_b.b /= y_l.b then
+      put_line("FAILED, problem with b");
+      ok := false;
+   end if;
+   if y_b.c /= y_l.c then
+      put_line("FAILED, problem with c");
+      ok := false;
+   end if;
+   if y_b.d /= y_l.d then
+      put_line("FAILED, problem with d");
+      ok := false;
+   end if;
+
+   if ok then put_line("PASSED"); end if;
+end;
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, March  1, 2004  9:02 PM
+
+Well I will have to analyze this more carefully. Do you think GNAT
+is wrong with respect to the definition in the Ada 95 RM -- it seems
+right to me. All the attribute does in Ada 95 is to renumber the
+bits in an addressing unit ...
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March  1, 2004  9:38 PM
+
+...
+> Here is a proposed test program:
+...
+>    type IEEE_32_big_endian is
+>       record
+>          Sign : Integer range 0 .. 1;
+>          Exponent : Integer range 0 .. 2**8 - 1;
+>          Mantissa : Integer range 0 .. 2**23 - 1;
+>       end record;
+
+Minor nit: This assumes that Integer is 32-bit type, which is not guaranteed
+by the language and isn't true on at least one compiler...
+
+****************************************************************
+

Questions? Ask the ACAA Technical Agent