xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpn/t-instrument.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /* Test assembler support for --enable-profiling=instrument.
2 
3 Copyright 2002, 2003 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library test suite.
6 
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11 
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "gmp.h"
23 #include "gmp-impl.h"
24 #include "longlong.h"
25 #include "tests.h"
26 
27 
28 #if WANT_PROFILING_INSTRUMENT
29 
30 /* This program exercises each mpn routine that might be implemented in
31    assembler.  It ensures the __cyg_profile_func_enter and exit calls have
32    come out right, and that in the x86 code "ret_internal" is correctly used
33    for PIC setups.  */
34 
35 
36 /* Changes to enter_seen done by __cyg_profile_func_enter are essentially
37    unknown to the optimizer, so must use volatile.  */
38 volatile int  enter_seen;
39 
40 /* Dummy used to stop various calls going dead. */
41 unsigned long  notdead;
42 
43 const char     *name = "<none>";
44 int  old_ncall;
45 
46 struct {
47   void  *this_fn;
48   void  *call_site;
49 } call[100];
50 int  ncall;
51 
52 
53 void __cyg_profile_func_enter (void *, void *)
54   __attribute__ ((no_instrument_function));
55 
56 void
57 __cyg_profile_func_enter (void *this_fn, void *call_site)
58 {
59 #if 0
60   printf ("%24s %p %p\n", name, this_fn, call_site);
61 #endif
62   ASSERT_ALWAYS (ncall >= 0);
63   ASSERT_ALWAYS (ncall <= numberof (call));
64 
65   if (ncall >= numberof (call))
66     {
67       printf ("__cyg_profile_func_enter: oops, call stack full, from %s\n", name);
68       abort ();
69     }
70 
71   enter_seen = 1;
72   call[ncall].this_fn = this_fn;
73   call[ncall].call_site = call_site;
74   ncall++;
75 }
76 
77 void __cyg_profile_func_exit (void *, void *)
78   __attribute__ ((no_instrument_function));
79 
80 void
81 __cyg_profile_func_exit  (void *this_fn, void *call_site)
82 {
83   ASSERT_ALWAYS (ncall >= 0);
84   ASSERT_ALWAYS (ncall <= numberof (call));
85 
86   if (ncall == 0)
87     {
88       printf ("__cyg_profile_func_exit: call stack empty, from %s\n", name);
89       abort ();
90     }
91 
92   ncall--;
93   if (this_fn != call[ncall].this_fn || call_site != call[ncall].call_site)
94     {
95       printf ("__cyg_profile_func_exit: unbalanced this_fn/call_site from %s\n", name);
96       printf ("  this_fn got  %p\n", this_fn);
97       printf ("          want %p\n", call[ncall].this_fn);
98       printf ("  call_site got  %p\n", call_site);
99       printf ("            want %p\n", call[ncall].call_site);
100       abort ();
101     }
102 }
103 
104 
105 void
106 pre (const char *str)
107 {
108   name = str;
109   enter_seen = 0;
110   old_ncall = ncall;
111 }
112 
113 void
114 post (void)
115 {
116   if (! enter_seen)
117     {
118       printf ("did not reach __cyg_profile_func_enter from %s\n", name);
119       abort ();
120     }
121 
122   if (ncall != old_ncall)
123     {
124       printf ("unbalance enter/exit calls from %s\n", name);
125       printf ("  ncall     %d\n", ncall);
126       printf ("  old_ncall %d\n", old_ncall);
127       abort ();
128     }
129 }
130 
131 void
132 check (void)
133 {
134   mp_limb_t  wp[100], xp[100], yp[100];
135   mp_size_t  size = 100;
136 
137   refmpn_zero (xp, size);
138   refmpn_zero (yp, size);
139   refmpn_zero (wp, size);
140 
141   pre ("mpn_add_n");
142   mpn_add_n (wp, xp, yp, size);
143   post ();
144 
145 #if HAVE_NATIVE_mpn_add_nc
146   pre ("mpn_add_nc");
147   mpn_add_nc (wp, xp, yp, size, CNST_LIMB(0));
148   post ();
149 #endif
150 
151 #if HAVE_NATIVE_mpn_addlsh1_n
152   pre ("mpn_addlsh1_n");
153   mpn_addlsh1_n (wp, xp, yp, size);
154   post ();
155 #endif
156 
157 #if HAVE_NATIVE_mpn_and_n
158   pre ("mpn_and_n");
159   mpn_and_n (wp, xp, yp, size);
160   post ();
161 #endif
162 
163 #if HAVE_NATIVE_mpn_andn_n
164   pre ("mpn_andn_n");
165   mpn_andn_n (wp, xp, yp, size);
166   post ();
167 #endif
168 
169   pre ("mpn_addmul_1");
170   mpn_addmul_1 (wp, xp, size, yp[0]);
171   post ();
172 
173 #if HAVE_NATIVE_mpn_addmul_1c
174   pre ("mpn_addmul_1c");
175   mpn_addmul_1c (wp, xp, size, yp[0], CNST_LIMB(0));
176   post ();
177 #endif
178 
179 #if HAVE_NATIVE_mpn_com
180   pre ("mpn_com");
181   mpn_com (wp, xp, size);
182   post ();
183 #endif
184 
185 #if HAVE_NATIVE_mpn_copyd
186   pre ("mpn_copyd");
187   mpn_copyd (wp, xp, size);
188   post ();
189 #endif
190 
191 #if HAVE_NATIVE_mpn_copyi
192   pre ("mpn_copyi");
193   mpn_copyi (wp, xp, size);
194   post ();
195 #endif
196 
197   pre ("mpn_divexact_1");
198   mpn_divexact_1 (wp, xp, size, CNST_LIMB(123));
199   post ();
200 
201   pre ("mpn_divexact_by3c");
202   mpn_divexact_by3c (wp, xp, size, CNST_LIMB(0));
203   post ();
204 
205   pre ("mpn_divrem_1");
206   mpn_divrem_1 (wp, (mp_size_t) 0, xp, size, CNST_LIMB(123));
207   post ();
208 
209 #if HAVE_NATIVE_mpn_divrem_1c
210   pre ("mpn_divrem_1c");
211   mpn_divrem_1c (wp, (mp_size_t) 0, xp, size, CNST_LIMB(123), CNST_LIMB(122));
212   post ();
213 #endif
214 
215   pre ("mpn_gcd_1");
216   xp[0] |= 1;
217   notdead += (unsigned long) mpn_gcd_1 (xp, size, CNST_LIMB(123));
218   post ();
219 
220   pre ("mpn_hamdist");
221   notdead += mpn_hamdist (xp, yp, size);
222   post ();
223 
224 #if HAVE_NATIVE_mpn_ior_n
225   pre ("mpn_ior_n");
226   mpn_ior_n (wp, xp, yp, size);
227   post ();
228 #endif
229 
230 #if HAVE_NATIVE_mpn_iorn_n
231   pre ("mpn_iorn_n");
232   mpn_iorn_n (wp, xp, yp, size);
233   post ();
234 #endif
235 
236   pre ("mpn_lshift");
237   mpn_lshift (wp, xp, size, 1);
238   post ();
239 
240   pre ("mpn_mod_1");
241   notdead += mpn_mod_1 (xp, size, CNST_LIMB(123));
242   post ();
243 
244 #if HAVE_NATIVE_mpn_mod_1c
245   pre ("mpn_mod_1c");
246   notdead += mpn_mod_1c (xp, size, CNST_LIMB(123), CNST_LIMB(122));
247   post ();
248 #endif
249 
250 #if GMP_NUMB_BITS % 4 == 0
251   pre ("mpn_mod_34lsub1");
252   notdead += mpn_mod_34lsub1 (xp, size);
253   post ();
254 #endif
255 
256   pre ("mpn_modexact_1_odd");
257   notdead += mpn_modexact_1_odd (xp, size, CNST_LIMB(123));
258   post ();
259 
260   pre ("mpn_modexact_1c_odd");
261   notdead += mpn_modexact_1c_odd (xp, size, CNST_LIMB(123), CNST_LIMB(456));
262   post ();
263 
264   pre ("mpn_mul_1");
265   mpn_mul_1 (wp, xp, size, yp[0]);
266   post ();
267 
268 #if HAVE_NATIVE_mpn_mul_1c
269   pre ("mpn_mul_1c");
270   mpn_mul_1c (wp, xp, size, yp[0], CNST_LIMB(0));
271   post ();
272 #endif
273 
274 #if HAVE_NATIVE_mpn_mul_2
275   pre ("mpn_mul_2");
276   mpn_mul_2 (wp, xp, size-1, yp);
277   post ();
278 #endif
279 
280   pre ("mpn_mul_basecase");
281   mpn_mul_basecase (wp, xp, (mp_size_t) 3, yp, (mp_size_t) 3);
282   post ();
283 
284 #if HAVE_NATIVE_mpn_nand_n
285   pre ("mpn_nand_n");
286   mpn_nand_n (wp, xp, yp, size);
287   post ();
288 #endif
289 
290 #if HAVE_NATIVE_mpn_nior_n
291   pre ("mpn_nior_n");
292   mpn_nior_n (wp, xp, yp, size);
293   post ();
294 #endif
295 
296   pre ("mpn_popcount");
297   notdead += mpn_popcount (xp, size);
298   post ();
299 
300   pre ("mpn_preinv_mod_1");
301   notdead += mpn_preinv_mod_1 (xp, size, GMP_NUMB_MAX,
302                                refmpn_invert_limb (GMP_NUMB_MAX));
303   post ();
304 
305 #if USE_PREINV_DIVREM_1 || HAVE_NATIVE_mpn_preinv_divrem_1
306   pre ("mpn_preinv_divrem_1");
307   mpn_preinv_divrem_1 (wp, (mp_size_t) 0, xp, size, GMP_NUMB_MAX,
308                        refmpn_invert_limb (GMP_NUMB_MAX), 0);
309   post ();
310 #endif
311 
312 #if HAVE_NATIVE_mpn_rsh1add_n
313   pre ("mpn_rsh1add_n");
314   mpn_rsh1add_n (wp, xp, yp, size);
315   post ();
316 #endif
317 
318 #if HAVE_NATIVE_mpn_rsh1sub_n
319   pre ("mpn_rsh1sub_n");
320   mpn_rsh1sub_n (wp, xp, yp, size);
321   post ();
322 #endif
323 
324   pre ("mpn_rshift");
325   mpn_rshift (wp, xp, size, 1);
326   post ();
327 
328   pre ("mpn_sqr_basecase");
329   mpn_sqr_basecase (wp, xp, (mp_size_t) 3);
330   post ();
331 
332   pre ("mpn_submul_1");
333   mpn_submul_1 (wp, xp, size, yp[0]);
334   post ();
335 
336 #if HAVE_NATIVE_mpn_submul_1c
337   pre ("mpn_submul_1c");
338   mpn_submul_1c (wp, xp, size, yp[0], CNST_LIMB(0));
339   post ();
340 #endif
341 
342   pre ("mpn_sub_n");
343   mpn_sub_n (wp, xp, yp, size);
344   post ();
345 
346 #if HAVE_NATIVE_mpn_sub_nc
347   pre ("mpn_sub_nc");
348   mpn_sub_nc (wp, xp, yp, size, CNST_LIMB(0));
349   post ();
350 #endif
351 
352 #if HAVE_NATIVE_mpn_sublsh1_n
353   pre ("mpn_sublsh1_n");
354   mpn_sublsh1_n (wp, xp, yp, size);
355   post ();
356 #endif
357 
358 #if HAVE_NATIVE_mpn_udiv_qrnnd
359   pre ("mpn_udiv_qrnnd");
360   mpn_udiv_qrnnd (&wp[0], CNST_LIMB(122), xp[0], CNST_LIMB(123));
361   post ();
362 #endif
363 
364 #if HAVE_NATIVE_mpn_udiv_qrnnd_r
365   pre ("mpn_udiv_qrnnd_r");
366   mpn_udiv_qrnnd (CNST_LIMB(122), xp[0], CNST_LIMB(123), &wp[0]);
367   post ();
368 #endif
369 
370 #if HAVE_NATIVE_mpn_umul_ppmm
371   pre ("mpn_umul_ppmm");
372   mpn_umul_ppmm (&wp[0], xp[0], yp[0]);
373   post ();
374 #endif
375 
376 #if HAVE_NATIVE_mpn_umul_ppmm_r
377   pre ("mpn_umul_ppmm_r");
378   mpn_umul_ppmm_r (&wp[0], xp[0], yp[0]);
379   post ();
380 #endif
381 
382 #if HAVE_NATIVE_mpn_xor_n
383   pre ("mpn_xor_n");
384   mpn_xor_n (wp, xp, yp, size);
385   post ();
386 #endif
387 
388 #if HAVE_NATIVE_mpn_xnor_n
389   pre ("mpn_xnor_n");
390   mpn_xnor_n (wp, xp, yp, size);
391   post ();
392 #endif
393 }
394 
395 
396 int
397 main (void)
398 {
399   tests_start ();
400 
401   check ();
402 
403   tests_end ();
404   exit (0);
405 }
406 
407 
408 #else /* ! WANT_PROFILING_INSTRUMENT */
409 
410 int
411 main (void)
412 {
413   exit (0);
414 }
415 
416 #endif
417