Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
<!-- Crown Copyright (c) 1998 -->
2
<HTML>
3
<HEAD>
4
<TITLE>SHAPEs, ALIGNMENTs and OFFSETs.</TITLE>
5
</HEAD>
6
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
7
<A NAME=S18>
8
<H1>TDF Guide, Issue 4.0 </H1>
9
<H3>January 1998</H3>
10
<A HREF="guide7.html"><IMG SRC="../images/next.gif" ALT="next section">
11
</A> <A HREF="guide5.html">
12
<IMG SRC="../images/prev.gif" ALT="previous section"></A>
13
<A HREF="guide1.html"><IMG SRC="../images/top.gif" ALT="current document"></A>
14
<A HREF="../index.html"><IMG SRC="../images/home.gif" ALT="TenDRA home page">
15
</A>
16
<IMG SRC="../images/no_index.gif" ALT="document index"><P>
17
<HR>
18
<DL>
19
<DT><A HREF="#S19"><B>4.1 </B> - Shapes</A><DD>
20
<DT><A HREF="#S20"><B>4.1.1 </B> - TOP, BOTTOM, LUB</A><DD>
21
<DT><A HREF="#S21"><B>4.1.2 </B> - INTEGER</A><DD>
22
<DT><A HREF="#S22"><B>4.1.3 </B> - FLOATING and complex</A><DD>
23
<DT><A HREF="#S23"><B>4.1.4 </B> - BITFIELD</A><DD>
24
<DT><A HREF="#S24"><B>4.1.5 </B> - PROC</A><DD>
25
<DT><A HREF="#S25"><B>4.1.6 </B> - Non-primitive SHAPEs</A><DD>
26
<DT><A HREF="#S26"><B>4.2 </B> - Alignments</A><DD>
27
<DT><A HREF="#S27"><B>4.2.1 </B> - ALIGNMENT constructors</A>
28
<DD>
29
<DT><A HREF="#S28"><B>4.2.2 </B> - Special alignments</A><DD>
30
<DT><A HREF="#S29"><B>4.2.3 </B> - AL_TAG, make_al_tagdef</A>
31
<DD>
32
<DT><A HREF="#S30"><B>4.3 </B> - Pointer and offset SHAPEs</A><DD>
33
<DT><A HREF="#S31"><B>4.3.1 </B> - OFFSET</A><DD>
34
<DT><A HREF="#S32"><B>4.4 </B> - Compound SHAPEs</A><DD>
35
<DT><A HREF="#S33"><B>4.4.1 </B> - Offset arithmetic with compound
36
shapes</A><DD>
37
<DT><A HREF="#S34"><B>4.4.2 </B> - offset_mult</A><DD>
38
<DT><A HREF="#S35"><B>4.4.3 </B> - OFFSET ordering and representation</A><DD>
39
<DT><A HREF="#S36"><B>4.5 </B> - BITFIELD alignments</A><DD>
40
</DL>
41
<HR>
42
<H1>4  SHAPEs, ALIGNMENTs and OFFSETs.</H1>
43
In most languages there is some notion of the type of a value. This
44
is often an uncomfortable mix of a definition of a representation
45
for the value and a means of choosing which operators are applicable
46
to the value. The TDF analogue of the type of value is its SHAPE (S3.20).
47
A SHAPE is only concerned with the representation of a value, being
48
an abstraction of its size and alignment properties. Clearly an architecture-independent
49
representation of a program cannot say, for example, that a pointer
50
is 32 bits long; the size of pointers has to be abstracted so that
51
translations to particular architectures can choose the size that
52
is apposite for the platform.<P>
53
<A NAME=S19>
54
<HR><H2>4.1. Shapes</H2>
55
There are ten different basic constructors for the SORT SHAPE from
56
bitfield to top as shown in table 3. SHAPEs arising from those constructors
57
are used as qualifiers (just using an upper case version of the constructor
58
name) to various SORTs in the definition; for example, EXP TOP is
59
an expression with top SHAPE. This is just used for definitional purposes
60
only; there is no SORT SHAPENAME as one has SORTNAME.<P>
61
In the TDF specification of EXPs, you will observe that all EXPs in
62
constructor signatures are all qualified by the SHAPE name; for example,
63
a parameter might be EXP INTEGER(v). This merely means that for the
64
construct to be meaningful the parameter must be derived from a constructor
65
defined to be an EXP INTEGER(v). You might be forgiven for assuming
66
that TDF is hence strongly-typed by its SHAPEs. This is not true;
67
the producer must get it right. There are some checks in translators,
68
but these are not exhaustive and are more for the benefit of translator
69
writers than for the user. A tool for testing the SHAPE correctness
70
of a TDF program would be useful but has yet to be written.<P>
71
<A NAME=S20>
72
<H3>4.1.1. TOP, BOTTOM, LUB</H3>
73
Two of the SHAPE constructions are rather specialised; these are 
74
TOP and BOTTOM. The result of any expression with a TOP shape will
75
always be discarded; examples are those produced by assign and integer_test
76
. A BOTTOM SHAPE is produced by an expression which will leave the
77
current flow of control e.g. goto . The significance of these SHAPEs
78
only really impinges on the computation of the shapes of constructs
79
which have alternative expressions as results. For example, the result
80
of conditional is the result of one of its component expressions.
81
In this case, the SHAPE of the result is described as the LUB of the
82
SHAPEs of the components. This simply means that if one of the component
83
SHAPEs is TOP then the resulting SHAPE is TOP; if one is BOTTOM then
84
the resulting SHAPE is the SHAPE of the other; otherwise both component
85
SHAPEs must be equal and is the resulting SHAPE. Since this operation
86
is associative, commutative and idempotent, we can speak quite unambiguously
87
of the LUB of several SHAPEs.<P>
88
<A NAME=S21>
89
<H3>4.1.2. INTEGER</H3>
90
Integer values in TDF have shape INTEGER(v) where v is of SORT VARIETY.
91
The constructor for this SHAPE is integer with a VARIETY parameter.
92
The basic constructor for VARIETY is var_limits which has a pair of
93
signed natural numbers as parameters giving the limits of possible
94
values that the integer can attain. The SHAPE required for a 32 bit
95
signed integer would be:<P>
96
<PRE>
97
integer(var_limits(-2<I>31</I>, 2<I>31</I>-1))
98
</PRE>
99
while an unsigned char is:<P>
100
<PRE>
101
integer(var_limits(0, 255))
102
</PRE>
103
A translator should represent each integer variety by an object big
104
enough (or bigger) to contain all the possible values with limits
105
of the VARIETY. That being said, I must confess that most current
106
translators do not handle integers of more than the maximum given
107
naturally by the target architecture, but this will be rectified in
108
due course.<P>
109
The other way of constructing a VARIETY is to specify the number of
110
bits required for its 2s-complemennt representation using var_width:
111
<P>
112
<PRE>
113
	signed_width:	BOOL
