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