Blame tune/many.pl

Packit 5c3484
#! /usr/bin/perl -w
Packit 5c3484
Packit 5c3484
# Copyright 2000-2002 Free Software Foundation, Inc.
Packit 5c3484
#
Packit 5c3484
#  This file is part of the GNU MP Library.
Packit 5c3484
#
Packit 5c3484
#  The GNU MP Library is free software; you can redistribute it and/or modify
Packit 5c3484
#  it under the terms of either:
Packit 5c3484
#
Packit 5c3484
#    * the GNU Lesser General Public License as published by the Free
Packit 5c3484
#      Software Foundation; either version 3 of the License, or (at your
Packit 5c3484
#      option) any later version.
Packit 5c3484
#
Packit 5c3484
#  or
Packit 5c3484
#
Packit 5c3484
#    * the GNU General Public License as published by the Free Software
Packit 5c3484
#      Foundation; either version 2 of the License, or (at your option) any
Packit 5c3484
#      later version.
Packit 5c3484
#
Packit 5c3484
#  or both in parallel, as here.
Packit 5c3484
#
Packit 5c3484
#  The GNU MP Library is distributed in the hope that it will be useful, but
Packit 5c3484
#  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit 5c3484
#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit 5c3484
#  for more details.
Packit 5c3484
#
Packit 5c3484
#  You should have received copies of the GNU General Public License and the
Packit 5c3484
#  GNU Lesser General Public License along with the GNU MP Library.  If not,
Packit 5c3484
#  see https://www.gnu.org/licenses/.
Packit 5c3484
Packit 5c3484
Packit 5c3484
# Usage:  cd $builddir/tune
Packit 5c3484
#	  perl $srcdir/tune/many.pl [-t] <files/dirs>...
Packit 5c3484
#
Packit 5c3484
# Output: speed-many.c
Packit 5c3484
#         try-many.c
Packit 5c3484
#         Makefile.many
Packit 5c3484
#
Packit 5c3484
# Make alternate versions of various mpn routines available for measuring
Packit 5c3484
# and testing.
Packit 5c3484
#
Packit 5c3484
# The $srcdir and $builddir in the invocation above just means the script
Packit 5c3484
# lives in the tune source directory, but should be run in the tune build
Packit 5c3484
# directory.  When not using a separate object directory this just becomes
Packit 5c3484
#
Packit 5c3484
#	cd tune
Packit 5c3484
#	perl many.pl [-t] <files/dirs>...
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# SINGLE FILES
Packit 5c3484
#
Packit 5c3484
# Suppose $HOME/newcode/mul_1_experiment.asm is a new implementation of
Packit 5c3484
# mpn_mul_1, then
Packit 5c3484
#
Packit 5c3484
#	cd $builddir/tune
Packit 5c3484
#	perl $srcdir/tune/many.pl $HOME/newcode/mul_1_experiment.asm
Packit 5c3484
#
Packit 5c3484
# will produce rules and renaming so that a speed program incorporating it
Packit 5c3484
# can be built,
Packit 5c3484
#
Packit 5c3484
#	make -f Makefile.many speed-many
Packit 5c3484
#
Packit 5c3484
# then for example it can be compared to the standard mul_1,
Packit 5c3484
#
Packit 5c3484
#	./speed-many -s 1-30 mpn_mul_1 mpn_mul_1_experiment
Packit 5c3484
#
Packit 5c3484
# An expanded try program can be used to check correctness,
Packit 5c3484
#
Packit 5c3484
#	make -f Makefile.many try-many
Packit 5c3484
#
Packit 5c3484
# and run
Packit 5c3484
#
Packit 5c3484
#	./try-many mpn_mul_1_experiment
Packit 5c3484
#
Packit 5c3484
# Files can be ".c", ".S" or ".asm".  ".s" files can't be used because they
Packit 5c3484
# don't get any preprocessing so there's no way to do renaming of their
Packit 5c3484
# functions.
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# WHOLE DIRECTORIES
Packit 5c3484
#
Packit 5c3484
# If a directory is given, then all files in it will be made available.
Packit 5c3484
# For example,
Packit 5c3484
#
Packit 5c3484
#	cd $builddir/tune
Packit 5c3484
#	perl $srcdir/tune/many.pl $HOME/newcode
Packit 5c3484
#
Packit 5c3484
# Each file should have a suffix, like "_experiment" above.
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# MPN DIRECTORIES
Packit 5c3484
#
Packit 5c3484
# mpn directories from the GMP source tree can be included, and this is a
Packit 5c3484
# convenient way to compare multiple implementations suiting different chips
Packit 5c3484
# in a CPU family.  For example the following would make all x86 routines
Packit 5c3484
# available,
Packit 5c3484
#
Packit 5c3484
#	cd $builddir/tune
Packit 5c3484
#	perl $srcdir/tune/many.pl `find $srcdir/mpn/x86 -type d`
Packit 5c3484
#
Packit 5c3484
# On a new x86 chip a comparison could then be made to see how existing code
Packit 5c3484
# runs.  For example,
Packit 5c3484
#
Packit 5c3484
#	make -f Makefile.many speed-many
Packit 5c3484
#	./speed-many -s 1-30 -c \
Packit 5c3484
#		mpn_add_n_x86 mpn_add_n_pentium mpn_add_n_k6 mpn_add_n_k7
Packit 5c3484
#
Packit 5c3484
# Files in "mpn" subdirectories don't need the "_experiment" style suffix
Packit 5c3484
# described above, instead a suffix is constructed from the subdirectory.
Packit 5c3484
# For example "mpn/x86/k7/mmx/mod_1.asm" will generate a function
Packit 5c3484
# mpn_mod_1_k7_mmx.  The rule is to take the last directory name after the
Packit 5c3484
# "mpn", or the last two if there's three or more.  (Check the generated
Packit 5c3484
# speed-many.c if in doubt.)
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# GENERIC C
Packit 5c3484
#
Packit 5c3484
# The mpn/generic directory can be included too, just like any processor
Packit 5c3484
# specific directory.  This is a good way to compare assembler and generic C
Packit 5c3484
# implementations.  For example,
Packit 5c3484
#
Packit 5c3484
#	cd $builddir/tune
Packit 5c3484
#	perl $srcdir/tune/many.pl $srcdir/mpn/generic
Packit 5c3484
#
Packit 5c3484
# or if just a few routines are of interest, then for example
Packit 5c3484
#
Packit 5c3484
#	cd $builddir/tune
Packit 5c3484
#	perl $srcdir/tune/many.pl \
Packit 5c3484
#		$srcdir/mpn/generic/lshift.c \
Packit 5c3484
#		$srcdir/mpn/generic/mod_1.c \
Packit 5c3484
#		$srcdir/mpn/generic/aorsmul_1.c
Packit 5c3484
#
Packit 5c3484
# giving mpn_lshift_generic etc.
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# TESTS/DEVEL PROGRAMS
Packit 5c3484
#
Packit 5c3484
# Makefile.many also has rules to build the tests/devel programs with suitable
Packit 5c3484
# renaming, and with some parameters for correctness or speed.  This is less
Packit 5c3484
# convenient than the speed and try programs, but provides an independent
Packit 5c3484
# check.  For example,
Packit 5c3484
#
Packit 5c3484
#	make -f Makefile.many tests_mul_1_experimental
Packit 5c3484
#	./tests_mul_1_experimental
Packit 5c3484
#
Packit 5c3484
# and for speed
Packit 5c3484
#
Packit 5c3484
#	make -f Makefile.many tests_mul_1_experimental_sp
Packit 5c3484
#	./tests_mul_1_experimental_sp
Packit 5c3484
#
Packit 5c3484
# Not all the programs support speed measuring, in which case only the
Packit 5c3484
# correctness test will be useful.
Packit 5c3484
#
Packit 5c3484
# The parameters for repetitions and host clock speed are -D defines.  Some
Packit 5c3484
# defaults are provided at the end of Makefile.many, but probably these will
Packit 5c3484
# want to be overridden.  For example,
Packit 5c3484
#
Packit 5c3484
#	rm tests_mul_1_experimental.o
Packit 5c3484
#	make -f Makefile.many \
Packit 5c3484
#	   CFLAGS_TESTS="-DSIZE=50 -DTIMES=1000 -DRANDOM -DCLOCK=175000000" \
Packit 5c3484
#	   tests_mul_1_experimental
Packit 5c3484
#	./tests_mul_1_experimental
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# OTHER NOTES
Packit 5c3484
#
Packit 5c3484
# The mappings of file names to functions, and the macros to then use for
Packit 5c3484
# speed measuring etc are driven by @table below.  The scheme isn't
Packit 5c3484
# completely general, it's only got as many variations as have been needed
Packit 5c3484
# so far.
Packit 5c3484
#
Packit 5c3484
# Some functions are only made available in speed-many, or others only in
Packit 5c3484
# try-many.  An @table entry speed=>none means no speed measuring is
Packit 5c3484
# available, or try=>none no try program testing.  These can be removed
Packit 5c3484
# if/when the respective programs get the necessary support.
Packit 5c3484
#
Packit 5c3484
# If a file has "1c" or "nc" carry-in entrypoints, they're renamed and made
Packit 5c3484
# available too.  These are recognised from PROLOGUE or MULFUNC_PROLOGUE in
Packit 5c3484
# .S and .asm files, or from a line starting with "mpn_foo_1c" in a .c file
Packit 5c3484
# (possibly via a #define), and on that basis are entirely optional.  This
Packit 5c3484
# entrypoint matching is done for the standard entrypoints too, but it would
Packit 5c3484
# be very unusual to have for instance a mul_1c without a mul_1.
Packit 5c3484
#
Packit 5c3484
# Some mpz files are recognized.  For example an experimental copy of
Packit 5c3484
# mpz/powm.c could be included as powm_new.c and would be called
Packit 5c3484
# mpz_powm_new.  So far only speed measuring is available for these.
Packit 5c3484
#
Packit 5c3484
# For the ".S" and ".asm" files, both PIC and non-PIC objects are built.
Packit 5c3484
# The PIC functions have a "_pic" suffix, for example "mpn_mod_1_k7_mmx_pic".
Packit 5c3484
# This can be ignored for routines that don't differ for PIC, or for CPUs
Packit 5c3484
# where everything is PIC anyway.
Packit 5c3484
#
Packit 5c3484
# K&R compilers are supported via the same ansi2knr mechanism used by
Packit 5c3484
# automake, though it's hard to believe anyone will have much interest in
Packit 5c3484
# measuring a compiler so old that it doesn't even have an ANSI mode.
Packit 5c3484
#
Packit 5c3484
# The "-t" option can be used to print a trace of the files found and what's
Packit 5c3484
# done with them.  A great deal of obscure output is produced, but it can
Packit 5c3484
# indicate where or why some files aren't being recognised etc.  For
Packit 5c3484
# example,
Packit 5c3484
#
Packit 5c3484
#	cd $builddir/tune
Packit 5c3484
#	perl $srcdir/tune/many.pl -t $HOME/newcode/add_n_weird.asm
Packit 5c3484
#
Packit 5c3484
# In general, when including new code, all that's really necessary is that
Packit 5c3484
# it will compile or assemble under the current configuration.  It's fine if
Packit 5c3484
# some code doesn't actually run due to bugs, or to needing a newer CPU or
Packit 5c3484
# whatever, simply don't ask for the offending routines when invoking
Packit 5c3484
# speed-many or try-many, or don't try to run them on sizes they don't yet
Packit 5c3484
# support, or whatever.
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# CPU SPECIFICS
Packit 5c3484
#
Packit 5c3484
# x86 - All the x86 code will assemble on any system, but code for newer
Packit 5c3484
#       chips might not run on older chips.  Expect SIGILLs from new
Packit 5c3484
#       instructions on old chips.
Packit 5c3484
#
Packit 5c3484
#       A few "new" instructions, like cmov for instance, are done as macros
Packit 5c3484
#       and will generate some equivalent plain i386 code when HAVE_HOST_CPU
Packit 5c3484
#       in config.m4 indicates an old CPU.  It won't run fast, but it does
Packit 5c3484
#       make it possible to test correctness.
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# INTERNALS
Packit 5c3484
#
Packit 5c3484
# The nonsense involving $ENV is some hooks used during development to add
Packit 5c3484
# additional functions temporarily.
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# FUTURE
Packit 5c3484
#
Packit 5c3484
# Maybe the C files should be compiled pic and non-pic too.  Wait until
Packit 5c3484
# there's a difference that might be of interest.
Packit 5c3484
#
Packit 5c3484
# Warn if a file provides no functions.
Packit 5c3484
#
Packit 5c3484
# Allow mpz and mpn files of the same name.  Currently the mpn fib2_ui
Packit 5c3484
# matching hides the mpz version of that.  Will need to check the file
Packit 5c3484
# contents to see which it is.  Would be worth allowing an "mpz_" or "mpn_"
Packit 5c3484
# prefix on the filenames to have working versions of both in one directory.
Packit 5c3484
#
Packit 5c3484
#
Packit 5c3484
# LIMITATIONS
Packit 5c3484
#
Packit 5c3484
# Some of the command lines can become very long when a lot of files are
Packit 5c3484
# included.  If this is a problem on a given system the only suggestion is
Packit 5c3484
# to run many.pl for just those that are actually wanted at a particular
Packit 5c3484
# time.
Packit 5c3484
#
Packit 5c3484
# DOS 8.3 or SysV 14 char filesystems won't work, since the long filenames
Packit 5c3484
# generated will almost certainly fail to be unique.
Packit 5c3484
Packit 5c3484
Packit 5c3484
use strict;
Packit 5c3484
use File::Basename;
Packit 5c3484
use Getopt::Std;
Packit 5c3484
Packit 5c3484
my %opt;
Packit 5c3484
getopts('t', \%opt);
Packit 5c3484
Packit 5c3484
my @DIRECTORIES = @ARGV;
Packit 5c3484
if (defined $ENV{directories}) { push @DIRECTORIES, @{$ENV{directories}} }
Packit 5c3484
Packit 5c3484
Packit 5c3484
# regexp - matched against the start of the filename.  If a grouping "(...)"
Packit 5c3484
#          is present then only the first such part is used.
Packit 5c3484
#
Packit 5c3484
# mulfunc - filenames to be generated from a multi-function file.
Packit 5c3484
#
Packit 5c3484
# funs - functions provided by the file, defaulting to the filename with mpn
Packit 5c3484
#          (or mpX).
Packit 5c3484
#
Packit 5c3484
# mpX - prefix like "mpz", defaulting to "mpn".
Packit 5c3484
#
Packit 5c3484
# ret - return value type.
Packit 5c3484
#
Packit 5c3484
# args, args_<fun> - arguments for the given function.  If an args_<fun> is
Packit 5c3484
#          set then it's used, otherwise plain args is used.  "mp_limb_t
Packit 5c3484
#          carry" is appended for carry-in variants.
Packit 5c3484
#
Packit 5c3484
# try - try.c TYPE_ to use, defaulting to TYPE_fun with the function name
Packit 5c3484
#          in upper case.  "C" is appended for carry-in variants.  Can be
Packit 5c3484
#          'none' for no try program entry.
Packit 5c3484
#
Packit 5c3484
# speed - SPEED_ROUTINE_ to use, handled like "try".
Packit 5c3484
#
Packit 5c3484
# speed_flags - SPEED_ROUTINE_ to use, handled like "try".
Packit 5c3484
Packit 5c3484
Packit 5c3484
my @table =
Packit 5c3484
    (
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'add_n|sub_n|addlsh1_n|sublsh1_n|rsh1add_n|rsh1sub_n',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'aors_n',
Packit 5c3484
       'mulfunc'=> ['add_n','sub_n'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'addmul_1|submul_1',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'aorsmul_1',
Packit 5c3484
       'mulfunc'=> ['addmul_1','submul_1'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'addmul_2|submul_2',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_2',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try-minsize' => 2,
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'addmul_3|submul_3',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_3',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try-minsize' => 3,
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'addmul_4|submul_4',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_4',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try-minsize' => 4,
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'addmul_5|submul_5',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_5',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try-minsize' => 5,
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'addmul_6|submul_6',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_6',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try-minsize' => 6,
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'addmul_7|submul_7',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_7',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try-minsize' => 7,
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'addmul_8|submul_8',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_8',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try-minsize' => 8,
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'add_n_sub_n',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr sum, mp_ptr diff, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'com|copyi|copyd',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_COPY',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'dive_1',
Packit 5c3484
       'funs'  => ['divexact_1'],
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'diveby3',
Packit 5c3484
       'funs'  => ['divexact_by3c'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr dst, mp_srcptr src, mp_size_t size',
Packit 5c3484
       'carrys'=> [''],
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_COPY',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     # mpn_preinv_divrem_1 is an optional extra entrypoint
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'divrem_1',
Packit 5c3484
       'funs'  => ['divrem_1', 'preinv_divrem_1'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args_divrem_1' => 'mp_ptr rp, mp_size_t xsize, mp_srcptr sp, mp_size_t size, mp_limb_t divisor',
Packit 5c3484
       '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',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
       'speed_suffixes' => ['f'],
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'pre_divrem_1',
Packit 5c3484
       'funs'  => ['preinv_divrem_1'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       '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',
Packit 5c3484
       'speed_flags' => 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'divrem_2',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr qp, mp_size_t qxn, mp_srcptr np, mp_size_t nsize, mp_srcptr dp',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'sb_divrem_mn',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr qp, mp_ptr np, mp_size_t nsize, mp_srcptr dp, mp_size_t dsize',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_DC_DIVREM_SB',
Packit 5c3484
       'try-minsize' => 3,
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'tdiv_qr',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr qp, mp_size_t qxn, mp_ptr np, mp_size_t nsize, mp_srcptr dp, mp_size_t dsize',
Packit 5c3484
       'speed' => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'get_str',
Packit 5c3484
       'ret'   => 'size_t',
Packit 5c3484
       'args'  => 'unsigned char *str, int base, mp_ptr mptr, mp_size_t msize',
Packit 5c3484
       'speed_flags' => 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'set_str',
Packit 5c3484
       'ret'   => 'mp_size_t',
Packit 5c3484
       'args'  => 'mp_ptr xp, const unsigned char *str, size_t str_len, int base',
Packit 5c3484
       'speed_flags' => 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'fac_ui',
Packit 5c3484
       'mpX'   => 'mpz',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mpz_ptr r, unsigned long n',
Packit 5c3484
       'speed_flags' => 'FLAG_NODATA',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'fib2_ui',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr fp, mp_ptr f1p, unsigned long n',
Packit 5c3484
       'rename'=> ['__gmp_fib_table'],
Packit 5c3484
       'speed_flags' => 'FLAG_NODATA',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'fib_ui',
Packit 5c3484
       'mpX'   => 'mpz',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mpz_ptr fn, unsigned long n',
Packit 5c3484
       'speed_flags' => 'FLAG_NODATA',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'fib2_ui',
Packit 5c3484
       'mpX'   => 'mpz',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mpz_ptr fn, mpz_ptr fnsub1, unsigned long n',
Packit 5c3484
       'speed_flags' => 'FLAG_NODATA',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'lucnum_ui',
Packit 5c3484
       'mpX'   => 'mpz',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mpz_ptr ln, unsigned long n',
Packit 5c3484
       'speed_flags' => 'FLAG_NODATA',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'lucnum2_ui',
Packit 5c3484
       'mpX'   => 'mpz',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mpz_ptr ln, mpz_ptr lnsub1, unsigned long n',
Packit 5c3484
       'speed_flags' => 'FLAG_NODATA',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'gcd_1',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr xp, mp_size_t xsize, mp_limb_t y',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'speed_suffixes' => ['N'],
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> '(gcd)(?!(_1|ext|_finda))',
Packit 5c3484
       'ret'   => 'mp_size_t',
Packit 5c3484
       'args'  => 'mp_ptr gp, mp_ptr up, mp_size_t usize, mp_ptr vp, mp_size_t vsize',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'gcd_finda',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_srcptr cp',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'jacobi',
Packit 5c3484
       'funs'  => ['jacobi', 'legendre', 'kronecker'],
Packit 5c3484
       'mpX'   => 'mpz',
Packit 5c3484
       'ret'   => 'int',
Packit 5c3484
       'args'  => 'mpz_srcptr a, mpz_srcptr b',
Packit 5c3484
       'try-legendre' => 'TYPE_MPZ_JACOBI',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'jacbase',
Packit 5c3484
       'funs'  => ['jacobi_base'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_limb_t a, mp_limb_t b, int bit1',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_JACBASE',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'logops_n',
Packit 5c3484
       'mulfunc'=> ['and_n','andn_n','nand_n','ior_n','iorn_n','nior_n','xor_n','xnor_n'],
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> '[lr]shift',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, unsigned shift',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     # mpn_preinv_mod_1 is an optional extra entrypoint
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> '(mod_1)(?!_rs)',
Packit 5c3484
       'funs'  => ['mod_1','preinv_mod_1'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args_mod_1'       => 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor',
Packit 5c3484
       'args_preinv_mod_1'=> 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor, mp_limb_t inverse',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'pre_mod_1',
Packit 5c3484
       'funs'  => ['preinv_mod_1'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor, mp_limb_t inverse',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'mod_34lsub1',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_srcptr src, mp_size_t len',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'invert_limb',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_limb_t divisor',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       # not for use with hppa reversed argument versions of mpn_umul_ppmm
Packit 5c3484
       'regexp'=> 'udiv',
Packit 5c3484
       'funs'  => ['udiv_qrnnd','udiv_qrnnd_r'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args_udiv_qrnnd'   => 'mp_limb_t *, mp_limb_t, mp_limb_t, mp_limb_t',
Packit 5c3484
       'args_udiv_qrnnd_r' => 'mp_limb_t, mp_limb_t, mp_limb_t, mp_limb_t *',
Packit 5c3484
       'speed' => 'none',
Packit 5c3484
       'try-minsize' => 2,
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'mode1o',
Packit 5c3484
       'funs'  => ['modexact_1_odd'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_srcptr src, mp_size_t size, mp_limb_t divisor',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'modlinv',
Packit 5c3484
       'funs'  => ['modlimb_invert'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_limb_t v',
Packit 5c3484
       'carrys'=> [''],
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'mul_1',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'mul_2',
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr mult',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_UNARY_2',
Packit 5c3484
       'speed_flags'=> 'FLAG_R',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'mul_basecase',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t xsize, mp_srcptr yp, mp_size_t ysize',
Packit 5c3484
       'speed_flags' => 'FLAG_R_OPTIONAL | FLAG_RSIZE',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> '(mul_n)[_.]',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
Packit 5c3484
       'rename'=> ['kara_mul_n','kara_sqr_n','toom3_mul_n','toom3_sqr_n'],
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'umul',
Packit 5c3484
       'funs'  => ['umul_ppmm','umul_ppmm_r'],
Packit 5c3484
       'ret'   => 'mp_limb_t',
Packit 5c3484
       'args_umul_ppmm'   => 'mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2',
Packit 5c3484
       'args_umul_ppmm_r' => 'mp_limb_t m1, mp_limb_t m2, mp_limb_t *lowptr',
Packit 5c3484
       'speed' => 'none',
Packit 5c3484
       'try-minsize' => 3,
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'popham',
Packit 5c3484
       'mulfunc'=> ['popcount','hamdist'],
Packit 5c3484
       'ret'   => 'unsigned long',
Packit 5c3484
       'args_popcount'=> 'mp_srcptr xp, mp_size_t size',
Packit 5c3484
       'args_hamdist' => 'mp_srcptr xp, mp_srcptr yp, mp_size_t size',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'popcount',
Packit 5c3484
       'ret'   => 'unsigned long',
Packit 5c3484
       'args'  => 'mp_srcptr xp, mp_size_t size',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'hamdist',
Packit 5c3484
       'ret'   => 'unsigned long',
Packit 5c3484
       'args'  => 'mp_srcptr xp, mp_srcptr yp, mp_size_t size',
Packit 5c3484
       # extra renaming to support sharing a data table with mpn_popcount
Packit 5c3484
       'rename'=> ['popcount'],
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'sqr_basecase',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
Packit 5c3484
       'speed' => 'SPEED_ROUTINE_MPN_SQR',
Packit 5c3484
       'try'   => 'TYPE_SQR',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'sqr_diagonal',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'sqrtrem',
Packit 5c3484
       'ret'   => 'mp_size_t',
Packit 5c3484
       'args'  => 'mp_ptr root, mp_ptr rem, mp_srcptr src, mp_size_t size',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'cntlz',
Packit 5c3484
       'funs'  => ['count_leading_zeros'],
Packit 5c3484
       'ret'   => 'unsigned',
Packit 5c3484
       'args'  => 'mp_limb_t',
Packit 5c3484
       'macro-before' => "#undef COUNT_LEADING_ZEROS_0",
Packit 5c3484
       'macro-speed'  =>
Packit 5c3484
'#ifdef COUNT_LEADING_ZEROS_0
Packit 5c3484
#define COUNT_LEADING_ZEROS_0_ALLOWED   1
Packit 5c3484
#else
Packit 5c3484
#define COUNT_LEADING_ZEROS_0_ALLOWED   0
Packit 5c3484
#endif
Packit 5c3484
  SPEED_ROUTINE_COUNT_ZEROS_A (1, COUNT_LEADING_ZEROS_0_ALLOWED);
Packit 5c3484
  $fun (c, n);
Packit 5c3484
  SPEED_ROUTINE_COUNT_ZEROS_B ()',
Packit 5c3484
       'speed_flags'=> 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'cnttz',
Packit 5c3484
       'funs'  => ['count_trailing_zeros'],
Packit 5c3484
       'ret'   => 'unsigned',
Packit 5c3484
       'args'  => 'mp_limb_t',
Packit 5c3484
       'macro-speed' => '
Packit 5c3484
  SPEED_ROUTINE_COUNT_ZEROS_A (0, 0);
Packit 5c3484
  $fun (c, n);
Packit 5c3484
  SPEED_ROUTINE_COUNT_ZEROS_B ()',
Packit 5c3484
       'speed_flags' => 'FLAG_R_OPTIONAL',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'zero',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mp_ptr ptr, mp_size_t size',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> '(powm)(?!_ui)',
Packit 5c3484
       'mpX'   => 'mpz',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'powm_ui',
Packit 5c3484
       'mpX'   => 'mpz',
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'mpz_ptr r, mpz_srcptr b, unsigned long e, mpz_srcptr m',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
     },
Packit 5c3484
Packit 5c3484
     # special for use during development
Packit 5c3484
     {
Packit 5c3484
       'regexp'=> 'back',
Packit 5c3484
       'funs'  => ['back_to_back'],
Packit 5c3484
       'ret'   => 'void',
Packit 5c3484
       'args'  => 'void',
Packit 5c3484
       'pic'   => 'no',
Packit 5c3484
       'try'   => 'none',
Packit 5c3484
       'speed_flags'=> 'FLAG_NODATA',
Packit 5c3484
     },
Packit 5c3484
     );
Packit 5c3484
Packit 5c3484
if (defined $ENV{table2}) {
Packit 5c3484
  my @newtable = @{$ENV{table2}};
Packit 5c3484
  push @newtable, @table;
Packit 5c3484
  @table = @newtable;
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
my %pictable =
Packit 5c3484
    (
Packit 5c3484
     'yes' => {
Packit 5c3484
       'suffix' =>  '_pic',
Packit 5c3484
       'asmflags'=> '$(ASMFLAGS_PIC)',
Packit 5c3484
       'cflags' =>  '$(CFLAGS_PIC)',
Packit 5c3484
     },
Packit 5c3484
     'no' => {
Packit 5c3484
       'suffix' =>  '',
Packit 5c3484
       'asmflags'=> '',
Packit 5c3484
       'cflags' =>  '',
Packit 5c3484
     },
Packit 5c3484
     );
Packit 5c3484
Packit 5c3484
Packit 5c3484
my $builddir = $ENV{builddir};
Packit 5c3484
$builddir = "." if (! defined $builddir);
Packit 5c3484
Packit 5c3484
my $top_builddir = "${builddir}/..";
Packit 5c3484
Packit 5c3484
Packit 5c3484
open(MAKEFILE, "<${builddir}/Makefile")
Packit 5c3484
  or die "Cannot open ${builddir}/Makefile: $!\n"
Packit 5c3484
       . "Is this a tune build directory?";
Packit 5c3484
my ($srcdir, $top_srcdir);
Packit 5c3484
while (<MAKEFILE>) {
Packit 5c3484
  if (/^srcdir = (.*)/) {     $srcdir = $1;     }
Packit 5c3484
  if (/^top_srcdir = (.*)/) { $top_srcdir = $1; }
Packit 5c3484
}
Packit 5c3484
die "Cannot find \$srcdir in Makefile\n" if (! defined $srcdir);
Packit 5c3484
die "Cannot find \$top_srcdir in Makefile\n" if (! defined $top_srcdir);
Packit 5c3484
print "srcdir $srcdir\n" if $opt{'t'};
Packit 5c3484
print "top_srcdir $top_srcdir\n" if $opt{'t'};
Packit 5c3484
close(MAKEFILE);
Packit 5c3484
Packit 5c3484
Packit 5c3484
open(SPEED, ">speed-many.c") or die;
Packit 5c3484
print SPEED
Packit 5c3484
"/* speed-many.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */
Packit 5c3484
Packit 5c3484
";
Packit 5c3484
my $SPEED_EXTRA_ROUTINES = "#define SPEED_EXTRA_ROUTINES \\\n";
Packit 5c3484
my $SPEED_EXTRA_PROTOS = "#define SPEED_EXTRA_PROTOS \\\n";
Packit 5c3484
my $SPEED_CODE = "";
Packit 5c3484
Packit 5c3484
open(TRY, ">try-many.c") or die;
Packit 5c3484
print TRY
Packit 5c3484
    "/* try-many.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */\n" .
Packit 5c3484
    "\n";
Packit 5c3484
my $TRY_EXTRA_ROUTINES = "#define EXTRA_ROUTINES \\\n";
Packit 5c3484
my $TRY_EXTRA_PROTOS = "#define EXTRA_PROTOS \\\n";
Packit 5c3484
Packit 5c3484
open(FD,"<${top_builddir}/libtool") or die "Cannot open \"${top_builddir}/libtool\": $!\n";
Packit 5c3484
my $pic_flag;
Packit 5c3484
while (<FD>) {
Packit 5c3484
  if (/^pic_flag="?([^"]*)"?$/) {
Packit 5c3484
    $pic_flag=$1;
Packit 5c3484
    last;
Packit 5c3484
  }
Packit 5c3484
}
Packit 5c3484
close FD;
Packit 5c3484
if (! defined $pic_flag) {
Packit 5c3484
  die "Cannot find pic_flag in ${top_builddir}/libtool";
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
my $CFLAGS_PIC = $pic_flag;
Packit 5c3484
Packit 5c3484
my $ASMFLAGS_PIC = "";
Packit 5c3484
foreach (split /[ \t]/, $pic_flag) {
Packit 5c3484
  if (/^-D/) {
Packit 5c3484
    $ASMFLAGS_PIC .= " " . $_;
Packit 5c3484
  }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
open(MAKEFILE, ">Makefile.many") or die;
Packit 5c3484
print MAKEFILE
Packit 5c3484
    "# Makefile.many generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST\n" .
Packit 5c3484
    "\n" .
Packit 5c3484
    "all: speed-many try-many\n" .
Packit 5c3484
    "\n" .
Packit 5c3484
    "#--------- begin included copy of basic Makefile ----------\n" .
Packit 5c3484
    "\n";
Packit 5c3484
open(FD,"<${builddir}/Makefile") or die "Cannot open \"${builddir}/Makefile\": $!\n";
Packit 5c3484
print MAKEFILE <FD>;
Packit 5c3484
close FD;
Packit 5c3484
print MAKEFILE
Packit 5c3484
    "\n" .
Packit 5c3484
    "#--------- end included copy of basic Makefile ----------\n" .
Packit 5c3484
    "\n" .
Packit 5c3484
    "CFLAGS_PIC = $CFLAGS_PIC\n" .
Packit 5c3484
    "ASMFLAGS_PIC = $ASMFLAGS_PIC\n" .
Packit 5c3484
    "\n";
Packit 5c3484
Packit 5c3484
my $CLEAN="";
Packit 5c3484
my $MANY_OBJS="";
Packit 5c3484
Packit 5c3484
Packit 5c3484
sub print_ansi2knr {
Packit 5c3484
  my ($base,$file,$includes) = @_;
Packit 5c3484
  if (! defined $file)     { $file = "$base.c"; }
Packit 5c3484
  if (! defined $includes) { $includes = ""; }
Packit 5c3484
Packit 5c3484
  print MAKEFILE <
Packit 5c3484
${base}_.c: $file \$(ANSI2KNR)
Packit 5c3484
	\$(CPP) \$(DEFS) \$(INCLUDES) $includes \$(AM_CPPFLAGS) \$(CPPFLAGS) $file | sed 's/^# \([0-9]\)/#line \\1/' | \$(ANSI2KNR) >${base}_.c
Packit 5c3484
Packit 5c3484
EOF
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
# Spawning a glob is a touch slow when there's lots of files.
Packit 5c3484
my @files = ();
Packit 5c3484
foreach my $dir (@DIRECTORIES) {
Packit 5c3484
  print "dir $dir\n" if $opt{'t'};
Packit 5c3484
  if (-f $dir) {
Packit 5c3484
    push @files,$dir;
Packit 5c3484
  } else {
Packit 5c3484
    if (! opendir DD,$dir) {
Packit 5c3484
      print "Cannot open $dir: $!\n";
Packit 5c3484
    } else {
Packit 5c3484
      push @files, map {$_="$dir/$_"} grep /\.(c|asm|S|h)$/, readdir DD;
Packit 5c3484
      closedir DD;
Packit 5c3484
    }
Packit 5c3484
  }
Packit 5c3484
}
Packit 5c3484
@files = sort @files;
Packit 5c3484
print "@files ",join(" ",@files),"\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
my $count_files = 0;
Packit 5c3484
my $count_functions = 0;
Packit 5c3484
my %seen_obj;
Packit 5c3484
my %seen_file;
Packit 5c3484
Packit 5c3484
foreach my $file_full (@files) {
Packit 5c3484
  if (! -f $file_full) {
Packit 5c3484
    print "Not a file: $file_full\n";
Packit 5c3484
    next;
Packit 5c3484
  }
Packit 5c3484
  if (defined $seen_file{$file_full}) {
Packit 5c3484
    print "Skipping duplicate file: $file_full\n";
Packit 5c3484
    next;
Packit 5c3484
  }
Packit 5c3484
  $seen_file{$file_full} = 1;
Packit 5c3484
Packit 5c3484
  my ($FILE,$path,$lang) = fileparse($file_full,"\.[a-zA-Z]+");
Packit 5c3484
  $path =~ s/\/$//;
Packit 5c3484
  print "file $FILE path $path lang $lang\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
  my @pic_choices;
Packit 5c3484
  if ($lang eq '.asm')  { @pic_choices=('no','yes'); }
Packit 5c3484
  elsif ($lang eq '.c') { @pic_choices=('no'); }
Packit 5c3484
  elsif ($lang eq '.S') { @pic_choices=('no','yes'); }
Packit 5c3484
  elsif ($lang eq '.h') { @pic_choices=('no'); }
Packit 5c3484
  else { next };
Packit 5c3484
Packit 5c3484
  my ($t, $file_match);
Packit 5c3484
  foreach my $p (@table) {
Packit 5c3484
    # print " ",$p->{'regexp'},"\n" if $opt{'t'};
Packit 5c3484
    if ($FILE =~ "^($p->{'regexp'})") {
Packit 5c3484
      $t = $p;
Packit 5c3484
      $file_match = $1;
Packit 5c3484
      $file_match = $2 if defined $2;
Packit 5c3484
      last;
Packit 5c3484
    }
Packit 5c3484
  }
Packit 5c3484
  next if ! defined $t;
Packit 5c3484
  print "match $t->{'regexp'} $FILE ($file_full)\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
  if (! open FD,"<$file_full") { print "Can't open $file_full: $!\n"; next }
Packit 5c3484
  my @file_contents = <FD>;
Packit 5c3484
  close FD;
Packit 5c3484
Packit 5c3484
  my $objs;
Packit 5c3484
  if (defined $t->{'mulfunc'}) { $objs = $t->{'mulfunc'}; }
Packit 5c3484
  else                         { $objs = [$file_match]; }
Packit 5c3484
  print "objs @$objs\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
  my $ret = $t->{'ret'};
Packit 5c3484
  if (! defined $ret && $lang eq '.h') { $ret = ''; }
Packit 5c3484
  if (! defined $ret) { die "$FILE return type not defined\n" };
Packit 5c3484
  print "ret $ret\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
  my $mpX = $t->{'mpX'};
Packit 5c3484
  if (! defined $mpX) { $mpX = ($lang eq '.h' ? '' : 'mpn'); }
Packit 5c3484
  $mpX = "${mpX}_" if $mpX ne '';
Packit 5c3484
  print "mpX $mpX\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
  my $carrys;
Packit 5c3484
  if (defined $t->{'carrys'}) { $carrys = $t->{'carrys'}; }
Packit 5c3484
  else                        { $carrys = ['','c'];       }
Packit 5c3484
  print "carrys $carrys @$carrys\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
  # some restriction functions are implemented, but they're not very useful
Packit 5c3484
  my $restriction='';
Packit 5c3484
Packit 5c3484
  my $suffix;
Packit 5c3484
  if ($FILE =~ ("${file_match}_(.+)")) {
Packit 5c3484
    $suffix = $1;
Packit 5c3484
  } elsif ($path =~ /\/mp[zn]\/(.*)$/) {
Packit 5c3484
    # derive the suffix from the path
Packit 5c3484
    $suffix = $1;
Packit 5c3484
    $suffix =~ s/\//_/g;
Packit 5c3484
    # use last directory name, or if there's 3 or more then the last two
Packit 5c3484
    if ($suffix =~ /([^_]*_)+([^_]+_[^_]+)$/) {
Packit 5c3484
      $suffix = $2;
Packit 5c3484
    } elsif ($suffix =~ /([^_]*_)*([^_]+)$/) {
Packit 5c3484
      $suffix = $2;
Packit 5c3484
    }
Packit 5c3484
  } else {
Packit 5c3484
    die "Can't determine suffix for: $file_full (path $path)\n";
Packit 5c3484
  }
Packit 5c3484
  print "suffix $suffix\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
  $count_files++;
Packit 5c3484
Packit 5c3484
  foreach my $obj (@{$objs}) {
Packit 5c3484
    print "obj $obj\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
    my $obj_with_suffix = "${obj}_$suffix";
Packit 5c3484
    if (defined $seen_obj{$obj_with_suffix}) {
Packit 5c3484
      print "Skipping duplicate object: $obj_with_suffix\n";
Packit 5c3484
      print "   first from: $seen_obj{$obj_with_suffix}\n";
Packit 5c3484
      print "   now from:   $file_full\n";
Packit 5c3484
      next;
Packit 5c3484
    }
Packit 5c3484
    $seen_obj{$obj_with_suffix} = $file_full;
Packit 5c3484
Packit 5c3484
    my $funs = $t->{'funs'};
Packit 5c3484
    $funs = [$obj] if ! defined $funs;
Packit 5c3484
    print "funs @$funs\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
    if (defined $t->{'pic'}) { @pic_choices = ('no'); }
Packit 5c3484
Packit 5c3484
    foreach my $pic (map {$pictable{$_}} @pic_choices) {
Packit 5c3484
      print "pic $pic->{'suffix'}\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
      my $objbase = "${obj}_$suffix$pic->{'suffix'}";
Packit 5c3484
      print "objbase $objbase\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
      if ($path !~ "." && -f "${objbase}.c") {
Packit 5c3484
	die "Already have ${objbase}.c";
Packit 5c3484
      }
Packit 5c3484
Packit 5c3484
      my $tmp_file = "tmp-$objbase.c";
Packit 5c3484
Packit 5c3484
      my $renaming;
Packit 5c3484
      foreach my $fun (@{$funs}) {
Packit 5c3484
        if ($mpX eq 'mpn_' && $lang eq '.c') {
Packit 5c3484
          $renaming .= "\t\t-DHAVE_NATIVE_mpn_$fun=1 \\\n";
Packit 5c3484
        }
Packit 5c3484
Packit 5c3484
        # The carry-in variant is with a "c" appended, unless there's a "_1"
Packit 5c3484
        # somewhere, eg. "modexact_1_odd", in which case that becomes "_1c".
Packit 5c3484
	my $fun_carry = $fun;
Packit 5c3484
	if (! ($fun_carry =~ s/_1/_1c/)) { $fun_carry = "${fun}c"; }
Packit 5c3484
Packit 5c3484
	$renaming .=
Packit 5c3484
	    "\t\t-D__g$mpX$fun=$mpX${fun}_$suffix$pic->{'suffix'} \\\n" .
Packit 5c3484
	    "\t\t-D__g$mpX$fun_carry=$mpX${fun_carry}_$suffix$pic->{'suffix'} \\\n";
Packit 5c3484
      }
Packit 5c3484
      foreach my $r (@{$t->{'rename'}}) {
Packit 5c3484
	if ($r =~ /^__gmp/) {
Packit 5c3484
	  $renaming .= "\\\n" .
Packit 5c3484
	      "\t\t-D$r=${r}_$suffix$pic->{'suffix'}";
Packit 5c3484
	} else {
Packit 5c3484
	  $renaming .= "\\\n" .
Packit 5c3484
	      "\t\t-D__g$mpX$r=$mpX${r}_$suffix$pic->{'suffix'}";
Packit 5c3484
	}
Packit 5c3484
      }
Packit 5c3484
      print "renaming $renaming\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
      print MAKEFILE "\n";
Packit 5c3484
      if ($lang eq '.asm') {
Packit 5c3484
	print MAKEFILE
Packit 5c3484
	    "$objbase.o: $file_full \$(ASM_HEADERS)\n" .
Packit 5c3484
	    "	\$(M4) \$(M4FLAGS) -DOPERATION_$obj $pic->{'asmflags'} \\\n" .
Packit 5c3484
  	    "$renaming" .
Packit 5c3484
	    "		$file_full >tmp-$objbase.s\n" .
Packit 5c3484
            "	\$(CCAS) \$(COMPILE_FLAGS) $pic->{'cflags'} tmp-$objbase.s -o $objbase.o\n" .
Packit 5c3484
            "	\$(RM_TMP) tmp-$objbase.s\n";
Packit 5c3484
	$MANY_OBJS .= " $objbase.o";
Packit 5c3484
Packit 5c3484
      } elsif ($lang eq '.c') {
Packit 5c3484
	print MAKEFILE
Packit 5c3484
	    "$objbase.o: $file_full\n" .
Packit 5c3484
	    "	\$(COMPILE) -DOPERATION_$obj $pic->{'cflags'} \\\n" .
Packit 5c3484
  	    "$renaming" .
Packit 5c3484
	    "		-c $file_full -o $objbase.o\n";
Packit 5c3484
	print_ansi2knr($objbase,
Packit 5c3484
		       $file_full,
Packit 5c3484
		       " -DOPERATION_$obj\\\n$renaming\t\t");
Packit 5c3484
	$MANY_OBJS .= " $objbase\$U.o";
Packit 5c3484
Packit 5c3484
      } elsif ($lang eq '.S') {
Packit 5c3484
	print MAKEFILE
Packit 5c3484
	    "$objbase.o: $file_full\n" .
Packit 5c3484
            "	\$(COMPILE) -g $pic->{'asmflags'} \\\n" .
Packit 5c3484
  	    "$renaming" .
Packit 5c3484
            "	-c $file_full -o $objbase.o\n";
Packit 5c3484
	$MANY_OBJS .= " $objbase.o";
Packit 5c3484
Packit 5c3484
      } elsif ($lang eq '.h') {
Packit 5c3484
	print MAKEFILE
Packit 5c3484
	    "$objbase.o: tmp-$objbase.c $file_full\n" .
Packit 5c3484
	    "	\$(COMPILE) -DOPERATION_$obj $pic->{'cflags'} \\\n" .
Packit 5c3484
  	    "$renaming" .
Packit 5c3484
	    "		-c tmp-$objbase.c -o $objbase.o\n";
Packit 5c3484
	print_ansi2knr($objbase,
Packit 5c3484
		       "tmp-$objbase.c",
Packit 5c3484
		       " -DOPERATION_$obj\\\n$renaming\t\t");
Packit 5c3484
	$MANY_OBJS .= " $objbase\$U.o";
Packit 5c3484
Packit 5c3484
        $CLEAN .= " tmp-$objbase.c";
Packit 5c3484
	open(TMP_C,">tmp-$objbase.c")
Packit 5c3484
	    or die "Can't create tmp-$objbase.c: $!\n";
Packit 5c3484
	print TMP_C
Packit 5c3484
"/* tmp-$objbase.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */
Packit 5c3484
Packit 5c3484
#include \"gmp.h\"
Packit 5c3484
#include \"gmp-impl.h\"
Packit 5c3484
#include \"longlong.h\"
Packit 5c3484
#include \"speed.h\"
Packit 5c3484
Packit 5c3484
";
Packit 5c3484
      }
Packit 5c3484
Packit 5c3484
      my $tests_program = "$top_srcdir/tests/devel/$obj.c";
Packit 5c3484
      if (-f $tests_program) {
Packit 5c3484
	$tests_program = "\$(top_srcdir)/tests/devel/$obj.c";
Packit 5c3484
	print_ansi2knr("tests_${objbase}",
Packit 5c3484
		       $tests_program,
Packit 5c3484
		       "\\\n$renaming\t\t\$(CFLAGS_TESTS_SP)");
Packit 5c3484
	print_ansi2knr("tests_${objbase}_sp",
Packit 5c3484
		       $tests_program,
Packit 5c3484
		       "\\\n$renaming\t\t\$(CFLAGS_TESTS_SP)");
Packit 5c3484
Packit 5c3484
	print MAKEFILE <
Packit 5c3484
tests_$objbase.o: $tests_program
Packit 5c3484
	\$(COMPILE) \$(CFLAGS_TESTS) \\
Packit 5c3484
$renaming		-c $tests_program -o tests_$objbase.o
Packit 5c3484
Packit 5c3484
tests_$objbase: $objbase\$U.o tests_$objbase\$U.o ../libgmp.la
Packit 5c3484
	\$(LINK) tests_$objbase\$U.o $objbase\$U.o ../libgmp.la -o tests_$objbase
Packit 5c3484
Packit 5c3484
tests_${objbase}_sp.o: $tests_program
Packit 5c3484
	\$(COMPILE) \$(CFLAGS_TESTS_SP) \\
Packit 5c3484
$renaming		-c $tests_program -o tests_${objbase}_sp.o
Packit 5c3484
Packit 5c3484
tests_${objbase}_sp: $objbase\$U.o tests_${objbase}_sp\$U.o ../libgmp.la
Packit 5c3484
	\$(LINK) tests_${objbase}_sp\$U.o $objbase\$U.o ../libgmp.la -o tests_${objbase}_sp
Packit 5c3484
Packit 5c3484
EOF
Packit 5c3484
        $CLEAN .= " tests_$objbase tests_${objbase}_sp";
Packit 5c3484
      }
Packit 5c3484
Packit 5c3484
      foreach my $fun (@{$funs}) {
Packit 5c3484
	print "fun $fun\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	if ($lang eq '.h') {
Packit 5c3484
          my $macro_before = $t->{'macro_before'};
Packit 5c3484
          $macro_before = "" if ! defined $macro_before;
Packit 5c3484
	  print TMP_C
Packit 5c3484
"$macro_before
Packit 5c3484
#undef $fun
Packit 5c3484
#include \"$file_full\"
Packit 5c3484
Packit 5c3484
";
Packit 5c3484
	}
Packit 5c3484
Packit 5c3484
	my $args = $t->{"args_$fun"};
Packit 5c3484
	if (! defined $args) { $args = $t->{'args'}; }
Packit 5c3484
	if (! defined $args) { die "Need args for $fun\n"; }
Packit 5c3484
	print "args $args\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	foreach my $carry (@$carrys) {
Packit 5c3484
	  print "carry $carry\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	  my $fun_carry = $fun;
Packit 5c3484
	  if (! ($fun_carry =~ s/_1/_1$carry/)) { $fun_carry = "$fun$carry"; }
Packit 5c3484
          print "fun_carry $fun_carry\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	  if ($lang =~ /\.(asm|S)/
Packit 5c3484
	      && ! grep(m"PROLOGUE\((.* )?$mpX$fun_carry[ ,)]",@file_contents)) {
Packit 5c3484
	    print "no PROLOGUE $mpX$fun_carry\n" if $opt{'t'};
Packit 5c3484
	    next;
Packit 5c3484
	  }
Packit 5c3484
	  if ($lang eq '.c'
Packit 5c3484
	      && ! grep(m"^(#define FUNCTION\s+)?$mpX$fun_carry\W", @file_contents)) {
Packit 5c3484
	    print "no mention of $mpX$fun_carry\n" if $opt{'t'};
Packit 5c3484
	    next;
Packit 5c3484
	  }
Packit 5c3484
	  if ($lang eq '.h'
Packit 5c3484
	      && ! grep(m"^#define $fun_carry\W", @file_contents)) {
Packit 5c3484
	    print "no mention of #define $fun_carry\n" if $opt{'t'};
Packit 5c3484
	    next;
Packit 5c3484
	  }
Packit 5c3484
Packit 5c3484
	  $count_functions++;
Packit 5c3484
Packit 5c3484
	  my $carryarg;
Packit 5c3484
	  if (defined $t->{'carryarg'}) { $carryarg = $t->{'carryarg'}; }
Packit 5c3484
	  if ($carry eq '')             { $carryarg = ''; }
Packit 5c3484
	  else                          { $carryarg = ', mp_limb_t carry'; }
Packit 5c3484
	  print "carryarg $carryarg\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	  my $funfull="$mpX${fun_carry}_$suffix$pic->{'suffix'}";
Packit 5c3484
	  print "funfull $funfull\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	  if ($lang ne '.h') {
Packit 5c3484
	    my $proto = "$t->{'ret'} $funfull _PROTO (($args$carryarg)); \\\n";
Packit 5c3484
	    $SPEED_EXTRA_PROTOS .= $proto;
Packit 5c3484
	    $TRY_EXTRA_PROTOS .= $proto;
Packit 5c3484
	  }
Packit 5c3484
Packit 5c3484
	  my $try_type = $t->{"try-$fun"};
Packit 5c3484
	  $try_type = $t->{'try'} if ! defined $try_type;
Packit 5c3484
	  if (! defined $try_type) {
Packit 5c3484
	    if ($mpX eq 'mpn_') {
Packit 5c3484
	      $try_type = "TYPE_\U$fun_carry";
Packit 5c3484
	    } else {
Packit 5c3484
	      $try_type = "TYPE_\U$mpX\U$fun_carry";
Packit 5c3484
	    }
Packit 5c3484
	  }
Packit 5c3484
	  print "try_type $try_type\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	  my $try_minsize = $t->{'try-minsize'};
Packit 5c3484
	  if (defined $try_minsize) {
Packit 5c3484
	    $try_minsize = ", " . $try_minsize;
Packit 5c3484
	  } else {
Packit 5c3484
	    $try_minsize = "";
Packit 5c3484
	  }
Packit 5c3484
	  print "try_minsize $try_minsize\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	  if ($try_type ne 'none') {
Packit 5c3484
	    $TRY_EXTRA_ROUTINES .=
Packit 5c3484
		"  { TRY($mpX${fun_carry}_$suffix$pic->{'suffix'}), $try_type$try_minsize }, \\\n";
Packit 5c3484
	  }
Packit 5c3484
Packit 5c3484
	  my $speed_flags = $t->{'speed_flags'};
Packit 5c3484
	  $speed_flags = '0' if ! defined $speed_flags;
Packit 5c3484
	  print "speed_flags $speed_flags\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	  my $speed_routine = $t->{'speed'};
Packit 5c3484
	  $speed_routine = "SPEED_ROUTINE_\U$mpX\U$fun"
Packit 5c3484
	      if !defined $speed_routine;
Packit 5c3484
	  if (! ($speed_routine =~ s/_1/_1\U$carry/)) {
Packit 5c3484
	    $speed_routine = "$speed_routine\U$carry";
Packit 5c3484
	  }
Packit 5c3484
	  print "speed_routine $speed_routine\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
	  my @speed_suffixes = ();
Packit 5c3484
	  push (@speed_suffixes, '') if $speed_routine ne 'none';
Packit 5c3484
	  push (@speed_suffixes, @{$t->{'speed_suffixes'}})
Packit 5c3484
	      if defined $t->{'speed_suffixes'};
Packit 5c3484
Packit 5c3484
          my $macro_speed = $t->{'macro-speed'};
Packit 5c3484
          $macro_speed = "$speed_routine ($fun_carry)" if ! defined $macro_speed;
Packit 5c3484
          $macro_speed =~ s/\$fun/$fun_carry/g;
Packit 5c3484
Packit 5c3484
	  foreach my $S (@speed_suffixes) {
Packit 5c3484
	    my $Sfunfull="$mpX${fun_carry}${S}_$suffix$pic->{'suffix'}";
Packit 5c3484
Packit 5c3484
	    $SPEED_EXTRA_PROTOS .=
Packit 5c3484
	      "double speed_$Sfunfull _PROTO ((struct speed_params *s)); \\\n";
Packit 5c3484
	    $SPEED_EXTRA_ROUTINES .=
Packit 5c3484
	      "  { \"$Sfunfull\", speed_$Sfunfull, $speed_flags }, \\\n";
Packit 5c3484
	    if ($lang eq '.h') {
Packit 5c3484
              print TMP_C
Packit 5c3484
"double
Packit 5c3484
speed_$Sfunfull (struct speed_params *s)
Packit 5c3484
{
Packit 5c3484
$macro_speed
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
";
Packit 5c3484
            } else {
Packit 5c3484
	      $SPEED_CODE .=
Packit 5c3484
	        "double\n" .
Packit 5c3484
	        "speed_$Sfunfull (struct speed_params *s)\n" .
Packit 5c3484
                "{\n" .
Packit 5c3484
                "$restriction" .
Packit 5c3484
	        "  $speed_routine\U$S\E ($funfull)\n" .
Packit 5c3484
                "}\n";
Packit 5c3484
            }
Packit 5c3484
	  }
Packit 5c3484
	}
Packit 5c3484
      }
Packit 5c3484
    }
Packit 5c3484
  }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
print SPEED $SPEED_EXTRA_PROTOS . "\n";
Packit 5c3484
print SPEED $SPEED_EXTRA_ROUTINES . "\n";
Packit 5c3484
if (defined $ENV{speedinc}) { print SPEED $ENV{speedinc} . "\n"; }
Packit 5c3484
print SPEED
Packit 5c3484
    "#include \"speed.c\"\n" .
Packit 5c3484
    "\n";
Packit 5c3484
print SPEED $SPEED_CODE;
Packit 5c3484
Packit 5c3484
print TRY $TRY_EXTRA_ROUTINES . "\n";
Packit 5c3484
print TRY $TRY_EXTRA_PROTOS . "\n";
Packit 5c3484
my $tryinc = "";
Packit 5c3484
if (defined $ENV{tryinc}) {
Packit 5c3484
  $tryinc = $ENV{tryinc};
Packit 5c3484
  print TRY "#include \"$tryinc\"\n";
Packit 5c3484
}
Packit 5c3484
print "tryinc $tryinc\n" if $opt{'t'};
Packit 5c3484
print TRY
Packit 5c3484
    "#include \"try.c\"\n" .
Packit 5c3484
    "\n";
Packit 5c3484
Packit 5c3484
my $extra_libraries = "";
Packit 5c3484
if (defined $ENV{extra_libraries}) { $extra_libraries = $ENV{extra_libraries};}
Packit 5c3484
Packit 5c3484
my $trydeps = "";
Packit 5c3484
if (defined $ENV{trydeps}) { $trydeps = $ENV{trydeps}; }
Packit 5c3484
$trydeps .= " $tryinc";
Packit 5c3484
print "trydeps $trydeps\n" if $opt{'t'};
Packit 5c3484
Packit 5c3484
print MAKEFILE <
Packit 5c3484
Packit 5c3484
MANY_OBJS = $MANY_OBJS
Packit 5c3484
MANY_CLEAN = \$(MANY_OBJS) \\
Packit 5c3484
	speed-many.c speed-many\$U.o speed-many\$(EXEEXT) \\
Packit 5c3484
	try-many.c try-many\$U.o try-many \\
Packit 5c3484
	$CLEAN
Packit 5c3484
MANY_DISTCLEAN = Makefile.many
Packit 5c3484
Packit 5c3484
speed-many: \$(MANY_OBJS) speed-many\$U.o libspeed.la $extra_libraries
Packit 5c3484
	\$(LINK) \$(LDFLAGS) speed-many\$U.o \$(MANY_OBJS) \$(LDADD) \$(LIBS) $extra_libraries
Packit 5c3484
Packit 5c3484
try-many: \$(MANY_OBJS) try-many\$U.o libspeed.la $extra_libraries
Packit 5c3484
	\$(LINK) \$(LDFLAGS) try-many\$U.o \$(MANY_OBJS)  \$(LDADD) \$(LIBS) $extra_libraries
Packit 5c3484
Packit 5c3484
try-many.o: try-many.c \$(top_srcdir)/tests/devel/try.c $trydeps
Packit 5c3484
	\$(COMPILE) -I\$(top_srcdir)/tests/devel -c try-many.c
Packit 5c3484
Packit 5c3484
EOF
Packit 5c3484
Packit 5c3484
print_ansi2knr("speed-many");
Packit 5c3484
print_ansi2knr("try-many",
Packit 5c3484
	       "\$(top_srcdir)/tests/devel/try.c",
Packit 5c3484
	       "-I\$(top_srcdir)/tests/devel");
Packit 5c3484
Packit 5c3484
print MAKEFILE <
Packit 5c3484
RM_TMP = rm -f
Packit 5c3484
CFLAGS_TESTS = -DSIZE=50 -DTIMES=1 -DRANDOM -DCLOCK=333000000
Packit 5c3484
CFLAGS_TESTS_SP = -DSIZE=1024 -DNOCHECK -DOPS=200000000 -DCLOCK=333000000
Packit 5c3484
EOF
Packit 5c3484
Packit 5c3484
close MAKEFILE or die;
Packit 5c3484
Packit 5c3484
print "Total $count_files files, $count_functions functions\n";
Packit 5c3484
Packit 5c3484
Packit 5c3484
Packit 5c3484
# Local variables:
Packit 5c3484
# perl-indent-level: 2
Packit 5c3484
# End: