1-- CXG2022.A
2--
3--                             Grant of Unlimited Rights
4--
5--     Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
6--     F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
7--     unlimited rights in the software and documentation contained herein.
8--     Unlimited rights are defined in DFAR 252.227-7013(a)(19).  By making
9--     this public release, the Government intends to confer upon all
10--     recipients unlimited rights  equal to those held by the Government.
11--     These rights include rights to use, duplicate, release or disclose the
12--     released technical data and computer software in whole or in part, in
13--     any manner and for any purpose whatsoever, and to have or permit others
14--     to do so.
15--
16--                                    DISCLAIMER
17--
18--     ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
19--     DISCLOSED ARE AS IS.  THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
20--     WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
21--     SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
22--     OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
23--     PARTICULAR PURPOSE OF SAID MATERIAL.
24--*
25--
26-- OBJECTIVE:
27--      Check that multiplication and division of binary fixed point
28--      numbers with compatible 'small values produce exact results.
29--
30-- TEST DESCRIPTION:
31--      Signed, unsigned, and a mixture of signed and unsigned
32--      binary fixed point values are multiplied and divided.
33--      The result is checked against the expected "perfect result set"
34--
35-- SPECIAL REQUIREMENTS
36--      The Strict Mode for the numerical accuracy must be
37--      selected.  The method by which this mode is selected
38--      is implementation dependent.
39--
40-- APPLICABILITY CRITERIA:
41--      This test applies only to implementations supporting the
42--      Numerics Annex.
43--      This test only applies to the Strict Mode for numerical
44--      accuracy.
45--
46--
47-- CHANGE HISTORY:
48--       1 Apr 96   SAIC    Initial release for 2.1
49--      29 Jan 1998 EDS     Repaired fixed point errors ("**" and
50--                          assumptions about 'Small)
51--!
52
53with System;
54with Report;
55procedure CXG2022 is
56   Verbose : constant Boolean := False;
57
58procedure Check_Signed is
59   type Pairs is delta 2.0 range -2.0 ** (System.Max_Mantissa) ..
60                                  2.0 ** (System.Max_Mantissa) - 1.0;
61   type Halves is delta 0.5 range -2.0 ** (System.Max_Mantissa-2) ..
62                                   2.0 ** (System.Max_Mantissa-2) - 1.0;
63   P1, P2, P3, P4 : Pairs;
64   H1, H2, H3, H4 : Halves;
65
66   procedure Dont_Opt is
67   -- keep optimizer from knowing the constant value of expressions
68   begin
69      if Report.Ident_Bool (False) then
70         P1 :=  2.0;  P2 := 4.0;  P3 := 6.0;
71         H1 := -2.0;  H2 := 9.0;  H3 := 3.0;
72      end if;
73   end Dont_Opt;
74
75begin
76   H1 := -0.5;
77   H2 := Halves'First;
78   H3 := 1.0;
79   P1 := 12.0;
80   P2 := Pairs'First;
81   P3 := Pairs'Last;
82   Dont_Opt;
83
84   P4 := Pairs (P1 * H1);     -- 12.0 * -0.5
85   if P4 /= -6.0 then
86      Report.Failed ("12.0 * -0.5 = " & Pairs'Image (P4));
87   end if;
88
89   H4 := Halves (P1 / H1);     -- 12.0 / -0.5
90   if H4 /= -24.0 then
91      Report.Failed ("12.0 / -0.5 = " & Halves'Image (H4));
92   end if;
93
94   P4 := P3 * H3;     -- Pairs'Last * 1.0
95   if P4 /= Pairs'Last then
96      Report.Failed ("Pairs'Last * 1.0 = " & Pairs'Image (P4));
97   end if;
98
99   P4 := P3 / H3;     -- Pairs'Last / 1.0
100   if P4 /= Pairs'Last then
101      Report.Failed ("Pairs'Last / 1.0 = " & Pairs'Image (P4));
102   end if;
103
104   P4 := P2 * 0.25;     -- Pairs'First * 0.25
105   if P4 /= Pairs (-2.0 ** (System.Max_Mantissa - 2)) then
106      Report.Failed ("Pairs'First * 0.25 = " & Pairs'Image (P4));
107   end if;
108
109   P4 := 100.5 / H1;   -- 100.5 / -0.5
110   if P4 = -201.0 then
111      null;   -- Perfect result
112   elsif Pairs'Small = 2.0 and ( P4 = -200.0 or P4 = -202.0 ) then
113      null;   -- Allowed variation
114   else
115      Report.Failed ("Pairs'Small =" & Pairs'Image (Pairs'Small) &
116                     " and 100.5/-0.5 = " & Pairs'Image (P4) );
117   end if;
118
119   H4 := H1 * H2;   --  -0.5 * Halves'First
120   if H4 /= Halves (2.0 ** (System.Max_Mantissa-3)) then
121      Report.Failed ("-0.5 * Halves'First =" & Halves'Image (H4) &
122                     " instead of " &
123                     Halves'Image( Halves(2.0 ** (System.Max_Mantissa-3))));
124   end if;
125
126exception
127   when others =>
128      Report.Failed ("unexpected exception in Check_Signed");
129end Check_Signed;
130
131
132
133procedure Check_Unsigned is
134   type Pairs is delta 2.0 range 0.0 .. 2.0 ** (System.Max_Mantissa+1) - 1.0;
135   type Halves is delta 0.5 range 0.0 .. 2.0 ** (System.Max_Mantissa-1) - 1.0;
136   P1, P2, P3, P4 : Pairs;
137   H1, H2, H3, H4 : Halves;
138
139   procedure Dont_Opt is
140   -- keep optimizer from knowing the constant value of expressions
141   begin
142      if Report.Ident_Bool (False) then
143         P1 :=  2.0;  P2 := 4.0;  P3 := 6.0;
144         H1 :=  2.0;  H2 := 9.0;  H3 := 3.0;
145      end if;
146   end Dont_Opt;
147
148begin
149   H1 := 10.5;
150   H2 := Halves(2.0 ** (System.Max_Mantissa - 6));
151   H3 := 1.0;
152   P1 := 12.0;
153   P2 := Pairs'Last / 2;
154   P3 := Pairs'Last;
155   Dont_Opt;
156
157   P4 := Pairs (P1 * H1);     -- 12.0 * 10.5
158   if P4 /= 126.0 then
159      Report.Failed ("12.0 * 10.5 = " & Pairs'Image (P4));
160   end if;
161
162   H4 := Halves (P1 / H1);     -- 12.0 / 10.5
163   if H4 /= 1.0 and H4 /= 1.5 then
164      Report.Failed ("12.0 / 10.5 = " & Halves'Image (H4));
165   end if;
166
167   P4 := P3 * H3;     -- Pairs'Last * 1.0
168   if P4 /= Pairs'Last then
169      Report.Failed ("Pairs'Last * 1.0 = " & Pairs'Image (P4));
170   end if;
171
172   P4 := P3 / H3;     -- Pairs'Last / 1.0
173   if P4 /= Pairs'Last then
174      Report.Failed ("Pairs'Last / 1.0 = " & Pairs'Image (P4));
175   end if;
176
177   P4 := P1 * 0.25;     -- 12.0 * 0.25
178   if P4 /= 2.0 and P4 /= 4.0 then
179      Report.Failed ("12.0 * 0.25 = " & Pairs'Image (P4));
180   end if;
181
182   P4 := 100.5 / H1;   -- 100.5 / 10.5    = 9.571...
183   if P4 /= 8.0 and P4 /= 10.0 then
184      Report.Failed ("100.5/10.5 = " & Pairs'Image (P4));
185   end if;
186
187   H4 := H2 * 2;   --  2**(max_mantissa-6) * 2
188   if H4 /= Halves(2.0 ** (System.Max_Mantissa-5)) then
189      Report.Failed ("2**(System.Max_Mantissa-6) * 2=" & Halves'Image (H4) &
190                     " instead of " &
191                     Halves'Image( Halves(2.0 ** (System.Max_Mantissa-5))));
192   end if;
193
194exception
195   when others =>
196      Report.Failed ("unexpected exception in Check_Unsigned");
197end Check_Unsigned;
198
199
200
201procedure Check_Mixed is
202   type Pairs is delta 2.0 range -2.0 ** (System.Max_Mantissa) ..
203                                  2.0 ** (System.Max_Mantissa) - 1.0;
204   type Halves is delta 0.5 range 0.0 .. 2.0 ** (System.Max_Mantissa-1) - 1.0;
205   P1, P2, P3, P4 : Pairs;
206   H1, H2, H3, H4 : Halves;
207
208   procedure Dont_Opt is
209   -- keep optimizer from knowing the constant value of expressions
210   begin
211      if Report.Ident_Bool (False) then
212         P1 :=  2.0;  P2 := 4.0;  P3 := 6.0;
213         H1 :=  2.0;  H2 := 9.0;  H3 := 3.0;
214      end if;
215   end Dont_Opt;
216
217begin
218   H1 := 10.5;
219   H2 := Halves(2.0 ** (System.Max_Mantissa - 6));
220   H3 := 1.0;
221   P1 := 12.0;
222   P2 := -4.0;
223   P3 := Pairs'Last;
224   Dont_Opt;
225
226   P4 := Pairs (P1 * H1);     -- 12.0 * 10.5
227   if P4 /= 126.0 then
228      Report.Failed ("12.0 * 10.5 = " & Pairs'Image (P4));
229   end if;
230
231   H4 := Halves (P1 / H1);     -- 12.0 / 10.5
232   if H4 /= 1.0 and H4 /= 1.5 then
233      Report.Failed ("12.0 / 10.5 = " & Halves'Image (H4));
234   end if;
235
236   P4 := P3 * H3;     -- Pairs'Last * 1.0
237   if P4 /= Pairs'Last then
238      Report.Failed ("Pairs'Last * 1.0 = " & Pairs'Image (P4));
239   end if;
240
241   P4 := P3 / H3;     -- Pairs'Last / 1.0
242   if P4 /= Pairs'Last then
243      Report.Failed ("Pairs'Last / 1.0 = " & Pairs'Image (P4));
244   end if;
245
246   P4 := P1 * 0.25;   -- 12.0 * 0.25
247   if P4 = 3.0 then
248      null;    -- Perfect result
249   elsif Pairs'Small = 2.0 and then ( P4 = 2.0 or P4 = 4.0 ) then
250      null;    -- Allowed deviation
251   else
252      Report.Failed ("Pairs'Small =" & Pairs'Image (Pairs'Small) &
253                     "and 12.0 * 0.25 = " & Pairs'Image (P4) );
254   end if;
255
256   P4 := 100.5 / H1;   -- 100.5 / 10.5    = 9.571...
257   if P4 = 9.0 then
258      null;    -- Perfect result
259   elsif Pairs'Small = 2.0 and then ( P4 = 8.0 or P4 = 10.0 ) then
260      null;    -- Allowed values
261   else
262     Report.Failed ("Pairs'Small =" & Pairs'Image (Pairs'Small) &
263                    "and 100.5/10.5 = " & Pairs'Image (P4) );
264   end if;
265
266   H4 := H2 * 2;   --  2**(max_mantissa-6) * 2
267   if H4 /= Halves(2.0 ** (System.Max_Mantissa-5)) then
268      Report.Failed ("2**(System.Max_Mantissa-6) * 2=" & Halves'Image (H4) &
269                     " instead of " &
270                     Halves'Image( Halves(2.0 ** (System.Max_Mantissa-5))));
271   end if;
272
273   P4 := Pairs(P1 * 6) / P2;    -- 12 * 6 / -4
274   if (P4 /= -18.0)  then
275      Report.Failed ("12*6/-4 = " & Pairs'Image(P4));
276   end if;
277
278   P4 := Halves(P1 * 6.0) / P2;    -- 12 * 6 / -4
279   if (P4 /= -18.0)  then
280      Report.Failed ("Halves(12*6)/-4 = " & Pairs'Image(P4));
281   end if;
282
283exception
284   when others =>
285      Report.Failed ("unexpected exception in Check_Mixed");
286end Check_Mixed;
287
288
289begin  -- main
290   Report.Test ("CXG2022",
291                "Check the accuracy of multiplication and division" &
292                " of binary fixed point numbers");
293   if Verbose then
294      Report.Comment ("starting signed test");
295   end if;
296   Check_Signed;
297
298   if Verbose then
299      Report.Comment ("starting unsigned test");
300   end if;
301   Check_Unsigned;
302
303   if Verbose then
304      Report.Comment ("starting mixed sign test");
305   end if;
306   Check_Mixed;
307
308   Report.Result;
309end CXG2022;
310