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