114
	width:	NAT
115
		   -&gt; VARIETY
116
</PRE>
117
<P>
118
<A NAME=S22>
119
<H3>4.1.3. FLOATING and complex</H3>
120
Similarly, floating point and complex numbers have shape FLOATING
121
qualified by a FLOATING_VARIETY. <P>
122
A FLOATING_VARIETY for a real number is constructed using fvar_parms:<P>
123
<PRE>
124
	base:	NAT
125
	mantissa_digits:	NAT
126
	minimum_exponent:	NAT
127
	maximum_exponent::	NAT
128
		   -&gt; FLOATING_VARIETY
129
</PRE>
130
A FLOATING_VARIETY specifies the base, number of mantissa digits,
131
and maximum and minimum exponent. Once again, it is intended that
132
the translator will choose a representation which will contain all
133
possible values, but in practice only those which are included in
134
IEEE float, double and extended are actually implemented.<P>
135
Complex numbers have a floating variety constructed by complex_parms
136
which has the the same signature as fvar_parms. The representation
137
of these numbers is likely to be a pair of real numbers each defined
138
as if by fvar_parms with the same arguments. The real and imaginary
139
parts of of a complex number can be extracted using real_part and
140
imaginary_part; these could have been injected ito the complex number
141
using make_complex or any of the complex operations. Many translators
142
will simply transform complex numbers into COMPOUNDs consisting of
143
two floating point numbers, transforming the complex operations into
144
floating point operations on the fields.<P>
145
<A NAME=S23>
146
<H3>4.1.4. BITFIELD</H3>
147
A number of contiguous bits have shape BITFIELD, qualified by a BITFIELD_VARIETY
148
(S3.4) which gives the number of bits involved and whether these bits
149
are to be treated as signed or unsigned integers. Current translators
150
put a maximum of 32 or 64 on the number of bits.<P>
151
<A NAME=S24>
152
<H3>4.1.5. PROC</H3>
153
The representational SHAPEs of procedure values is given by PROC with
154
constructor proc . I shall return to this in the description of the
155
operations which use it.<P>
156
<A NAME=S25>
157
<H3>4.1.6. Non-primitive SHAPEs</H3>
158
The construction of the other four SHAPEs involves either existing
159
SHAPEs or the alignments of existing SHAPEs. These are constructed
160
by compound, nof , offset and pointer. Before describing these, we
161
require a digression into what is meant by alignments and offsets.<P>
162
<P>
163
<A NAME=S26>
164
<HR><H2>4.2. Alignments</H2>
165
In most processor architectures there are limitations on how one can
166
address particular kinds of objects in convenient ways. These limitations
167
are usually defined as part of the ABI for the processor. For example,
168
in the MIPs processor the fastest way to access a 32-bit integer is
169
to ensure that the address of the integer is aligned on a 4-byte boundary
170
in the address space; obviously one can extract a mis-aligned integer
171
but not in one machine instruction. Similarly, 16-bit integers should
172
be aligned on a 2-byte boundary. In principle, each primitive object
173
could have similar restrictions for efficient access and these restrictions
174
could vary from platform to platform. Hence, the notion of alignment
175
has to be abstracted to form part of the architecture independent
176
TDF - we cannot assume that any particular alignment regime will hold
177
universally.<P>
178
The abstraction of alignments clearly has to cover compound objects
179
as well as primitive ones like integers. For example, if a field of
180
structure in C is to be accessed efficiently, then the alignment of
181
the field will influence the alignment of the structure as whole;
182
the structure itself could be a component of a larger object whose
183
alignment must then depend on the alignment of the structure and so
184
on. In general, we find that a compound alignment is given by the
185
maximum alignment of its components, regardless of the form of the
186
compound object e.g. whether it is a structure, union, array or whatever.
187
<P>
188
This gives an immediate handle on the abstraction of the alignment
189
of a compound object - it is just the set of abstractions of the alignments
190
of its components. Since &quot;maximum&quot; is associative, commutative
191
and idempotent, the component sets can be combined using normal set-union
192
rules. In other words, a compound alignment is abstracted as the set
193
of alignments of the primitive objects which make up the compound
194
object. Thus the alignment abstraction of a C structure with only
195
float fields is the singleton set containing the alignment of a float
196
while that of a C union of an int and this structure is a pair of
197
the alignments of an int and a float.<P>
198
<A NAME=S27>
199
<H3>4.2.1. ALIGNMENT constructors</H3>
200
The TDF abstraction of an alignment has SORT ALIGNMENT. The constructor,
201
unite_alignments, gives the set-union of its ALIGNMENT parameters;
202
this would correspond to taking a maximum of two real alignments in
203
the translator. <P>
204
The constructor , alignment, gives the ALIGNMENT of a given SHAPE
205
according to the rules given in the definition. These rules effectively
206
<I>define</I> the primitive ALIGNMENTs as in the ALIGNMENT column
207
of table 3. Those for PROC, all OFFSETs and all POINTERs are constants
208
regardless of any SHAPE qualifiers. Each of the INTERGER VARIETYs,
209
each of the FLOATING VARIETYs and each of the BITFIELD VARIETYs have
210
their own ALIGNMENTs. These ALIGNMENTs will be bound to values apposite
211
to the particular platform at translate-time. The ALIGNMENT of TOP
212
is conventionally taken to be the empty set of ALIGNMENTs (corresponding
213
to the minimum alignment on the platform). <P>
214
The alignment of a procedure parameter clearly has to include the
215
alignment of its SHAPE; however, most ABIs will mandate a greater
216
alignment for some SHAPEs e.g. the alignment of a byte parameter is
217
usually defined to be on a 32-bit rather than an 8-bit boundary. The
218
constructor, parameter_alignment, gives the ALIGNMENT of a parameter
219
of given SHAPE.<P>
220
<A NAME=S28>
221
<H3>4.2.2. Special alignments</H3>
222
There are several other special ALIGNMENTs.<P>
223
The alignment of a code address is {<I>code</I>} given by code_alignment;
224
this will be the alignment of a pointer given by make_local_lv giving
225
the value of a label. <P>
226
The other special ALIGNMENTs are considered to include all of the
227
others, but remain distinct. They are all concerned with offsets and
228
pointers relevant to procedure frames, procedure parameters and local
229
allocations and are collectively known as frame alignments. These
230
frame alignments differ from the normal alignments in that their mapping
231
to a given architecture is rather more than just saying that it describes
232
some n-bit boundary. For example, alloca_alignment describes the alignment
233
of dynamic space produced by local_alloc (roughly the C alloca). Now,
234
an ABI could specify that the alloca space is a stack disjoint from
235
the normal procedure stack; thus manipulations of space at alloca_alignment
236
may involve different code to space generated in other ways.<P>
237
Similar considerations apply to the other special alignments,  callees_alignment(b),
238
callers_alignment(b) and locals_alignment. The first two give the
239
alignments of the bases of the two different parameter spaces in procedures
240
(q.v.) and locals_alignment gives the alignment of the base of locally
241
declared tags within a procedure. The exact interpretation of these
242
depends on how the frame stack is defined in the target ABI, e.g.
243
does the stack grow downwards or upwards? <P>
244
The final special alignment is var_param_alignment. This describes
245
the alignment of a special kind of parameter to a procedure which
246
can be of arbitrary length (see <A HREF="guide7.html#12">section 5.1.1
247
on page 27</A>).<P>
248
<A NAME=S29>
249
<H3>4.2.3. AL_TAG, make_al_tagdef</H3>
250
Alignments can also be named as AL_TAGs using  make_al_tagdef. There
251
is no corresponding make_al_tagdec since AL_TAGs are implicitly declared
252
by their constructor, make_al_tag. The main reason for having names
253
for alignments is to allow one to resolve the ALIGNMENTs of recursive
254
data structures. If, for example, we have mutually recursive structures,
255
their ALIGNMENTs are best named and given as a set of equations formed
256
by AL_TAGDEFs. A translator can then solve these equations trivially
257
by substitution; this is easy because the only significant operation
258
is set-union.<P>
259
<A NAME=S30>
260
<HR><H2>4.3. Pointer and offset SHAPEs</H2>
261
A pointer value must have a form which reflects the alignment of the
262
object that it points to; for example, in the MIPs processor, the
263
bottom two bits of a pointer to an integer must be zero. The TDF SHAPE
264
for a pointer is POINTER qualified by the ALIGNMENT of the object
265
pointed to. The constructor pointer uses this alignment to make a
266
POINTER SHAPE.<P>
267
<A NAME=S31>
268
<H3>4.3.1. OFFSET</H3>
269
Expressions which give sizes or offsets in TDF have an OFFSET SHAPE.
270
These are always described as the difference between two pointers.
271
Since the alignments of the objects pointed to could be different,
272
an OFFSET is qualified by these two ALIGNMENTs. Thus an EXP OFFSET(X,Y)
273
is the difference between an EXP POINTER(X) and an EXP POINTER(Y).
274
In order for the alignment rules to apply, the set X of alignments
275
must include Y. The constructor offset uses two such alignments to
276
make an OFFSET SHAPE. However, many instances of offsets will be produced
277
implicitly by the offset arithmetic, e.g., offset_pad:<P>
278
<PRE>
279
<I>	a</I>: 	ALIGNMENT
280
<I>	arg</I>1: 	EXP OFFSET(<I>z, t</I>)
281
		   -&gt; EXP OFFSET(<I>z</I> xc8 <I> a, a</I>)
282
</PRE>
283
This gives the next OFFSET greater or equal to <I>arg1</I> at which
284
an object of ALIGNMENT <I>a</I> can be placed. It should be noted
285
that the calculation of shapes and alignments are all translate-time
286
activities; only EXPs should produce runnable code. This code, of
287
course, may depend on the shapes and alignments involved; for example,
288
offset_pad might round up <I>arg1</I> to be a multiple of four bytes
289
if<I> a</I> was an integer ALIGNMENT and <I>z</I> was a character
290
ALIGNMENT. Translators also do extensive constant analysis, so if
291
<I>arg1</I> was a constant offset, then the round-off would be done
292
at translate-time to produce another constant.<P>
293
.<P>
294
<A NAME=S32>
295
<HR><H2>4.4. Compound SHAPEs</H2>
296
The alignments of compound SHAPEs (i.e. those arising from the constructors
297
compound and nof) are derived from the constructions which produced
298
the SHAPE. To take the easy one first, the constructor nof has signature:<P>
299
<PRE>
300
<I>	n</I>:	 NAT
301
<I>	s</I>: 	SHAPE
302
		   -&gt; SHAPE
303
</PRE>
304
This SHAPE describes an array of <I>n</I> values all of SHAPE <I>s</I>;
305
note that <I>n</I> is a natural number and hence is a constant known
306
to the producer. Throughout the definition this is referred to as
307
the SHAPE NOF(n, s). The ALIGNMENT of such a value is alignment(s);
308
i.e. the alignment of an array is just the alignment of its elements.<P>
309
The other compound SHAPEs are produced using compound:<P>
310
<PRE>
311
<I>	sz</I>: 	EXP OFFSET(<I>x, y</I>)
312
		   -&gt; S	HAPE
