2 |
7u83 |
1 |
<!-- Crown Copyright (c) 1998 -->
|
|
|
2 |
<HTML>
|
|
|
3 |
<HEAD>
|
|
|
4 |
<TITLE>Operations</TITLE>
|
|
|
5 |
</HEAD>
|
|
|
6 |
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
|
|
|
7 |
<A NAME=S66>
|
|
|
8 |
<H1>TDF Guide, Issue 4.0 </H1>
|
|
|
9 |
<H3>January 1998</H3>
|
|
|
10 |
<A HREF="guide11.html"><IMG SRC="../images/next.gif" ALT="next section"></A>
|
|
|
11 |
<A HREF="guide9.html"><IMG SRC="../images/prev.gif" ALT="previous section"></A>
|
|
|
12 |
<A HREF="guide1.html"><IMG SRC="../images/top.gif" ALT="current document"></A>
|
|
|
13 |
<A HREF="../index.html"><IMG SRC="../images/home.gif" ALT="TenDRA home page">
|
|
|
14 |
</A>
|
|
|
15 |
<IMG SRC="../images/no_index.gif" ALT="document index"><P>
|
|
|
16 |
<HR>
|
|
|
17 |
<DL>
|
|
|
18 |
<DT><A HREF="#S67"><B>8.1 </B> - VARIETY and overflow</A><DD>
|
|
|
19 |
<DT><A HREF="#S68"><B>8.1.1 </B> - ERROR_TREATMENT</A><DD>
|
|
|
20 |
<DT><A HREF="#S69"><B>8.2 </B> - Division and remainder</A>
|
|
|
21 |
<DD>
|
|
|
22 |
<DT><A HREF="#S70"><B>8.3 </B> - change_variety</A><DD>
|
|
|
23 |
<DT><A HREF="#S71"><B>8.4 </B> - and, or, not, xor</A><DD>
|
|
|
24 |
<DT><A HREF="#S72"><B>8.5 </B> - Floating-point operations, ROUNDING_MODE</A>
|
|
|
25 |
<DD>
|
|
|
26 |
<DT><A HREF="#S73"><B>8.6 </B> - change_bitfield_to_int, change_int_to_bitfield
|
|
|
27 |
</A><DD>
|
|
|
28 |
<DT><A HREF="#S74"><B>8.7 </B> - make_compound, make_nof, n_copies</A><DD>
|
|
|
29 |
</DL>
|
|
|
30 |
<HR>
|
|
|
31 |
<H1>8 Operations</H1>
|
|
|
32 |
Most of the arithmetic operations of TDF have familiar analogues in
|
|
|
33 |
standard languages and processors. They differ principally in how
|
|
|
34 |
error conditions (e.g. numeric overflow) are handled. There is a wide
|
|
|
35 |
diversity in error handling in both languages and processors, so TDF
|
|
|
36 |
tries to reduce it to the simplest primitive level compatible with
|
|
|
37 |
their desired operation in languages and their implementation on processors.
|
|
|
38 |
Before delving into the details of error handling, it is worthwhile
|
|
|
39 |
revisiting the SHAPEs and ranges in arithmetic VARIETYs.<P>
|
|
|
40 |
<A NAME=S67>
|
|
|
41 |
<HR><H2>8.1. VARIETY and overflow</H2>
|
|
|
42 |
An INTEGER VARIETY, for example, is defined by some range of signed
|
|
|
43 |
natural numbers. A translator will fit this range into some possibly
|
|
|
44 |
larger range which is convenient for the processor in question. For
|
|
|
45 |
example, the integers with variety(1,10) would probably be represented
|
|
|
46 |
as unsigned characters with range (0..255), a convenient representation
|
|
|
47 |
for both storage and arithmetic. <P>
|
|
|
48 |
The question then arises of what is meant by overflow in an operation
|
|
|
49 |
which is meant to deliver an integer of this VARIETY - is it when
|
|
|
50 |
the integer result is outside the range (1..10) or outside the range
|
|
|
51 |
(0..255)? For purely pragmatic reasons, TDF chooses the latter - the
|
|
|
52 |
result is overflowed when it is outside its representational range
|
|
|
53 |
(0..255). If the program insists that it must be within (1..10), then
|
|
|
54 |
it can always test for it. If the program uses the error handling
|
|
|
55 |
mechanism and the result is outside (1..10) but still within the representational
|
|
|
56 |
limits, then, in order for the program to be portable, then the error
|
|
|
57 |
handling actions must in some sense be "continuous" with
|
|
|
58 |
the normal action. This would not be the case if, for example, the
|
|
|
59 |
value was used to index an array with bounds (1..10), but will usually
|
|
|
60 |
be the case where the value is used in further arithmetic operations
|
|
|
61 |
which have similar error handling. The arithmetic will continue to
|
|
|
62 |
give the mathematically correct result provided the representational
|
|
|
63 |
bounds are not exceeded.<P>
|
|
|
64 |
The limits in a VARIETY are there to provide a guide to its representation,
|
|
|
65 |
and not to give hard limits to its possible values. This choice is
|
|
|
66 |
consistent with the general TDF philosophy of how exceptions are to
|
|
|
67 |
be treated. If, for example, one wishes to do array-bound checking,
|
|
|
68 |
then it must be done by explicit tests on the indices and jumping
|
|
|
69 |
to some exception action if they fail. Similarly, explicit tests can
|
|
|
70 |
be made on an integer value, provided its representational limits
|
|
|
71 |
are not exceeded. It is unlikely that a translator could produce any
|
|
|
72 |
more efficient code, in general, if the tests were implicit. The representational
|
|
|
73 |
limits can be exceeded in arithmetic operations, so facilities are
|
|
|
74 |
provided to either to ignore it , to allow one to jump to a label
|
|
|
75 |
, or to obey a TDF exception handler if it happens.<P>
|
|
|
76 |
<A NAME=S68>
|
|
|
77 |
<H3>8.1.1. <A NAME=6>ERROR_TREATMENT</H3>
|
|
|
78 |
Taking integer addition as an example, plus has signature:<P>
|
|
|
79 |
<PRE>
|
|
|
80 |
<I> ov_err</I>: ERROR_TREATMENT
|
|
|
81 |
<I> arg1</I>: EXP INTEGER(<I>v</I>)
|
|
|
82 |
<I> arg2</I>: EXP INTEGER(<I>v</I>)
|
|
|
83 |
-> EXP INTEGER(<I>v</I>)
|
|
|
84 |
</PRE>
|
|
|
85 |
The result of the addition has the same integer VARIETY as its parameters.
|
|
|
86 |
If the representational bounds of <I>v</I> are exceeded, then the
|
|
|
87 |
action taken depends on the ERROR_TREATMENT <I>ov_err</I>. <P>
|
|
|
88 |
The ERROR_TREATMENT , impossible, is an assertion by the producer
|
|
|
89 |
that overflow will not occur; on its head be it if it does.<P>
|
|
|
90 |
The ERROR_TREATMENTS continue and wrap give "fixup" values
|
|
|
91 |
for the result. For continue the fixup value is undefined. For wrap,
|
|
|
92 |
the the answer will be modulo 2 to the power of the number of bits
|
|
|
93 |
in the representational variety.Thus, integer arithmetic with byte
|
|
|
94 |
representational variety is done modulo 256. This just corresponds
|
|
|
95 |
to what happens in most processors and, incidentally, the definition
|
|
|
96 |
of C. <P>
|
|
|
97 |
The ERROR_TREATMENT that one would use if one wished to jump to a
|
|
|
98 |
label is error_jump:<P>
|
|
|
99 |
<PRE>
|
|
|
100 |
<I> lab</I>: LABEL
|
|
|
101 |
-> ERROR_TREATMENT
|
|
|
102 |
</PRE>
|
|
|
103 |
A branch to <I>lab</I> will occur if the result overflows. <P>
|
|
|
104 |
The ERROR_TREATMENT, trap(overflow) will raise a TDF exception(see
|
|
|
105 |
<A HREF="guide8.html#31">section 6.3 on page 35</A>)with ERROR_CODE
|
|
|
106 |
overflow if overflow occurs.<P>
|
|
|
107 |
<P>
|
|
|
108 |
<A NAME=S69>
|
|
|
109 |
<HR><H2>8.2. Division and remainder</H2>
|
|
|
110 |
The various constructors in involving integer division (e.g. div1,
|
|
|
111 |
rem1) have two ERROR_TREATMENT parameters, one for overflow and one
|
|
|
112 |
for divide-by-zero e.g. div1 is:<P>
|
|
|
113 |
<PRE>
|
|
|
114 |
<I>div_by_zero_error</I>: ERROR_TREATMENT
|
|
|
115 |
<I>ov_err</I>: ERROR_TREATMENT
|
|
|
116 |
<I>arg1</I>: EXP INTEGER(<I>v</I>)
|
|
|
117 |
<I>arg2</I>: EXP INTEGER(<I>v</I>)
|
|
|
118 |
-> EXP INTEGER(<I>v</I>)
|
|
|
119 |
</PRE>
|
|
|
120 |
. There are two different kinds of division operators (with corresponding
|
|
|
121 |
remainder operators) defined. The operators div2 and rem2 are those
|
|
|
122 |
generally implemented directly by processor instructions giving the
|
|
|
123 |
sign of the remainder the same as the sign of the quotient. The other
|
|
|
124 |
pair, div1 and rem1, is less commonly implemented in hardware, but
|
|
|
125 |
have rather more consistent mathematical properties; here the sign
|
|
|
126 |
of remainder is the same as the sign of divisor. Thus, div1(x, 2)
|
|
|
127 |
is the same as shift_right(x, 1) which is only true for div2 if x
|
|
|
128 |
is positive. The two pairs of operations give the same results if
|
|
|
129 |
both operands have the same sign. The constructors div0 and rem0 allow
|
|
|
130 |
the translator to choose whichever of the two forms of division is
|
|
|
131 |
convenient - the producer is saying that he does not care which is
|
|
|
132 |
used, as long as they are pairwise consistent. The precise definition
|
|
|
133 |
of the divide operations is given in (S7.4)</A>.<P>
|
|
|
134 |
<A NAME=S70>
|
|
|
135 |
<HR><H2>8.3. change_variety</H2>
|
|
|
136 |
Conversions between the various INTEGER varieties are provided for
|
|
|
137 |
by change_variety:<P>
|
|
|
138 |
<PRE>
|
|
|
139 |
<I>ov_err</I>: ERROR_TREATMENT
|
|
|
140 |
<I> r</I>: VARIETY
|
|
|
141 |
<I> arg1</I>: EXP INTEGER(<I>v</I>)
|
|
|
142 |
-> EXP INTEGER(<I>r</I>)
|
|
|
143 |
</PRE>
|
|
|
144 |
If the value <I>arg1</I> is outside the limits of the representational
|
|
|
145 |
variety of <I>r</I>, then the ERROR_TREATMENT <I>ov_err</I> will be
|
|
|
146 |
invoked.<P>
|
|
|
147 |
<A NAME=S71>
|
|
|
148 |
<HR><H2>8.4. and, or, not, xor</H2>
|
|
|
149 |
The standard logical operations, and, not, or and xor are provided
|
|
|
150 |
for all integer varieties. Since integer varieties are defined to
|
|
|
151 |
be represented in twos-complement the result of these operations are
|
|
|
152 |
well defined.<P>
|
|
|
153 |
<A NAME=S72>
|
|
|
154 |
<HR><H2>8.5. Floating-point operations, ROUNDING_MODE</H2>
|
|
|
155 |
All of the floating-point (including complex) operations include ERROR-TREATMENTs.
|
|
|
156 |
If the result of a floating-point operation cannot be represented
|
|
|
157 |
in the desired FLOATING_VARIETY, the error treatment is invoked. If
|
|
|
158 |
the ERROR_TREATMENT is wrap or impossible, the result is undefined;
|
|
|
159 |
otherwise the jump operates in the same way as for integer operations.
|
|
|
160 |
Both floating_plus and floating_mult are defined as n-ary operations.
|
|
|
161 |
In general, floating addition and multiplication are not associative,
|
|
|
162 |
but a producer may not care about the order in which they are to be
|
|
|
163 |
performed. Making them appear as though they were associative allows
|
|
|
164 |
the translator to choose an order which is convenient to the hardware.<P>
|
|
|
165 |
Conversions from integer to floating are done by float_int and from
|
|
|
166 |
floating to integers by round_with_mode . This latter constructor
|
|
|
167 |
has a parameter of SORT ROUNDING_MODE which effectively gives the
|
|
|
168 |
IEEE rounding mode to be applied to the float to produce its integer
|
|
|
169 |
result.<P>
|
|
|
170 |
One can extract the real and imaginary parts of a complex FLOATING
|
|
|
171 |
using real_part and imaginary_part. A complex FLOATING can be constructed
|
|
|
172 |
using make_complex. Normal complex arithmetic applies to all the other
|
|
|
173 |
FLOATING constructors except for those explicitly excluded (eg floating_abs,
|
|
|
174 |
floating_max etc.)<P>
|
|
|
175 |
<A NAME=S73>
|
|
|
176 |
<HR><H2>8.6. change_bitfield_to_int, change_int_to_bitfield</H2>
|
|
|
177 |
There are two bit-field operation, change_bitfield_to_int and change_int_to_bitfield
|
|
|
178 |
to transform between bit-fields and integers. If the varieties do
|
|
|
179 |
not fit the result is undefined; the producer can always get it right.<P>
|
|
|
180 |
<A NAME=S74>
|
|
|
181 |
<HR><H2>8.7. <A NAME=36>make_compound, make_nof, n_copies</H2>
|
|
|
182 |
There is one operation to make values of COMPOUND SHAPE, make_compound:
|
|
|
183 |
<P>
|
|
|
184 |
<PRE>
|
|
|
185 |
<I> arg1</I>: EXP OFFSET(<I>base, y</I>)
|
|
|
186 |
<I> arg2</I>: LIST(EXP)
|
|
|
187 |
-> EXP COMPOUND(<I>sz</I>)
|
|
|
188 |
</PRE>
|
|
|
189 |
The OFFSET <I>arg1</I> is evaluated as a translate-time constant to
|
|
|
190 |
give <I>sz</I>, the size of the compound object. The EXPs of arg2
|
|
|
191 |
are alternately OFFSETs (also translate-time constants) and values
|
|
|
192 |
which will be placed at those offsets. This constructor is used to
|
|
|
193 |
construct values given by structure displays; in C, these only occur
|
|
|
194 |
with constant <I>val[i]</I> in global definitions. It is also used
|
|
|
195 |
to provide union injectors; here <I>sz</I> would be the size of the
|
|
|
196 |
union and the list would probably two elements with the first being
|
|
|
197 |
an offset_zero.<P>
|
|
|
198 |
Constant sized array values may be constructed using make_nof, make_nof_int
|
|
|
199 |
(see <A HREF="#36">section 8.7 on page 42</A>), and n_copies. Again,
|
|
|
200 |
they only occur in C as constants in global definitions.<P>
|
|
|
201 |
<HR>
|
|
|
202 |
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
|
|
|
203 |
Copyright © 1998.</I></P>
|
|
|
204 |
</BODY>
|
|
|
205 |
</HTML>
|