TEAM-ADA Archives

Team Ada: Ada Programming Language Advocacy


Options: Use Classic View

Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Topic: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
"W. Wesley Groleau x4923" <[log in to unmask]>
Fri, 16 Oct 1998 10:42:58 -0500
text/plain (113 lines)
I responded to Chris Sparks privately, but after another response, thought
there might be someone else who knows something I don't about some of my
ideas.  He said basically:

> [386 is little-endian, R3000 is big-endian OR little endian, must talk
> to each other, current software is little endian, new OS/compiler is big
> endian...] .....  Either we pay gobs of $ to
> get VxWorks to redo their OS as little endian or we spend lots of time
> (aka $) to redo our software and to incorporate data marshalling.

Yes, I see that problem.  I thought you had said something about GNAT.  In
any case, as I said, the RM doesn't force them to support it.  *IF* those
two things are equal, the RM ADVISES support, otherwise there's not even
the advice.  So, you have several choices--unfortunately, all of them are
potentially expensive, but upon an examination of your application, you
MIGHT find that one or more of them is not too expensive.

1. gobs of money to vxworks (or to the Ada compiler vendor)
   (Did VxWorks state that it would be gobs, or do they have a little known
   easy way to rebuild the OS in the little-endian mode?)

2. some amount of money to tamper with VxWorks/gcc yourself.

3. change to gnat and tamper with that on your own.

4. get an Ada compiler that supports Annex E on both hosts and
   spend some amount of time changing your code to use pragma Remote;

5. Use re-specification of derived types.  This would also take some
   amount of re-tooling.  Only you can say how much.  This is a technique
   taught to me ten years ago when I was learning Ada 83, but I have since
   met many Ada programmers that don't know about it.  (I don't recall
   ever actually using it myself.)  Here is a partial example for
   four-octet integers.  (I omitted the unchecked conversions, which
   should be obvious):

-- Copyright 1998, Raytheon Company.  Permission to copy, use, modify,
-- or extend granted to anyone willing to share results with the author.
-- History:
--      10 Aug 1998  W. Groleau   Created for 8.1.A review meeting.
--      16 Oct 1998  W. Groleau   Added additional documentation.
-- Convert_Demo: Shows how derived types with representation clauses
--               can be used to simplify conversions between formats.
--               This is not a "real" example--there are other factors
--               that would affect this particular problem.  But it does
--               show the technique.  THIS TECHNIQUE IS LEGAL FOR BOTH
--               DIALECTS OF ADA.  A similar technique is possible for
--               enumeration types that differ in their internal coding,
--               i.e., for Enum use (Pos_0 => 5, Pos_1 => 7, ....);
with Unchecked_Conversion;

package Convert_Demo is

   Null_Address : constant System.Address renames System.Null_Address;

   Bits : constant := 1;

   type Byte is mod 256;
   for Byte'Size use 8 * Bits;

   type Big_Endian is
         MSB  : Byte;
         NMSB : Byte;
         NLSB : Byte;
         LSB  : Byte;
      end record;

   for Big_Endian use
         MSB  at 0 range  0 ..  7;
         NMSB at 0 range  8 .. 15;
         NLSB at 0 range 16 .. 23;
         LSB  at 0 range 24 .. 31;
      end record;

   for Big_Endian'Size use 32 * Bits;

   type Little_Endian is new Big_Endian;
   for Little_Endian use
         LSB  at 0 range  0 ..  7;
         NLSB at 0 range  8 .. 15;
         NMSB at 0 range 16 .. 23;
         MSB  at 0 range 24 .. 31;
      end record;

   -- above is how to define it.  Following is how to use it

   function Bogus_Cast is new Unchecked_Conversion (Source => Big_Endian,
                                                    Target => Little_Endian);

   Big_Number_One   : constant Big_Endian    := (16#AA#, 16#BB#,
                                                 16#CC#, 16#DD#);
   Big_Number_Two   : constant Little_Endian := Little_Endian (Big_Number_One);
   Big_Number_Three : constant Little_Endian := Bogus_Cast    (Big_Number_One);

   -- now: Big_Number_One.NMSB   = BB  by definition
   --      Big_Number_Two.NMSB   = BB  by easy-to-read type conversion
   --      Big_Number_Three.NMSB = CC  showing that unchecked conversion doesn't work!

   -- the catch is that the compiler has to be smart enough to handle it, instead of stupidly implementing the conversion as an unchecked conversion.  I do not know whether the ACVC tests this, and I have not yet had the time to test it on GNAT or Apex or ObjectAda.  In fact, as you can see, I haven't even yet added the print statements to verify whether it works.  But it SHOULD work.  If anyone else has a chance to test it on any compiler, please share with me the test code and the results.

end Convert_Demo;