313
</PRE>
314
The <I>sz</I> parameter gives the minimum size which can accommodate
315
the SHAPE. <P>
316
<A NAME=S33>
317
<H3>4.4.1. Offset arithmetic with compound shapes</H3>
318
The constructors offset_add , offset_zero and shape_offset are used
319
together with offset_pad to implement (<I>inter alia</I>) selection
320
from structures represented by COMPOUND SHAPEs. Starting from the
321
zero OFFSET given by offset_zero, one can construct an EXP which is
322
the offset of a field by padding and adding offsets until the required
323
field is reached. The value of the field required could then be extracted
324
using component or add_to_ptr. Most producers would define a TOKEN
325
for the EXP OFFSET of each field of a structure or union used in the
326
program simply to reduce the size of the TDF<P>
327
The SHAPE of a C structure consisting of an char followed by an int
328
would require <I>x</I> to be the set consisting of two INTEGER VARIETYs,
329
one for int and one for char, and <I>sz</I> would probably have been
330
constructed like:<P>
331
<PRE>
332
<I>sz </I>= offset_add(offset_pad(int_al, shape_offset(char)), shape_offset(int))
333
</PRE>
334
The various rules for the ALIGNMENT qualifiers of the OFFSETs give
335
the required SHAPE; these rules also ensure that offset arithmetic
336
can be implemented simply using integer arithmetic for standard architectures
337
(see <A HREF="guide15.html#2">section 13.1 on page 56</A>). Note that
338
the OFFSET computed here is the minimum size for the SHAPE. This would
339
not in general be the same as the difference between successive elements
340
of an array of these structures which would have SHAPE OFFSET(<I>x</I>,
341
<I>x</I>) as produced by offset_pad(<I>x</I>, <I>sz</I>). For examples
342
of the use of OFFSETs to access and create structures, see  
343
<A HREF="guide14.html#0">section 12 on page 53</A>.<P>
344
<A NAME=S34>
345
<H3>4.4.2. offset_mult</H3>
346
In C, all structures have size known at translate-time. This means
347
that OFFSETs for all field selections of structures and unions are
348
translate-time constants; there is never any need to produce code
349
to compute these sizes and offsets. Other languages (notably Ada)
350
do have variable size structures and so sizes and offsets within these
351
structures may have to be computed dynamically. Indexing in C will
352
require the computation of dynamic OFFSETs; this would usually be
353
done by using offset_mult to multiply an offset expression representing
354
the stride by an integer expression giving the index:<P>
355
<PRE>
356
<I>	arg1</I>: 	EXP OFFSET(<I>x, x</I>)
357
<I>	arg2</I>: 	EXP INTEGER(<I>v</I>)
358
		   -&gt; EXP OFFSET(<I>x, x</I>)
359
</PRE>
360
and using add_to_ptr with a pointer expression giving the base of
361
the array with the resulting OFFSET.<P>
362
<A NAME=S35>
363
<H3>4.4.3. OFFSET ordering and representation</H3>
364
There is an ordering defined on OFFSETs with the same alignment qualifiers,
365
as given by offset_test and offset_max having properties like:<P>
366
<PRE>
367
shape_offset(S) xb3  offset_zero(alignment(S))
368
A xb3  B 	iff offset_max(A,B) = A
369
offset_add(A, B) xb3  A 	where B xb3  offset_zero(some compatible alignment)
370
</PRE>
371
In most machines, OFFSETs would be represented as single integer values
372
with the OFFSET ordering corresponding to simple integer ordering.
373
The offset_add constructor just translates to simple addition with
374
offset_zero as 0 with similar correspondences for the other offset
375
constructors. You might well ask why TDF does not simply use integers
376
for offsets, instead of introducing the rather complex OFFSET SHAPE.
377
The reasons are two-fold. First, following the OFFSET arithmetic rules
378
concerned with the ALIGNMENT qualifiers will ensure that one never
379
extracts a value from a pointer with the wrong alignment by, for example,
380
applying contents to an add_to_pointer. This frees TDF from having
381
to define the effect of strange operations like forming a float by
382
taking the contents of a pointer to a character which may be mis-aligned
383
with respect to floats - a heavy operation on most processors. The
384
second reason is quite simple; there are machines which cannot represent
385
OFFSETs by a single integer value.<P>
386
The iAPX-432 is a fairly extreme example of such a machine; it is
387
a &quot;capability&quot; machine which must segregate pointer values
388
and non-pointer values into different spaces. On this machine a value
389
of SHAPE POINTER({<I>pointer</I>, int}) (e.g. a pointer to a structure
390
containing both integers and pointers) could have two components;
391
one referring to the pointers and another to the integers. In general,
392
offsets from this pointer would also have two components, one to pick
393
out any pointer values and the other the integer values. This would
394
obviously be the case if the original POINTER referred to an array
395
of structures containing both pointers and integers; an offset to
396
an element of the array would have SHAPE OFFSET({<I>pointer</I>, int},{<I>pointer
397
</I>, int}); both elements of the offset would have to be used as
398
displacements to the corresponding elements of the pointer to extract
399
the structure element. The OFFSET ordering is now given by the comparison
400
of both displacements. Using this method, one finds that pointers
401
in store to non-pointer alignments are two words in different blocks
402
and pointers to pointer-alignments are four words, two in one block
403
and two in another. This sounds a very unwieldy machine compared to
404
normal machines with linear addressing. However, who knows what similar
405
strange machines will appear in future; the basic conflicts between
406
security, integrity and flexibility that the iAPX-432 sought to resolve
407
are still with us. For more on the modelling of pointers and offsets
408
see <A HREF="guide15.html#0">section 13 on page 56</A>.<P>
409
<A NAME=S36>
410
<HR><H2>4.5. BITFIELD alignments</H2>
411
Even in standard machines, one finds that the size of a pointer may
412
depend on the alignment of the data pointed at. Most machines do not
413
allow one to construct pointers to bits with the same facility as
414
other alignments. This usually means that pointers in memory to  BITFIELD
415
VARIETYs must be implemented as two words with an address and bit
416
displacement. One might imagine that a translator could implement
417
BITFIELD alignments so that they are the same as the smallest natural
418
alignment of the machine and avoid the bit displacement, but this
419
is not the intention of the definition. On any machine for which it
420
is meaningful, the alignment of a BITFIELD must be one bit; in other
421
words successive BITFIELDs are butted together with no padding bits
422
<A NAME=footnote73 HREF="footnote.html#73">*</A>. Within the limits
423
of what one can extract from BITFIELDs, namely INTEGER VARIETYs, this
424
is how one should implement non-standard alignments, perhaps in constructing
425
data, such as protocols, for exchange between machines. One could
426
implement some Ada representational statements in this way; certainly
427
the most commonly used ones.<P>
428
TDF Version 3.0 does not allow one to construct a pointer of SHAPE
429
POINTER(b) where b consists entirely of bitfield alignments; this
430
relieves the translators of the burden of doing general bit-addressing.
431
Of course, this simply shifts the burden to the producer. If the high
432
level language requires to construct a pointer to an arbitrary bit
433
position, then the producer is required to represent such a pointer
434
as a pair consisting of pointer to some alignment including the required
435
bitfield and an offset from this alignment to the bitfield. For example,
436
Ada may require the construction of a pointer to a boolean for use
437
as the parameter to a procedure; the SHAPE of the rep resentation
438
of this Ada pointer could be a COMPOUND formed from a POINTER({x,b})
439
and an OFFSET({x, b}, b) where b is the alignment given by a 1 bit
440
alignment. To access the boolean, the producer would use the elements
441
of this pair as arguements to bitfield_assign and bitfield_contents
442
(<A HREF="guide9.html#16">Assigning and extracting bitfields on page
443
39</A>.).<P>
444
<HR>
445
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
446
Copyright &copy; 1998.</I></P>
447
</BODY>
448
</HTML>