CVS difference for ais/ai-00133.txt

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

--- ais/ai-00133.txt	2001/09/08 01:42:46	1.6
+++ ais/ai-00133.txt	2003/11/27 02:01:11	1.7
@@ -1,26 +1,25 @@
-!standard 13.05.03 (00)                               98-03-27  AI95-00133/02
+!standard 13.05.03 (00)                               03-10-31	AI95-00133/03
 !class binding interpretation 96-05-07
 !status work item 96-05-07
 !status received 96-05-07
 !priority Medium
 !difficulty Medium
-!subject controlling bit ordering
+!subject Controlling bit ordering
-!summary 98-03-27
-The Bit_Order clause is intended to provide compiler uniformity on a
-single machine.  If there is one storage element per word, then it is
-not necessarily clear which direction the bits should be ordered in; the
-programmer may use Bit_Order to specify it.
-If there are more than one storage elements per word, then Bit_Order
-follows the addressing order by default, and the implementation need not
-support anything else.  If the implementation chooses to support (all)
-Bit_Order clauses on such a machine, then a single component can end up
-being allocated in a noncontiguous set of bits.
+The interpretation of component_clauses in the nondefault bit order is based on
+*machine scalars*, which are chunks of storage that can be natively loaded and
+stored by the machine. All the component_clauses at a given offset are
+considered to be part of the same machine scalar, and the first_bit and last_bit
+are interpreted are bit offsets within that machine scalar. This makes it
+possible to write endian-independent record_representation_clauses.
-!question 98-03-27
+The recommended level of support for Bit_Order clauses is modified to include
+support for the nondefault bit order in all cases.
 What problem is the Bit_Order attribute supposed to solve?
 Is is intended to solve:
    1) the "compiler uniformity problem" where a single program on
@@ -34,16 +33,251 @@
       different bit orders need to access shared memory, files,
       devices, or network channels, so one processor has to do
       cumbersome byte flipping?
+(The former.)
-!recommendation 98-03-27
 (See Summary.)
