* Rep Specs @ 1996-10-07 0:00 Doug Shipler 1996-10-08 0:00 ` Stephen Leake 0 siblings, 1 reply; 6+ messages in thread From: Doug Shipler @ 1996-10-07 0:00 UTC (permalink / raw) I am using SunAda83 version 1.1k on a SunOS Sparc 5. I have a record that is rep speced into 32 bit long words. One of the words is split up into several fields, one is a 16 bit integer, and the others are bit flags. The interesting part is that when I try to access one of the bit flags, the compiler fetches the wrong bit, it gets a bit from the 16 bit integer field. In this example, Flag3 accesses a bit inside Value. for My_Record_Typ use record at mod 32; Value at 0 * 4 range 16 .. 31; Flag1 at 0 * 4 range 15 .. 15; Flag2 at 0 * 4 range 13 .. 14; Unused1 at 0 * 4 range 10 .. 12; Flag3 at 0 * 4 range 9 .. 9; Flag4 at 0 * 4 range 8 .. 8; Unused2 at 0 * 4 range 4 .. 7; OtherVal at 0 * 4 range 0 .. 3; ........ Any ideas are greatly appreciated! ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Rep Specs 1996-10-07 0:00 Rep Specs Doug Shipler @ 1996-10-08 0:00 ` Stephen Leake 1996-10-09 0:00 ` Rep Specs,endian,ncohen Peter Hermann 1996-10-13 0:00 ` Rep Specs Robert Dewar 0 siblings, 2 replies; 6+ messages in thread From: Stephen Leake @ 1996-10-08 0:00 UTC (permalink / raw) Doug Shipler wrote: > > I am using SunAda83 version 1.1k on a SunOS Sparc 5. I have a record > that is rep speced into 32 bit long words. One of the words is > split up into several fields, one is a 16 bit integer, and the > others are bit flags. The interesting part is that when I try to > access one of the bit flags, the compiler fetches the wrong bit, it > gets a bit from the 16 bit integer field. > > In this example, Flag3 accesses a bit inside Value. > > for My_Record_Typ use > record at mod 32; > Value at 0 * 4 range 16 .. 31; > Flag1 at 0 * 4 range 15 .. 15; > Flag2 at 0 * 4 range 13 .. 14; > Unused1 at 0 * 4 range 10 .. 12; > Flag3 at 0 * 4 range 9 .. 9; > Flag4 at 0 * 4 range 8 .. 8; > Unused2 at 0 * 4 range 4 .. 7; > OtherVal at 0 * 4 range 0 .. 3; > ........ > > Any ideas are greatly appreciated! I ran into a similar problem. The cause is that the Sparc is little-bit-endian; it stores the least significant bit in the highest numbered bit slot. This is how I solved the problem in a (so far) portable way: ------------ for Intel/gnat --------------- with System; package Endianness -- Purpose: -- define constants to reflect hardware bit and word endianness in -- record representation clauses (in Ada83). Obviously, this file is -- highly system-dependent (Ada95 solves this much more nicely!). is -- this is for gnat on an Intel 386 compatible processor System_Name : System.NAME := System.SYSTEM_NAME_GNAT; Bit_Order : constant := 1; High_Bit_First : constant := 1; Low_Bit_First : constant := 0; MSBit : constant := 7; LSBit : constant := 0; type Byte_Order_Type is (BIG_ENDIAN, LITTLE_ENDIAN); Byte_Order : constant Byte_Order_Type := LITTLE_ENDIAN; end Endianness; ------------------- for Sparc/SunAda -------------------- with System; package Endianness -- Purpose: -- define constants to reflect hardware bit and word endianness in -- record representation clauses (in Ada83). Obviously, this file is -- highly system-dependent (Ada95 solves this much more nicely!). is -- this is for Sun (Verdix) Ada on a Sparc processor System_Name : System.NAME := System.SUN4_UNIX; Bit_Order : constant := -1; High_Bit_First : constant := 0; Low_Bit_First : constant := 1; MSBit : constant := 0; LSBit : constant := 7; type Byte_Order_Type is (BIG_ENDIAN, LITTLE_ENDIAN); Byte_Order : constant Byte_Order_Type := BIG_ENDIAN; end Endianness; Then, a rep clause looks like: type Out_Health_Flags_Type is record User_Ephemeris_Needed : BOOLEAN; Approximate_GPS_Time_Needed : BOOLEAN; Self_Survey_Data_Needed : BOOLEAN; Almanac_Not_Current : BOOLEAN; Operational_Status : OPERATIONAL_STATUS_TYPE; end record; for Out_Health_Flags_Type use record User_Ephemeris_Needed at 0 range LSBit + Bit_Order * 0 .. LSBit + Bit_Order * 0; Approximate_GPS_Time_Needed at 0 range LSBit + Bit_Order * 1 .. LSBit + Bit_Order * 1; Self_Survey_Data_Needed at 0 range LSBit + Bit_Order * 2 .. LSBit + Bit_Order * 2; Almanac_Not_Current at 0 range LSBit + Bit_Order * 3 .. LSBit + Bit_Order * 3; Operational_Status at 0 range High_Bit_First * (LSBit + Bit_Order * 4) + Low_Bit_First * (LSBit + Bit_Order * 7) .. Low_Bit_First * (LSBit + Bit_Order * 4) + High_Bit_First * (LSBit + Bit_Order * 7); end record; for Out_Health_Flags_Type'Size use 8; As long as you include the proper version of Endianness in your library, the rep clause is correct for either little-bit-endian (Sparc) or big-bit-endian (Intel). Note that the issue of byte-endianness doesn't show up in the rep clause; that's handled by the `at 0', as long as Storage_Unit is 8 bits. Byte-endianness shows up when converting multi-byte values to byte arrays: function To_2_Byte is new Unchecked_Conversion (TARGET => Byte_Array_2_Type, SOURCE => Geode_Types.INTEGER); procedure To_Network (Item : in Geode_Types.INTEGER; Buffer : out Geode_Types.BYTE_ARRAY; Last : in out Geode_Types.INTEGER) is use Geode_Types; begin case Byte_Order is when BIG_ENDIAN => Buffer (Last+1 .. Last+2) := To_2_Byte (Item); when LITTLE_ENDIAN => declare Temp : constant BYTE_ARRAY (1 .. 2) := To_2_Byte (Item); begin Buffer (Last+1) := Temp (2); Buffer (Last+2) := Temp (1); end; end case; Last := Last+2; end To_Network; You MUST test this code for each compiler/hardware combination; some may do the integer <> byte array unchecked conversion differently. -- - Stephe ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Rep Specs,endian,ncohen 1996-10-08 0:00 ` Stephen Leake @ 1996-10-09 0:00 ` Peter Hermann 1996-10-10 0:00 ` Norman H. Cohen 1996-10-13 0:00 ` Rep Specs Robert Dewar 1 sibling, 1 reply; 6+ messages in thread From: Peter Hermann @ 1996-10-09 0:00 UTC (permalink / raw) : I ran into a similar problem. The cause is that the Sparc is : little-bit-endian; it stores the least significant bit in the highest : numbered bit slot. : This is how I solved the problem in a (so far) portable way: I remember Norman H. Cohen has written an essay about the endian /portability problem somewhere in AdaLetters(?). -- Peter Hermann Tel:+49-711-685-3611 Fax:3758 ph@csv.ica.uni-stuttgart.de Pfaffenwaldring 27, 70569 Stuttgart Uni Computeranwendungen Team Ada: "C'mon people let the world begin" (Paul McCartney) ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Rep Specs,endian,ncohen 1996-10-09 0:00 ` Rep Specs,endian,ncohen Peter Hermann @ 1996-10-10 0:00 ` Norman H. Cohen 1996-10-11 0:00 ` Stephen Leake 0 siblings, 1 reply; 6+ messages in thread From: Norman H. Cohen @ 1996-10-10 0:00 UTC (permalink / raw) Peter Hermann wrote: > I remember Norman H. Cohen has written an essay about the endian > /portability problem somewhere in AdaLetters(?). "Endian-Independent Record Representation Clauses", Ada Letters XIV, No. 1 (January/February 1994), pp. 27-29 Stephen Leake's solution appears to be an instance of the approach suggested in the article. The article gives the general recipe for constructing the component clauses. Note that the problem being solved here is the porting of the source text for record-representation clauses, NOT the run-time translation of a byte stream from one endianness to another. Please disregard the assertion in the article that this problem would be solved in Ada 9X by an attribute definition clause for the 'Bit_Order attribute. The implementation advice in RM95-13.5.3(8) allows a compiler to reject an attribute-definition clause for the nondefault bit order in all the useful cases. Compilers are generally allowed to reject nondefault 'Bit_Order definitions because the designers of Ada 95 believed that component clauses interpreted according to the nondefault bit order could specify noncontiguous bit fields, an implementation nightmare. However, that depends on how you interpret the meaning of a bit offset in a nondefault-endian component clause. If you insist that at B range 10 .. 12 be synonymous, assuming 8-bit bytes, with at B+1 range 2 .. 4 then you do indeed get noncontiguous bit fields. But another interpretation is to look at the highest bit number, say b, specified with a given byte offset, and to view all component clauses with that byte offset as specifying a contiguous range of bits within the smallest "loadable storage unit" (byte, halfword, word, or doubleword on a typical 32-bit or 64-bit machine) having at least b+1 bits. For example, given the component clauses A at 0 range 0 .. 5; B at 0 range 6 .. 11; C at 0 range 12 .. 15; and no other "at 0" component clauses, we would assume that A, B, and C reside within a 16-bit loadable storage unit at offset 0, and that when this 16-bit field is loaded into a register, B is a contiguous field of bits somewhere in the middle of this 16-bit unit. Whether A is at the high-order end or the low-order end of the 16-bit unit depends on which bit ordering applies to the record type, but either way, there is a sensible interpretation with B specifying a field that is contiguous when loaded. Given this interpretation of bit offsets, there is a one-to-one correspondence between record representation clauses that specify a given layout when interpreted as big-endian clauses and other record representation clauses that specify the "same" layout when interpreted as little-endian representation clauses. (I explain below what I mean when I say that layouts are the "same".) Thus it would be practical to require all compilers to support nondefault-endian record-representation clauses, with an attribute-definition clause for T'Bit_Order determining how the record-representation clause for type T is to be interpreted. This would solve the source portability problem by allowing the programmer to arbitrarily specify a layout in his favorite bit order, knowing that a compiler that is big-endian by default and a compiler that is little-endian by default will interpret the record-representation clause the "same" way. When I say that a layout on a big-endian machine and a layout on a little-endian machine are the "same", I mean that the layout is divided into "loadable storage units" with the same sizes and byte offsets, and that the left-to-right bit position of each record component within corresponding loadable storage units is the same. These are the only properties of a layout that can be usefully preserved among opposite-endian machines. -- Norman H. Cohen mailto:ncohen@watson.ibm.com http://www.research.ibm.com/people/n/ncohen ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Rep Specs,endian,ncohen 1996-10-10 0:00 ` Norman H. Cohen @ 1996-10-11 0:00 ` Stephen Leake 0 siblings, 0 replies; 6+ messages in thread From: Stephen Leake @ 1996-10-11 0:00 UTC (permalink / raw) Norman H. Cohen wrote: > > Peter Hermann wrote: > > > I remember Norman H. Cohen has written an essay about the endian > > /portability problem somewhere in AdaLetters(?). > > "Endian-Independent Record Representation Clauses", Ada Letters XIV, No. > 1 (January/February 1994), pp. 27-29 > > Stephen Leake's solution appears to be an instance of the approach > suggested in the article. The article gives the general recipe for > constructing the component clauses. Yes, it is, and I apologize for not giving proper credit. I couldn't remember where I had learned the technique! -- - Stephe ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Rep Specs 1996-10-08 0:00 ` Stephen Leake 1996-10-09 0:00 ` Rep Specs,endian,ncohen Peter Hermann @ 1996-10-13 0:00 ` Robert Dewar 1 sibling, 0 replies; 6+ messages in thread From: Robert Dewar @ 1996-10-13 0:00 UTC (permalink / raw) Stephen Lake said, responding to Doug Shipler's problem: "I ran into a similar problem. The cause is that the Sparc is little-bit-endian; it stores the least significant bit in the highest numbered bit slot." and then follows a very contorted work around! No, that's not the cause. The quoted code is quite correct, and should work on either a little endian or big-endian machine. If it does not you have run into a compiler bug. Your suggestion might be reasonable as a work around, but we should not leave the impression that this work around is neccessary on a correctly functioning Ada compiler! ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~1996-10-13 0:00 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1996-10-07 0:00 Rep Specs Doug Shipler 1996-10-08 0:00 ` Stephen Leake 1996-10-09 0:00 ` Rep Specs,endian,ncohen Peter Hermann 1996-10-10 0:00 ` Norman H. Cohen 1996-10-11 0:00 ` Stephen Leake 1996-10-13 0:00 ` Rep Specs Robert Dewar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox