Annotation of OpenXM_contrib/gmp/tune/many.pl, Revision 1.1.1.1
1.1 ohara 1: #! /usr/bin/perl -w
2:
3: # Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
4: #
5: # This file is part of the GNU MP Library.
6: #
7: # The GNU MP Library is free software; you can redistribute it and/or modify
8: # it under the terms of the GNU Lesser General Public License as published by
9: # the Free Software Foundation; either version 2.1 of the License, or (at your
10: # option) any later version.
11: #
12: # The GNU MP Library is distributed in the hope that it will be useful, but
13: # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15: # License for more details.
16: #
17: # You should have received a copy of the GNU Lesser General Public License
18: # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19: # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: # MA 02111-1307, USA.
21:
22:
23: # Usage: cd $builddir/tune
24: # perl $srcdir/tune/many.pl [-t] <files/dirs>...
25: #
26: # Output: speed-many.c
27: # try-many.c
28: # Makefile.many
29: #
30: # Make alternate versions of various mpn routines available for measuring
31: # and testing.
32: #
33: # The $srcdir and $builddir in the invocation above just means the script
34: # lives in the tune source directory, but should be run in the tune build
35: # directory. When not using a separate object directory this just becomes
36: #
37: # cd tune
38: # perl many.pl [-t] <files/dirs>...
39: #
40: #
41: # SINGLE FILES
42: #
43: # Suppose $HOME/newcode/mul_1_experiment.asm is a new implementation of
44: # mpn_mul_1, then
45: #
46: # cd $builddir/tune
47: # perl $srcdir/tune/many.pl $HOME/newcode/mul_1_experiment.asm
48: #
49: # will produce rules and renaming so that a speed program incorporating it
50: # can be built,
51: #
52: # make -f Makefile.many speed-many
53: #
54: # then for example it can be compared to the standard mul_1,
55: #
56: # ./speed-many -s 1-30 mpn_mul_1 mpn_mul_1_experiment
57: #
58: # An expanded try program can be used to check correctness,
59: #
60: # make -f Makefile.many try-many
61: #
62: # and run
63: #
64: # ./try-many mpn_mul_1_experiment
65: #
66: # Files can be ".c", ".S" or ".asm". ".s" files can't be used because they
67: # don't get any preprocessing so there's no way to do renaming of their
68: # functions.
69: #
70: #
71: # WHOLE DIRECTORIES
72: #
73: # If a directory is given, then all files in it will be made available.
74: # For example,
75: #
76: # cd $builddir/tune
77: # perl $srcdir/tune/many.pl $HOME/newcode
78: #
79: # Each file should have a suffix, like "_experiment" above.
80: #
81: #
82: # MPN DIRECTORIES
83: #
84: # mpn directories from the GMP source tree can be included, and this is a
85: # convenient way to compare multiple implementations suiting different chips
86: # in a CPU family. For example the following would make all x86 routines
87: # available,
88: #
89: # cd $builddir/tune
90: # perl $srcdir/tune/many.pl `find $srcdir/mpn/x86 -type d`
91: #
92: # On a new x86 chip a comparison could then be made to see how existing code
93: # runs. For example,
94: #
95: # make -f Makefile.many speed-many
96: # ./speed-many -s 1-30 -c \
97: # mpn_add_n_x86 mpn_add_n_pentium mpn_add_n_k6 mpn_add_n_k7
98: #
99: # Files in "mpn" subdirectories don't need the "_experiment" style suffix
100: # described above, instead a suffix is constructed from the subdirectory.
101: # For example "mpn/x86/k7/mmx/mod_1.asm" will generate a function
102: # mpn_mod_1_k7_mmx. The rule is to take the last directory name after the
103: # "mpn", or the last two if there's three or more. (Check the generated
104: # speed-many.c if in doubt.)
105: #
106: #
107: # GENERIC C
108: #
109: # The mpn/generic directory can be included too, just like any processor
110: # specific directory. This is a good way to compare assembler and generic C
111: # implementations. For example,
112: #
113: # cd $builddir/tune
114: # perl $srcdir/tune/many.pl $srcdir/mpn/generic
115: #
116: # or if just a few routines are of interest, then for example
117: #
118: # cd $builddir/tune
119: # perl $srcdir/tune/many.pl \
120: # $srcdir/mpn/generic/lshift.c \
121: # $srcdir/mpn/generic/mod_1.c \
122: # $srcdir/mpn/generic/aorsmul_1.c
123: #
124: # giving mpn_lshift_generic etc.
125: #
126: #
127: # TESTS/DEVEL PROGRAMS
128: #
129: # Makefile.many also has rules to build the tests/devel programs with suitable
130: # renaming, and with some parameters for correctness or speed. This is less
131: # convenient than the speed and try programs, but provides an independent
132: # check. For example,
133: #
134: # make -f Makefile.many tests_mul_1_experimental
135: # ./tests_mul_1_experimental
136: #
137: # and for speed
138: #
139: # make -f Makefile.many tests_mul_1_experimental_sp
140: # ./tests_mul_1_experimental_sp
141: #
142: # Not all the programs support speed measuring, in which case only the
143: # correctness test will be useful.
144: #
145: # The parameters for repetitions and host clock speed are -D defines. Some
146: # defaults are provided at the end of Makefile.many, but probably these will
147: # want to be overridden. For example,
148: #
149: # rm tests_mul_1_experimental.o
150: # make -f Makefile.many \
151: # CFLAGS_TESTS="-DSIZE=50 -DTIMES=1000 -DRANDOM -DCLOCK=175000000" \
152: # tests_mul_1_experimental
153: # ./tests_mul_1_experimental
154: #
155: #
156: # OTHER NOTES
157: #
158: # The mappings of file names to functions, and the macros to then use for
159: # speed measuring etc are driven by @table below. The scheme isn't
160: # completely general, it's only got as many variations as have been needed
161: # so far.
162: #
163: # Some functions are only made available in speed-many, or others only in
164: # try-many. An @table entry speed=>none means no speed measuring is
165: # available, or try=>none no try program testing. These can be removed
166: # if/when the respective programs get the necessary support.
167: #
168: # If a file has "1c" or "nc" carry-in entrypoints, they're renamed and made
169: # available too. These are recognised from PROLOGUE or MULFUNC_PROLOGUE in
170: # .S and .asm files, or from a line starting with "mpn_foo_1c" in a .c file
171: # (possibly via a #define), and on that basis are entirely optional. This
172: # entrypoint matching is done for the standard entrypoints too, but it would
173: # be very unusual to have for instance a mul_1c without a mul_1.
174: #
175: # Some mpz files are recognized. For example an experimental copy of
176: # mpz/powm.c could be included as powm_new.c and would be called
177: # mpz_powm_new. So far only speed measuring is available for these.
178: #
179: # For the ".S" and ".asm" files, both PIC and non-PIC objects are built.
180: # The PIC functions have a "_pic" suffix, for example "mpn_mod_1_k7_mmx_pic".
181: # This can be ignored for routines that don't differ for PIC, or for CPUs
182: # where everything is PIC anyway.
183: #
184: # K&R compilers are supported via the same ansi2knr mechanism used by
185: # automake, though it's hard to believe anyone will have much interest in
186: # measuring a compiler so old that it doesn't even have an ANSI mode.
187: #
188: # The "-t" option can be used to print a trace of the files found and what's
189: # done with them. A great deal of obscure output is produced, but it can
190: # indicate where or why some files aren't being recognised etc. For
191: # example,
192: #
193: # cd $builddir/tune
194: # perl $srcdir/tune/many.pl -t $HOME/newcode/add_n_weird.asm
195: #
196: # In general, when including new code, all that's really necessary is that
197: # it will compile or assemble under the current configuration. It's fine if
198: # some code doesn't actually run due to bugs, or to needing a newer CPU or
199: # whatever, simply don't ask for the offending routines when invoking
200: # speed-many or try-many, or don't try to run them on sizes they don't yet
201: # support, or whatever.
202: #
203: #
204: # CPU SPECIFICS
205: #
206: # x86 - All the x86 code will assemble on any system, but code for newer
207: # chips might not run on older chips. Expect SIGILLs from new
208: # instructions on old chips.
209: #
210: # A few "new" instructions, like cmov for instance, are done as macros
211: # and will generate some equivalent plain i386 code when HAVE_HOST_CPU
212: # in config.m4 indicates an old CPU. It won't run fast, but it does
213: # make it possible to test correctness.
214: #
215: #
216: # INTERNALS
217: #
218: # The nonsense involving $ENV is some hooks used during development to add
219: # additional functions temporarily.
220: #
221: #
222: # FUTURE
223: #
224: # Maybe the C files should be compiled pic and non-pic too. Wait until
225: # there's a difference that might be of interest.
226: #
227: # Warn if a file provides no functions.
228: #
229: # Allow mpz and mpn files of the same name. Currently the mpn fib2_ui
230: # matching hides the mpz version of that. Will need to check the file
231: # contents to see which it is. Would be worth allowing an "mpz_" or "mpn_"
232: # prefix on the filenames to have working versions of both in one directory.
233: #
234: #
235: # LIMITATIONS
236: #
237: # Some of the command lines can become very long when a lot of files are
238: # included. If this is a problem on a given system the only suggestion is
239: # to run many.pl for just those that are actually wanted at a particular
240: # time.
241: #
242: # DOS 8.3 or SysV 14 char filesystems won't work, since the long filenames
243: # generated will almost certainly fail to be unique.
244:
245:
246: use strict;
247: use File::Basename;
248: use Getopt::Std;
249:
250: my %opt;
251: getopts('t', \%opt);
252:
253: my @DIRECTORIES = @ARGV;
254: if (defined $ENV{directories}) { push @DIRECTORIES, @{$ENV{directories}} }
255:
256:
257: # regexp - matched against the start of the filename. If a grouping "(...)"
258: # is present then only the first such part is used.
259: #
260: # mulfunc - filenames to be generated from a multi-function file.
261: #
262: # funs - functions provided by the file, defaulting to the filename with mpn
263: # (or mpX).
264: #
265: # mpX - prefix like "mpz", defaulting to "mpn".
266: #
267: # ret - return value type.
268: #
269: # args, args_<fun> - arguments for the given function. If an args_<fun> is
270: # set then it's used, otherwise plain args is used. "mp_limb_t
271: # carry" is appended for carry-in variants.
272: #
273: # try - try.c TYPE_ to use, defaulting to TYPE_fun with the function name
274: # in upper case. "C" is appended for carry-in variants. Can be
275: # 'none' for no try program entry.
276: #
277: # speed - SPEED_ROUTINE_ to use, handled like "try".
278: #
279: # speed_flags - SPEED_ROUTINE_ to use, handled like "try".
280:
281:
282: my @table =
283: (
284: {
285: 'regexp'=> 'add_n|sub_n',
286: 'ret' => 'mp_limb_t',
287: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
288: 'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
289: 'speed_flags'=> 'FLAG_R_OPTIONAL',
290: },
291: {
292: 'regexp'=> 'aors_n',
293: 'mulfunc'=> ['add_n','sub_n'],
294: 'ret' => 'mp_limb_t',
295: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
296: 'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
297: 'speed_flags'=> 'FLAG_R_OPTIONAL',
298: },
299:
300: {
301: 'regexp'=> 'addmul_1|submul_1',
302: 'ret' => 'mp_limb_t',
303: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
304: 'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
305: 'speed_flags'=> 'FLAG_R',
306: },
307: {
308: 'regexp'=> 'aorsmul_1',
309: 'mulfunc'=> ['addmul_1','submul_1'],
310: 'ret' => 'mp_limb_t',
311: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
312: 'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
313: 'speed_flags'=> 'FLAG_R',
314: },
315:
316: {
317: 'regexp'=> 'addsub_n',
318: 'ret' => 'mp_limb_t',
319: 'args' => 'mp_ptr sum, mp_ptr diff, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
320: 'speed_flags'=> 'FLAG_R_OPTIONAL',
321: },
322:
323: {
324: 'regexp'=> 'bdivmod',
325: 'ret' => 'mp_limb_t',
326: 'args' => 'mp_ptr qp, mp_ptr up, mp_size_t usize, mp_srcptr vp, mp_size_t vsize, unsigned long int d',
327: 'carrys'=> [''],
328: 'try' => 'none',
329: 'speed' => 'none',
330: },
331:
332: {
333: 'regexp'=> 'com_n|copyi|copyd',
334: 'ret' => 'void',
335: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
336: 'speed' => 'SPEED_ROUTINE_MPN_COPY',
337: },
338:
339: {
340: 'regexp'=> 'dive_1',
341: 'funs' => ['divexact_1'],
342: 'ret' => 'void',
343: 'args' => 'mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor',
344: 'speed_flags'=> 'FLAG_R',
345: },
346: {
347: 'regexp'=> 'diveby3',
348: 'funs' => ['divexact_by3c'],
349: 'ret' => 'mp_limb_t',
350: 'args' => 'mp_ptr dst, mp_srcptr src, mp_size_t size',
351: 'carrys'=> [''],
352: 'speed' => 'SPEED_ROUTINE_MPN_COPY',
353: },
354:
355: # mpn_preinv_divrem_1 is an optional extra entrypoint
356: {
357: 'regexp'=> 'divrem_1',
358: 'funs' => ['divrem_1', 'preinv_divrem_1'],
359: 'ret' => 'mp_limb_t',
360: 'args_divrem_1' => 'mp_ptr rp, mp_size_t xsize, mp_srcptr sp, mp_size_t size, mp_limb_t divisor',
361: 'args_preinv_divrem_1' => 'mp_ptr rp, mp_size_t xsize, mp_srcptr sp, mp_size_t size, mp_limb_t divisor, mp_limb_t inverse, unsigned shift',
362: 'speed_flags'=> 'FLAG_R',
363: 'speed_suffixes' => ['f'],
364: },
365: {
366: 'regexp'=> 'pre_divrem_1',
367: 'funs' => ['preinv_divrem_1'],
368: 'ret' => 'mp_limb_t',
369: 'args' => 'mp_ptr qp, mp_size_t qxn, mp_srcptr ap, mp_size_t asize, mp_limb_t divisor, mp_limb_t inverse, int shift',
370: 'speed_flags' => 'FLAG_R',
371: },
372:
373: {
374: 'regexp'=> 'divrem_2',
375: 'ret' => 'mp_limb_t',
376: 'args' => 'mp_ptr qp, mp_size_t qxn, mp_srcptr np, mp_size_t nsize, mp_srcptr dp',
377: 'try' => 'none',
378: },
379:
380: {
381: 'regexp'=> 'sb_divrem_mn',
382: 'ret' => 'mp_limb_t',
383: 'args' => 'mp_ptr qp, mp_ptr np, mp_size_t nsize, mp_srcptr dp, mp_size_t dsize',
384: 'speed' => 'SPEED_ROUTINE_MPN_DC_DIVREM_SB',
385: 'try-minsize' => 3,
386: },
387: {
388: 'regexp'=> 'tdiv_qr',
389: 'ret' => 'void',
390: 'args' => 'mp_ptr qp, mp_size_t qxn, mp_ptr np, mp_size_t nsize, mp_srcptr dp, mp_size_t dsize',
391: 'speed' => 'none',
392: },
393:
394: {
395: 'regexp'=> 'get_str',
396: 'ret' => 'size_t',
397: 'args' => 'unsigned char *str, int base, mp_ptr mptr, mp_size_t msize',
398: 'speed_flags' => 'FLAG_R_OPTIONAL',
399: 'try' => 'none',
400: },
401: {
402: 'regexp'=> 'set_str',
403: 'ret' => 'mp_size_t',
404: 'args' => 'mp_ptr xp, const unsigned char *str, size_t str_len, int base',
405: 'speed_flags' => 'FLAG_R_OPTIONAL',
406: 'try' => 'none',
407: },
408:
409: {
410: 'regexp'=> 'fac_ui',
411: 'mpX' => 'mpz',
412: 'ret' => 'void',
413: 'args' => 'mpz_ptr r, unsigned long n',
414: 'speed_flags' => 'FLAG_NODATA',
415: 'try' => 'none',
416: },
417:
418: {
419: 'regexp'=> 'fib2_ui',
420: 'ret' => 'void',
421: 'args' => 'mp_ptr fp, mp_ptr f1p, unsigned long n',
422: 'rename'=> ['__gmp_fib_table'],
423: 'speed_flags' => 'FLAG_NODATA',
424: 'try' => 'none',
425: },
426: {
427: 'regexp'=> 'fib_ui',
428: 'mpX' => 'mpz',
429: 'ret' => 'void',
430: 'args' => 'mpz_ptr fn, unsigned long n',
431: 'speed_flags' => 'FLAG_NODATA',
432: 'try' => 'none',
433: },
434: {
435: 'regexp'=> 'fib2_ui',
436: 'mpX' => 'mpz',
437: 'ret' => 'void',
438: 'args' => 'mpz_ptr fn, mpz_ptr fnsub1, unsigned long n',
439: 'speed_flags' => 'FLAG_NODATA',
440: 'try' => 'none',
441: },
442:
443: {
444: 'regexp'=> 'lucnum_ui',
445: 'mpX' => 'mpz',
446: 'ret' => 'void',
447: 'args' => 'mpz_ptr ln, unsigned long n',
448: 'speed_flags' => 'FLAG_NODATA',
449: 'try' => 'none',
450: },
451: {
452: 'regexp'=> 'lucnum2_ui',
453: 'mpX' => 'mpz',
454: 'ret' => 'void',
455: 'args' => 'mpz_ptr ln, mpz_ptr lnsub1, unsigned long n',
456: 'speed_flags' => 'FLAG_NODATA',
457: 'try' => 'none',
458: },
459:
460: {
461: 'regexp'=> 'gcd_1',
462: 'ret' => 'mp_limb_t',
463: 'args' => 'mp_ptr xp, mp_size_t xsize, mp_limb_t y',
464: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
465: 'speed_flags'=> 'FLAG_R_OPTIONAL',
466: 'speed_suffixes' => ['N'],
467: },
468: {
469: 'regexp'=> '(gcd)(?!(_1|ext|_finda))',
470: 'ret' => 'mp_size_t',
471: 'args' => 'mp_ptr gp, mp_ptr up, mp_size_t usize, mp_ptr vp, mp_size_t vsize',
472: },
473: {
474: 'regexp'=> 'gcd_finda',
475: 'ret' => 'mp_limb_t',
476: 'args' => 'mp_srcptr cp',
477: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
478: },
479:
480:
481: {
482: 'regexp'=> 'jacobi',
483: 'funs' => ['jacobi', 'legendre', 'kronecker'],
484: 'mpX' => 'mpz',
485: 'ret' => 'int',
486: 'args' => 'mpz_srcptr a, mpz_srcptr b',
487: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
488: 'try-legendre' => 'TYPE_MPZ_JACOBI',
489: },
490: {
491: 'regexp'=> 'jacbase',
492: 'funs' => ['jacobi_base'],
493: 'ret' => 'mp_limb_t',
494: 'args' => 'mp_limb_t a, mp_limb_t b, int bit1',
495: 'attrib'=> 'ATTRIBUTE_CONST',
496: 'speed' => 'SPEED_ROUTINE_MPN_JACBASE',
497: 'try' => 'none',
498: },
499:
500: {
501: 'regexp'=> 'logops_n',
502: 'mulfunc'=> ['and_n','andn_n','nand_n','ior_n','iorn_n','nior_n','xor_n','xnor_n'],
503: 'ret' => 'void',
504: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
505: 'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
506: },
507:
508: {
509: 'regexp'=> '[lr]shift',
510: 'ret' => 'mp_limb_t',
511: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, unsigned shift',
512: 'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
513: 'speed_flags'=> 'FLAG_R',
514: },
515:
516: # mpn_preinv_mod_1 is an optional extra entrypoint
517: {
518: 'regexp'=> '(mod_1)(?!_rs)',
519: 'funs' => ['mod_1','preinv_mod_1'],
520: 'ret' => 'mp_limb_t',
521: 'args_mod_1' => 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor',
522: 'args_preinv_mod_1'=> 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor, mp_limb_t inverse',
523: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
524: 'speed_flags'=> 'FLAG_R',
525: },
526: {
527: 'regexp'=> 'pre_mod_1',
528: 'funs' => ['preinv_mod_1'],
529: 'ret' => 'mp_limb_t',
530: 'args' => 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor, mp_limb_t inverse',
531: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
532: 'speed_flags'=> 'FLAG_R',
533: },
534: {
535: 'regexp'=> 'mod_34lsub1',
536: 'ret' => 'mp_limb_t',
537: 'args' => 'mp_srcptr src, mp_size_t len',
538: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
539: },
540: {
541: 'regexp'=> 'invert_limb',
542: 'ret' => 'mp_limb_t',
543: 'args' => 'mp_limb_t divisor',
544: 'attrib'=> 'ATTRIBUTE_CONST',
545: 'speed_flags'=> 'FLAG_R_OPTIONAL',
546: 'try' => 'none',
547: },
548:
549: {
550: # not for use with hppa reversed argument versions of mpn_umul_ppmm
551: 'regexp'=> 'udiv',
552: 'funs' => ['udiv_qrnnd'],
553: 'ret' => 'mp_limb_t',
554: 'args' => 'mp_limb_t *remptr, mp_limb_t n1, mp_limb_t n0, mp_limb_t d',
555: 'speed' => 'none',
556: 'try-minsize' => 2,
557: },
558:
559: {
560: 'regexp'=> 'mode1o',
561: 'funs' => ['modexact_1_odd'],
562: 'ret' => 'mp_limb_t',
563: 'args' => 'mp_srcptr src, mp_size_t size, mp_limb_t divisor',
564: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
565: 'speed_flags'=> 'FLAG_R',
566: },
567: {
568: 'regexp'=> 'modlinv',
569: 'funs' => ['modlimb_invert'],
570: 'ret' => 'mp_limb_t',
571: 'args' => 'mp_limb_t v',
572: 'attrib'=> 'ATTRIBUTE_CONST',
573: 'carrys'=> [''],
574: 'try' => 'none',
575: },
576:
577: {
578: 'regexp'=> 'mul_1',
579: 'ret' => 'mp_limb_t',
580: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
581: 'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
582: 'speed_flags'=> 'FLAG_R',
583: },
584: {
585: 'regexp'=> 'mul_2',
586: 'ret' => 'mp_limb_t',
587: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr mult',
588: },
589:
590: {
591: 'regexp'=> 'mul_basecase',
592: 'ret' => 'void',
593: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t xsize, mp_srcptr yp, mp_size_t ysize',
594: 'speed_flags' => 'FLAG_R_OPTIONAL | FLAG_RSIZE',
595: },
596: {
597: 'regexp'=> '(mul_n)[_.]',
598: 'ret' => 'void',
599: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
600: 'rename'=> ['kara_mul_n','kara_sqr_n','toom3_mul_n','toom3_sqr_n'],
601: },
602: {
603: # not for use with hppa reversed argument versions of mpn_umul_ppmm
604: 'regexp'=> 'umul',
605: 'funs' => ['umul_ppmm'],
606: 'ret' => 'mp_limb_t',
607: 'args' => 'mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2',
608: 'speed' => 'none',
609: 'try-minsize' => 3,
610: },
611:
612:
613: {
614: 'regexp'=> 'popham',
615: 'mulfunc'=> ['popcount','hamdist'],
616: 'ret' => 'unsigned long',
617: 'args_popcount'=> 'mp_srcptr xp, mp_size_t size',
618: 'args_hamdist' => 'mp_srcptr xp, mp_srcptr yp, mp_size_t size',
619: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
620: },
621: {
622: 'regexp'=> 'popcount',
623: 'ret' => 'unsigned long',
624: 'args' => 'mp_srcptr xp, mp_size_t size',
625: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
626: },
627: {
628: 'regexp'=> 'hamdist',
629: 'ret' => 'unsigned long',
630: 'args' => 'mp_srcptr xp, mp_srcptr yp, mp_size_t size',
631: 'attrib'=> '__GMP_ATTRIBUTE_PURE',
632: # extra renaming to support sharing a data table with mpn_popcount
633: 'rename'=> ['popcount'],
634: },
635:
636: {
637: 'regexp'=> 'sqr_basecase',
638: 'ret' => 'void',
639: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
640: 'speed' => 'SPEED_ROUTINE_MPN_SQR',
641: 'try' => 'TYPE_SQR',
642: },
643: {
644: 'regexp'=> 'sqr_diagonal',
645: 'ret' => 'void',
646: 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
647: 'try' => 'none',
648: },
649:
650: {
651: 'regexp'=> 'sqrtrem',
652: 'ret' => 'mp_size_t',
653: 'args' => 'mp_ptr root, mp_ptr rem, mp_srcptr src, mp_size_t size',
654: 'try' => 'none',
655: },
656:
657: {
658: 'regexp'=> 'cntlz',
659: 'funs' => ['count_leading_zeros'],
660: 'ret' => 'unsigned',
661: 'args' => 'mp_limb_t',
662: 'attrib'=> 'ATTRIBUTE_CONST',
663: 'macro-before' => "#undef COUNT_LEADING_ZEROS_0",
664: 'macro-speed' =>
665: '#ifdef COUNT_LEADING_ZEROS_0
666: #define COUNT_LEADING_ZEROS_0_ALLOWED 1
667: #else
668: #define COUNT_LEADING_ZEROS_0_ALLOWED 0
669: #endif
670: SPEED_ROUTINE_COUNT_ZEROS_A (1, COUNT_LEADING_ZEROS_0_ALLOWED);
671: $fun (c, n);
672: SPEED_ROUTINE_COUNT_ZEROS_B ()',
673: 'speed_flags'=> 'FLAG_R_OPTIONAL',
674: 'try' => 'none',
675: },
676: {
677: 'regexp'=> 'cnttz',
678: 'funs' => ['count_trailing_zeros'],
679: 'ret' => 'unsigned',
680: 'args' => 'mp_limb_t',
681: 'attrib'=> 'ATTRIBUTE_CONST',
682: 'macro-speed' => '
683: SPEED_ROUTINE_COUNT_ZEROS_A (0, 0);
684: $fun (c, n);
685: SPEED_ROUTINE_COUNT_ZEROS_B ()',
686: 'speed_flags' => 'FLAG_R_OPTIONAL',
687: 'try' => 'none',
688: },
689:
690: {
691: 'regexp'=> 'zero',
692: 'ret' => 'void',
693: 'args' => 'mp_ptr ptr, mp_size_t size',
694: },
695:
696: {
697: 'regexp'=> '(powm)(?!_ui)',
698: 'mpX' => 'mpz',
699: 'ret' => 'void',
700: 'args' => 'mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m',
701: 'try' => 'none',
702: },
703: {
704: 'regexp'=> 'powm_ui',
705: 'mpX' => 'mpz',
706: 'ret' => 'void',
707: 'args' => 'mpz_ptr r, mpz_srcptr b, unsigned long e, mpz_srcptr m',
708: 'try' => 'none',
709: },
710:
711: # special for use during development
712: {
713: 'regexp'=> 'back',
714: 'funs' => ['back_to_back'],
715: 'ret' => 'void',
716: 'args' => 'void',
717: 'pic' => 'no',
718: 'try' => 'none',
719: 'speed_flags'=> 'FLAG_NODATA',
720: },
721: );
722:
723: if (defined $ENV{table2}) {
724: my @newtable = @{$ENV{table2}};
725: push @newtable, @table;
726: @table = @newtable;
727: }
728:
729:
730: my %pictable =
731: (
732: 'yes' => {
733: 'suffix' => '_pic',
734: 'asmflags'=> '$(ASMFLAGS_PIC)',
735: 'cflags' => '$(CFLAGS_PIC)',
736: },
737: 'no' => {
738: 'suffix' => '',
739: 'asmflags'=> '',
740: 'cflags' => '',
741: },
742: );
743:
744:
745: my $builddir = $ENV{builddir};
746: $builddir = "." if (! defined $builddir);
747:
748: my $top_builddir = "${builddir}/..";
749:
750:
751: open(MAKEFILE, "<${builddir}/Makefile")
752: or die "Cannot open Makefile: $!\nIs this a tune build directory?";
753: my ($srcdir, $top_srcdir);
754: while (<MAKEFILE>) {
755: if (/^srcdir = (.*)/) { $srcdir = $1; }
756: if (/^top_srcdir = (.*)/) { $top_srcdir = $1; }
757: }
758: die "Cannot find \$srcdir in Makefile\n" if (! defined $srcdir);
759: die "Cannot find \$top_srcdir in Makefile\n" if (! defined $top_srcdir);
760: print "srcdir $srcdir\n" if $opt{'t'};
761: print "top_srcdir $top_srcdir\n" if $opt{'t'};
762: close(MAKEFILE);
763:
764:
765: open(SPEED, ">speed-many.c") or die;
766: print SPEED
767: "/* speed-many.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */
768:
769: ";
770: my $SPEED_EXTRA_ROUTINES = "#define SPEED_EXTRA_ROUTINES \\\n";
771: my $SPEED_EXTRA_PROTOS = "#define SPEED_EXTRA_PROTOS \\\n";
772: my $SPEED_CODE = "";
773:
774: open(TRY, ">try-many.c") or die;
775: print TRY
776: "/* try-many.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */\n" .
777: "\n";
778: my $TRY_EXTRA_ROUTINES = "#define EXTRA_ROUTINES \\\n";
779: my $TRY_EXTRA_PROTOS = "#define EXTRA_PROTOS \\\n";
780:
781: open(FD,"<${top_builddir}/libtool") or die "Cannot open \"${top_builddir}/libtool\": $!\n";
782: my $pic_flag;
783: while (<FD>) {
784: if (/^pic_flag="?([^"]*)"?$/) {
785: $pic_flag=$1;
786: last;
787: }
788: }
789: close FD;
790: if (! defined $pic_flag) {
791: die "Cannot find pic_flag in ${top_builddir}/libtool";
792: }
793:
794: my $CFLAGS_PIC = $pic_flag;
795:
796: my $ASMFLAGS_PIC = "";
797: foreach (split /[ \t]/, $pic_flag) {
798: if (/^-D/) {
799: $ASMFLAGS_PIC .= " " . $_;
800: }
801: }
802:
803: open(MAKEFILE, ">Makefile.many") or die;
804: print MAKEFILE
805: "# Makefile.many generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST\n" .
806: "\n" .
807: "all: speed-many try-many\n" .
808: "\n" .
809: "#--------- begin included copy of basic Makefile ----------\n" .
810: "\n";
811: open(FD,"<${builddir}/Makefile") or die "Cannot open \"${builddir}/Makefile\": $!\n";
812: print MAKEFILE <FD>;
813: close FD;
814: print MAKEFILE
815: "\n" .
816: "#--------- end included copy of basic Makefile ----------\n" .
817: "\n" .
818: "CFLAGS_PIC = $CFLAGS_PIC\n" .
819: "ASMFLAGS_PIC = $ASMFLAGS_PIC\n" .
820: "\n";
821:
822: my $CLEAN="";
823: my $MANY_OBJS="";
824:
825:
826: sub print_ansi2knr {
827: my ($base,$file,$includes) = @_;
828: if (! defined $file) { $file = "$base.c"; }
829: if (! defined $includes) { $includes = ""; }
830:
831: print MAKEFILE <<EOF;
832: ${base}_.c: $file \$(ANSI2KNR)
833: \$(CPP) \$(DEFS) \$(INCLUDES) $includes \$(AM_CPPFLAGS) \$(CPPFLAGS) $file | sed 's/^# \([0-9]\)/#line \\1/' | \$(ANSI2KNR) >${base}_.c
834:
835: EOF
836: }
837:
838:
839: # Spawning a glob is a touch slow when there's lots of files.
840: my @files = ();
841: foreach my $dir (@DIRECTORIES) {
842: print "dir $dir\n" if $opt{'t'};
843: if (-f $dir) {
844: push @files,$dir;
845: } else {
846: if (! opendir DD,$dir) {
847: print "Cannot open $dir: $!\n";
848: } else {
849: push @files, map {$_="$dir/$_"} grep /\.(c|asm|S|h)$/, readdir DD;
850: closedir DD;
851: }
852: }
853: }
854: @files = sort @files;
855: print "@files ",join(" ",@files),"\n" if $opt{'t'};
856:
857: my $count_files = 0;
858: my $count_functions = 0;
859: my %seen_obj;
860: my %seen_file;
861:
862: foreach my $file_full (@files) {
863: if (! -f $file_full) {
864: print "Not a file: $file_full\n";
865: next;
866: }
867: if (defined $seen_file{$file_full}) {
868: print "Skipping duplicate file: $file_full\n";
869: next;
870: }
871: $seen_file{$file_full} = 1;
872:
873: my ($FILE,$path,$lang) = fileparse($file_full,"\.[a-zA-Z]+");
874: $path =~ s/\/$//;
875: print "file $FILE path $path lang $lang\n" if $opt{'t'};
876:
877: my @pic_choices;
878: if ($lang eq '.asm') { @pic_choices=('no','yes'); }
879: elsif ($lang eq '.c') { @pic_choices=('no'); }
880: elsif ($lang eq '.S') { @pic_choices=('no','yes'); }
881: elsif ($lang eq '.h') { @pic_choices=('no'); }
882: else { next };
883:
884: my ($t, $file_match);
885: foreach my $p (@table) {
886: # print " ",$p->{'regexp'},"\n" if $opt{'t'};
887: if ($FILE =~ "^($p->{'regexp'})") {
888: $t = $p;
889: $file_match = $1;
890: $file_match = $2 if defined $2;
891: last;
892: }
893: }
894: next if ! defined $t;
895: print "match $t->{'regexp'} $FILE ($file_full)\n" if $opt{'t'};
896:
897: if (! open FD,"<$file_full") { print "Can't open $file_full: $!\n"; next }
898: my @file_contents = <FD>;
899: close FD;
900:
901: my $objs;
902: if (defined $t->{'mulfunc'}) { $objs = $t->{'mulfunc'}; }
903: else { $objs = [$file_match]; }
904: print "objs @$objs\n" if $opt{'t'};
905:
906: my $ret = $t->{'ret'};
907: if (! defined $ret && $lang eq '.h') { $ret = ''; }
908: if (! defined $ret) { die "$FILE return type not defined\n" };
909: print "ret $ret\n" if $opt{'t'};
910:
911: my $mpX = $t->{'mpX'};
912: if (! defined $mpX) { $mpX = ($lang eq '.h' ? '' : 'mpn'); }
913: $mpX = "${mpX}_" if $mpX ne '';
914: print "mpX $mpX\n" if $opt{'t'};
915:
916: my $carrys;
917: if (defined $t->{'carrys'}) { $carrys = $t->{'carrys'}; }
918: else { $carrys = ['','c']; }
919: print "carrys $carrys @$carrys\n" if $opt{'t'};
920:
921: # some restriction functions are implemented, but they're not very useful
922: my $restriction='';
923:
924: my $suffix;
925: if ($FILE =~ ("${file_match}_(.+)")) {
926: $suffix = $1;
927: } elsif ($path =~ /\/mp[zn]\/(.*)$/) {
928: # derive the suffix from the path
929: $suffix = $1;
930: $suffix =~ s/\//_/g;
931: # use last directory name, or if there's 3 or more then the last two
932: if ($suffix =~ /([^_]*_)+([^_]+_[^_]+)$/) {
933: $suffix = $2;
934: } elsif ($suffix =~ /([^_]*_)*([^_]+)$/) {
935: $suffix = $2;
936: }
937: } else {
938: die "Can't determine suffix for: $file_full (path $path)\n";
939: }
940: print "suffix $suffix\n" if $opt{'t'};
941:
942: $count_files++;
943:
944: foreach my $obj (@{$objs}) {
945: print "obj $obj\n" if $opt{'t'};
946:
947: my $obj_with_suffix = "${obj}_$suffix";
948: if (defined $seen_obj{$obj_with_suffix}) {
949: print "Skipping duplicate object: $obj_with_suffix\n";
950: print " first from: $seen_obj{$obj_with_suffix}\n";
951: print " now from: $file_full\n";
952: next;
953: }
954: $seen_obj{$obj_with_suffix} = $file_full;
955:
956: my $funs = $t->{'funs'};
957: $funs = [$obj] if ! defined $funs;
958: print "funs @$funs\n" if $opt{'t'};
959:
960: if (defined $t->{'pic'}) { @pic_choices = ('no'); }
961:
962: foreach my $pic (map {$pictable{$_}} @pic_choices) {
963: print "pic $pic->{'suffix'}\n" if $opt{'t'};
964:
965: my $objbase = "${obj}_$suffix$pic->{'suffix'}";
966: print "objbase $objbase\n" if $opt{'t'};
967:
968: if ($path !~ "." && -f "${objbase}.c") {
969: die "Already have ${objbase}.c";
970: }
971:
972: my $tmp_file = "tmp-$objbase.c";
973:
974: my $renaming;
975: foreach my $fun (@{$funs}) {
976: if ($mpX eq 'mpn_' && $lang eq '.c') {
977: $renaming .= "\t\t-DHAVE_NATIVE_mpn_$fun=1 \\\n";
978: }
979:
980: # The carry-in variant is with a "c" appended, unless there's a "_1"
981: # somewhere, eg. "modexact_1_odd", in which case that becomes "_1c".
982: my $fun_carry = $fun;
983: if (! ($fun_carry =~ s/_1/_1c/)) { $fun_carry = "${fun}c"; }
984:
985: $renaming .=
986: "\t\t-D__g$mpX$fun=$mpX${fun}_$suffix$pic->{'suffix'} \\\n" .
987: "\t\t-D__g$mpX$fun_carry=$mpX${fun_carry}_$suffix$pic->{'suffix'} \\\n";
988: }
989: foreach my $r (@{$t->{'rename'}}) {
990: if ($r =~ /^__gmp/) {
991: $renaming .= "\\\n" .
992: "\t\t-D$r=${r}_$suffix$pic->{'suffix'}";
993: } else {
994: $renaming .= "\\\n" .
995: "\t\t-D__g$mpX$r=$mpX${r}_$suffix$pic->{'suffix'}";
996: }
997: }
998: print "renaming $renaming\n" if $opt{'t'};
999:
1000: print MAKEFILE "\n";
1001: if ($lang eq '.asm') {
1002: print MAKEFILE
1003: "$objbase.o: $file_full \$(ASM_HEADERS)\n" .
1004: " \$(M4) \$(M4FLAGS) -DOPERATION_$obj $pic->{'asmflags'} \\\n" .
1005: "$renaming" .
1006: " $file_full >tmp-$objbase.s\n" .
1007: " \$(CCAS) \$(COMPILE_FLAGS) $pic->{'cflags'} tmp-$objbase.s -o $objbase.o\n" .
1008: " \$(RM_TMP) tmp-$objbase.s\n";
1009: $MANY_OBJS .= " $objbase.o";
1010:
1011: } elsif ($lang eq '.c') {
1012: print MAKEFILE
1013: "$objbase.o: $file_full\n" .
1014: " \$(COMPILE) -DOPERATION_$obj $pic->{'cflags'} \\\n" .
1015: "$renaming" .
1016: " -c $file_full -o $objbase.o\n";
1017: print_ansi2knr($objbase,
1018: $file_full,
1019: " -DOPERATION_$obj\\\n$renaming\t\t");
1020: $MANY_OBJS .= " $objbase\$U.o";
1021:
1022: } elsif ($lang eq '.S') {
1023: print MAKEFILE
1024: "$objbase.o: $file_full\n" .
1025: " \$(COMPILE) -g $pic->{'asmflags'} \\\n" .
1026: "$renaming" .
1027: " -c $file_full -o $objbase.o\n";
1028: $MANY_OBJS .= " $objbase.o";
1029:
1030: } elsif ($lang eq '.h') {
1031: print MAKEFILE
1032: "$objbase.o: tmp-$objbase.c $file_full\n" .
1033: " \$(COMPILE) -DOPERATION_$obj $pic->{'cflags'} \\\n" .
1034: "$renaming" .
1035: " -c tmp-$objbase.c -o $objbase.o\n";
1036: print_ansi2knr($objbase,
1037: "tmp-$objbase.c",
1038: " -DOPERATION_$obj\\\n$renaming\t\t");
1039: $MANY_OBJS .= " $objbase\$U.o";
1040:
1041: $CLEAN .= " tmp-$objbase.c";
1042: open(TMP_C,">tmp-$objbase.c")
1043: or die "Can't create tmp-$objbase.c: $!\n";
1044: print TMP_C
1045: "/* tmp-$objbase.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */
1046:
1047: #include \"gmp.h\"
1048: #include \"gmp-impl.h\"
1049: #include \"longlong.h\"
1050: #include \"speed.h\"
1051:
1052: ";
1053: }
1054:
1055: my $tests_program = "$top_srcdir/tests/devel/$obj.c";
1056: if (-f $tests_program) {
1057: $tests_program = "\$(top_srcdir)/tests/devel/$obj.c";
1058: print_ansi2knr("tests_${objbase}",
1059: $tests_program,
1060: "\\\n$renaming\t\t\$(CFLAGS_TESTS_SP)");
1061: print_ansi2knr("tests_${objbase}_sp",
1062: $tests_program,
1063: "\\\n$renaming\t\t\$(CFLAGS_TESTS_SP)");
1064:
1065: print MAKEFILE <<EOF;
1066: tests_$objbase.o: $tests_program
1067: \$(COMPILE) \$(CFLAGS_TESTS) \\
1068: $renaming -c $tests_program -o tests_$objbase.o
1069:
1070: tests_$objbase: $objbase\$U.o tests_$objbase\$U.o ../libgmp.la
1071: \$(LINK) tests_$objbase\$U.o $objbase\$U.o ../libgmp.la -o tests_$objbase
1072:
1073: tests_${objbase}_sp.o: $tests_program
1074: \$(COMPILE) \$(CFLAGS_TESTS_SP) \\
1075: $renaming -c $tests_program -o tests_${objbase}_sp.o
1076:
1077: tests_${objbase}_sp: $objbase\$U.o tests_${objbase}_sp\$U.o ../libgmp.la
1078: \$(LINK) tests_${objbase}_sp\$U.o $objbase\$U.o ../libgmp.la -o tests_${objbase}_sp
1079:
1080: EOF
1081: $CLEAN .= " tests_$objbase tests_${objbase}_sp";
1082: }
1083:
1084: foreach my $fun (@{$funs}) {
1085: print "fun $fun\n" if $opt{'t'};
1086:
1087: if ($lang eq '.h') {
1088: my $macro_before = $t->{'macro_before'};
1089: $macro_before = "" if ! defined $macro_before;
1090: print TMP_C
1091: "$macro_before
1092: #undef $fun
1093: #include \"$file_full\"
1094:
1095: ";
1096: }
1097:
1098: my $args = $t->{"args_$fun"};
1099: if (! defined $args) { $args = $t->{'args'}; }
1100: if (! defined $args) { die "Need args for $fun\n"; }
1101: print "args $args\n" if $opt{'t'};
1102:
1103: foreach my $carry (@$carrys) {
1104: print "carry $carry\n" if $opt{'t'};
1105:
1106: my $fun_carry = $fun;
1107: if (! ($fun_carry =~ s/_1/_1$carry/)) { $fun_carry = "$fun$carry"; }
1108: print "fun_carry $fun_carry\n" if $opt{'t'};
1109:
1110: if ($lang =~ /\.(asm|S)/
1111: && ! grep(m"PROLOGUE\((.* )?$mpX$fun_carry[ )]",@file_contents)) {
1112: print "no PROLOGUE $mpX$fun_carry\n" if $opt{'t'};
1113: next;
1114: }
1115: if ($lang eq '.c'
1116: && ! grep(m"^(#define FUNCTION\s+)?$mpX$fun_carry\W", @file_contents)) {
1117: print "no mention of $mpX$fun_carry\n" if $opt{'t'};
1118: next;
1119: }
1120: if ($lang eq '.h'
1121: && ! grep(m"^#define $fun_carry\W", @file_contents)) {
1122: print "no mention of #define $fun_carry\n" if $opt{'t'};
1123: next;
1124: }
1125:
1126: $count_functions++;
1127:
1128: my $carryarg;
1129: if (defined $t->{'carryarg'}) { $carryarg = $t->{'carryarg'}; }
1130: if ($carry eq '') { $carryarg = ''; }
1131: else { $carryarg = ', mp_limb_t carry'; }
1132: print "carryarg $carryarg\n" if $opt{'t'};
1133:
1134: my $funfull="$mpX${fun_carry}_$suffix$pic->{'suffix'}";
1135: print "funfull $funfull\n" if $opt{'t'};
1136:
1137: if ($lang ne '.h') {
1138: my $attrib = $t->{'attrib'};
1139: if (defined $attrib) { $attrib = " $attrib"; }
1140: else { $attrib = ''; }
1141:
1142: my $proto = "$t->{'ret'} $funfull _PROTO (($args$carryarg))$attrib; \\\n";
1143: $SPEED_EXTRA_PROTOS .= $proto;
1144: $TRY_EXTRA_PROTOS .= $proto;
1145: }
1146:
1147: my $try_type = $t->{"try-$fun"};
1148: $try_type = $t->{'try'} if ! defined $try_type;
1149: if (! defined $try_type) {
1150: if ($mpX eq 'mpn_') {
1151: $try_type = "TYPE_\U$fun_carry";
1152: } else {
1153: $try_type = "TYPE_\U$mpX\U$fun_carry";
1154: }
1155: }
1156: print "try_type $try_type\n" if $opt{'t'};
1157:
1158: my $try_minsize = $t->{'try-minsize'};
1159: if (defined $try_minsize) {
1160: $try_minsize = ", " . $try_minsize;
1161: } else {
1162: $try_minsize = "";
1163: }
1164: print "try_minsize $try_minsize\n" if $opt{'t'};
1165:
1166: if ($try_type ne 'none') {
1167: $TRY_EXTRA_ROUTINES .=
1168: " { TRY($mpX${fun_carry}_$suffix$pic->{'suffix'}), $try_type$try_minsize }, \\\n";
1169: }
1170:
1171: my $speed_flags = $t->{'speed_flags'};
1172: $speed_flags = '0' if ! defined $speed_flags;
1173: print "speed_flags $speed_flags\n" if $opt{'t'};
1174:
1175: my $speed_routine = $t->{'speed'};
1176: $speed_routine = "SPEED_ROUTINE_\U$mpX\U$fun"
1177: if !defined $speed_routine;
1178: if (! ($speed_routine =~ s/_1/_1\U$carry/)) {
1179: $speed_routine = "$speed_routine\U$carry";
1180: }
1181: print "speed_routine $speed_routine\n" if $opt{'t'};
1182:
1183: my @speed_suffixes = ();
1184: push (@speed_suffixes, '') if $speed_routine ne 'none';
1185: push (@speed_suffixes, @{$t->{'speed_suffixes'}})
1186: if defined $t->{'speed_suffixes'};
1187:
1188: my $macro_speed = $t->{'macro-speed'};
1189: $macro_speed = "$speed_routine ($fun_carry)" if ! defined $macro_speed;
1190: $macro_speed =~ s/\$fun/$fun_carry/g;
1191:
1192: foreach my $S (@speed_suffixes) {
1193: my $Sfunfull="$mpX${fun_carry}${S}_$suffix$pic->{'suffix'}";
1194:
1195: $SPEED_EXTRA_PROTOS .=
1196: "double speed_$Sfunfull _PROTO ((struct speed_params *s)); \\\n";
1197: $SPEED_EXTRA_ROUTINES .=
1198: " { \"$Sfunfull\", speed_$Sfunfull, $speed_flags }, \\\n";
1199: if ($lang eq '.h') {
1200: print TMP_C
1201: "double
1202: speed_$Sfunfull (struct speed_params *s)
1203: {
1204: $macro_speed
1205: }
1206:
1207: ";
1208: } else {
1209: $SPEED_CODE .=
1210: "double\n" .
1211: "speed_$Sfunfull (struct speed_params *s)\n" .
1212: "{\n" .
1213: "$restriction" .
1214: " $speed_routine\U$S\E ($funfull)\n" .
1215: "}\n";
1216: }
1217: }
1218: }
1219: }
1220: }
1221: }
1222: }
1223:
1224:
1225: print SPEED $SPEED_EXTRA_PROTOS . "\n";
1226: print SPEED $SPEED_EXTRA_ROUTINES . "\n";
1227: if (defined $ENV{speedinc}) { print SPEED $ENV{speedinc} . "\n"; }
1228: print SPEED
1229: "#include \"speed.c\"\n" .
1230: "\n";
1231: print SPEED $SPEED_CODE;
1232:
1233: print TRY $TRY_EXTRA_ROUTINES . "\n";
1234: print TRY $TRY_EXTRA_PROTOS . "\n";
1235: my $tryinc = "";
1236: if (defined $ENV{tryinc}) {
1237: $tryinc = $ENV{tryinc};
1238: print TRY "#include \"$tryinc\"\n";
1239: }
1240: print "tryinc $tryinc\n" if $opt{'t'};
1241: print TRY
1242: "#include \"try.c\"\n" .
1243: "\n";
1244:
1245: my $extra_libraries = "";
1246: if (defined $ENV{extra_libraries}) { $extra_libraries = $ENV{extra_libraries};}
1247:
1248: my $trydeps = "";
1249: if (defined $ENV{trydeps}) { $trydeps = $ENV{trydeps}; }
1250: $trydeps .= " $tryinc";
1251: print "trydeps $trydeps\n" if $opt{'t'};
1252:
1253: print MAKEFILE <<EOF;
1254:
1255: MANY_OBJS = $MANY_OBJS
1256: MANY_CLEAN = \$(MANY_OBJS) \\
1257: speed-many.c speed-many\$U.o speed-many\$(EXEEXT) \\
1258: try-many.c try-many\$U.o try-many \\
1259: $CLEAN
1260: MANY_DISTCLEAN = Makefile.many
1261:
1262: speed-many: \$(MANY_OBJS) speed-many\$U.o libspeed.la $extra_libraries
1263: \$(LINK) \$(LDFLAGS) speed-many\$U.o \$(MANY_OBJS) \$(LDADD) \$(LIBS) $extra_libraries
1264:
1265: try-many: \$(MANY_OBJS) try-many\$U.o libspeed.la $extra_libraries
1266: \$(LINK) \$(LDFLAGS) try-many\$U.o \$(MANY_OBJS) \$(LDADD) \$(LIBS) $extra_libraries
1267:
1268: try-many.o: try-many.c \$(top_srcdir)/tests/devel/try.c $trydeps
1269: \$(COMPILE) -I\$(top_srcdir)/tests/devel -c try-many.c
1270:
1271: EOF
1272:
1273: print_ansi2knr("speed-many");
1274: print_ansi2knr("try-many",
1275: "\$(top_srcdir)/tests/devel/try.c",
1276: "-I\$(top_srcdir)/tests/devel");
1277:
1278: print MAKEFILE <<EOF;
1279: RM_TMP = rm -f
1280: CFLAGS_TESTS = -DSIZE=50 -DTIMES=1 -DRANDOM -DCLOCK=333000000
1281: CFLAGS_TESTS_SP = -DSIZE=1024 -DNOCHECK -DOPS=200000000 -DCLOCK=333000000
1282: EOF
1283:
1284:
1285: print "Total $count_files files, $count_functions functions\n";
1286:
1287:
1288:
1289: # Local variables:
1290: # perl-indent-level: 2
1291: # End:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>