+Add at the end of 13.3(8):
+A *machine scalar* is an amount of storage that can be conveniently and
+efficiently loaded, stored, or operated upon by the hardware. Machine scalars
+consist of an integral number of storage elements. The set of machine scalars is
+implementation-dependent, but must include at least the storage element and the
+word. [Machine scalars are used to interpret component_clauses when the
+nondefault bit ordering applies.]
+Add after 13.5.1(10)
+If the nondefault bit ordering applies to the type, the value of last_bit shall
+be less than the size of the largest machine scalar.
+Replace 13.5.1(13) by:
+A record_representation_clause (without the mod_clause) specifies the layout.
+If the nondefault bit ordering applies to the type, all the components having a
+component_clause specifying a given position are considered to be part of a
+single machine scalar, located at that position. The size of this machine scalar
+is determined by rounding up the largest value specified for last_bit. The
+first_bit and last_bit of each component_clause are then interpreted as bit
+offsets in this machine scalar.
+The storage place attributes (see 13.5.2) are taken from the values of the
+position, first_bit, and last_bit expressions after normalizing those values so
+that first_bit is less than Storage_Unit.
+Add after 13.5.1(17):
+o  An implementation should support machine scalars that correspond to all the
+integer, floating-point and address formats supported by the machine, and no
+Replace 13.5.3(8) by:
+o  The implementation should support the nondefault bit ordering in addition to
+the default bit ordering.
+Add after 13.5.3(8):
+NOTE: Bit_Order clauses make it possible to write record_representation_clauses
+that can be ported between machines having different bit ordering. They don't
+guarantee transparent exchange of data between such machines.
+NOTE: This AI is largely based on Norman Cohen's paper "A Proposal for Endian-
+Portable Record Representation Clauses", which can be found at http://www.ada-  This paper contains figures that would
+be hard to reproduce in a text-only format, so the interested reader is invited
+to consult the PDF version.  The most important definitions and conclusions of
+this paper are repeated here for convenience.
+There are at least two "endian problems". One is the run-time problem of
+transferring between a big-endian machine and a little-endian machine (or
+between big-endian and little-endian processes of a bi-endian machine). Another
+is the compile-time problem of specifying a layout portably, so that a single
+version of an Ada source file will produce the same layout regardless of the
+compiler's default bit ordering. This is a proposal to solve the second problem.
+Most machine instructions operate on small values that we shall call machine
+scalars. Typical machine scalars include an 8-bit byte, a 16-bit halfword, and a
+32-bit word, as well as 32- and 64-bit floating point formats. A machine scalar
+generally fits in a register or a pair of registers.
+The only difference between big-endian and little-endian execution is the
+correspondence between a sequence of two or more bytes in memory, starting at a
+given address and extending to higher-addressed bytes, and machine-scalar
+A program that never views the same bits as belonging to two different types
+(and never performs binary I/O, which is tantamount to viewing the raw contents
+of a file as the representation of some type) is inherently endian-independent.
+That is, the program is portable between big-endian and little-endian machines.
+A source program that views the same storage as belonging to more than one type
+can also be endian-independent, provided that an appropriate programming
+discipline is followed and provided that object code is generated from the
+source code in a manner consistent with the target execution bit ordering.
+A program viewing the same storage as belonging to more than one type will
+typically depend on properties like the following:
+   o  A given machine scalar occurs at a specified offset within a record.
+   o  The bits of a machine scalar can be subdivided into contiguous fields of
+specified sizes, occurring in a specified order from most significant bits to
+least significant bits.
+For example the IEEE 32-bit floating point format has a 1-bit sign field,
+followed by an 8-bit exponent field, followed by a 23-bit mantissa field. The
+word "followed" in this description pertains to the machine scalar
+representation, i.e. the register representation. On a big-endian target
+machine, this format might be represented as follows:
+   type IEEE_32 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 use
+      record
+         Sign at 0 range 0 .. 0;
+         Exponent at 0 range 1 .. 8;
+         Mantissa at 0 range 9 .. 31;
+      end record;
+On a little-endian target machine, the record representation clause would have
+to be written as follows:
+   for IEEE_32 use
+      record
+         Sign at 0 range 31 .. 31;
+         Exponent at 0 range 23 .. 30;
+         Mantissa at 0 range 0 .. 22;
+      end record;
+We would prefer to be able to write and maintain a single record-representation
+clause that would produce the appropriate memory mapping for the target machine
+whether that machine is big-endian or little-endian. At first glance, the
+Bit_Order clause appears to provide a solution. Unfortunately, the recommended
+level of support for the Bit_Order clause, as defined by 13.5.3(8) is very weak:
+   "If Word_Size = Storage_Unit, then the implementation should support the
+    nondefault bit ordering in addition to the default bit ordering."
+In other words, there is no requirement to support the non-default bit ordering
+if Word_Size > Storage_Unit. On most machines in existence today Storage_Unit is
+8 and Word_Size is typically 32 or more, so the recommended level of support is
+The reason why 13.5.3(8) is so weak has to do with the meaning of large bit
+numbers, i.e., bit numbers exceeding System.Storage_Unit - 1. The meaning of
+large bit numbers in the default bit ordering is well understood: assuming 8-bit
+bytes, bit 8+b of byte a is the same bit as bit b of byte a+1. Consequently,
+there are redundant ways to specify the same storage layout. For example, the
+big-endian record representation clause above could have been written
+   for IEEE_32 use
+      record
+         Sign at 0 range 0 .. 0;
+         Exponent at 0 range 1 .. 8;
+         Mantissa at 1 range 1 .. 23;
+      end record;
+While the meaning of large bit numbers is obvious in the default bit ordering,
+it is not obvious in the nondefault bit ordering. Suppose we and compile a big-
+endian record-representation clause, together with a big-endian Bit_Order
+clause, for a little-endian target. The record-representation clause includes
+the component clause:
+   Exponent at 0 range 1 .. 8;
+specifying that the Exponent component includes bits 1 to 8 of byte 0. If we
+adhere to the definition that bit 8+b of byte a is the same bit as bit b of byte
+a+1, then this is equivalent to bits 1 to 7 of byte 0 and bit 0 of byte 1. Under
+big-endian bit numbering rules, these are the 7 least significant bits of byte 0
+together with by the most significant bit of byte 1. Unfortunately, on a little-
+endian target, these two groups of bits will not be adjacent in a machine scalar
+corresponding to bytes 0 and 1. This would make it difficult to extract and
+update the Exponent component. Furthermore, it is not clear that there is a need
+for supporting non-contiguous components in the language, but it is clear that
+there is a need for supporting endian-independent record representation clause.
+It is important to notice that contiguity of bits is a meaningful notion within
+a machine scalar, or within a single byte of memory, but not between bits in
+different bytes of memory. The reason is that, on different target machines,
+bytes are loaded in different order to compose a machine scalar. If we want to
+be able to write endian-independent record representation clauses, we must
+cannot interpret large bit numbers with respect to the memory representation. We
+can only interpret them with respect to machine scalars.
+Therefore, we adopt the following convention: in a record-representation clause
+for the nondefault bit ordering, there is a one-to-one correspondence between
+byte offsets (i.e., the numbers appearing between the words "at" and "range")
+and machine scalars. That is, all components whose positions are specified with
+the same byte offset are assumed to be part of the same machine scalar (so that
+in typical implementations they will be loaded into a register together,
+ignoring alignment issues); and any two components required to reside within the
+same machine scalar have their positions specified in terms of the same byte
+offset. The length of a machine scalar is inferred from the highest bit number
+specified along with its byte position in some component clause, rounded up as
+Note that the set of machine scalars is implementation-dependent, so there is no
+guarantee that two compilers targetting the same machine will support the same
+set of machine scalars, and therefore the same set of record representation
+clauses. We give an implementation advice to support all integer, floating-point
+and address formats, though, as there is really no run-time complexity
+associated with supporting machine scalars: they only play a role when
+interpreting component_clauses. The reason why we have them is to reduce the
+likelihood that people will be surprised by the effect of some representation
+clauses, notably in the presence of holes.
+Also note that a representation clause written for, say, a 32-bit target
+machine, may not port to a 16-bit target machine (that could be the case for the
+above example) as there may not exist a 32-bit machine scalar on the latter
+[Author's note: Norm had the following definition: "The length of a machine
+scalar is inferred from the highest bit number specified along with its byte
+position in some component clause, rounded up to the next multiple of
+System.Storage_Unit." This means that a machine scalar according to this
+definition could have, say, 42 bytes. That's different from his original
+definition for this term, and it causes confusing effects where you have to
+introduce fillers for representation clauses to do the right thing. His paper
+has an example where a 24-bit component on a 32-bit machine ends up misplaced
+unless a 1-byte filler is explicitly introduced. I think it's better to define
+machine scalars to reflect the "natural" formats of the machine.]
+The proposed interpretation is of course incompatible in the sense that, for the
+nondefault bit ordering, it breaks the current rule that bit 8+b of byte a is
+the same bit as bit b of byte a+1. However, the existing RM is sufficiently
+vague and muddled that it's hard to believe that there is a lot of code out
+there depending on record_representation_clauses with nondefault bit ordering.
-!wording 96-05-07
+[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
-!discussion 96-05-07
+The attributes Position, First_Bit and Last_Bit are still normalized, even if
+the nondefault bit ordering is used. This means that if they are used to produce
+a record representation clause they may result in a different layout, because
+the partition in terms of machine scalars will change. Since these attributes
+are not static, any such scenario would involve the intervention of a human
+being or of a program generator, so the oddity is probably acceptable.
-!appendix 96-05-07
 !section 13.5.3(00)
 !subject controlling bit ordering

Questions? Ask the ACAA Technical Agent