many.pl
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:39k
源码类别:

数学计算

开发平台:

Unix_Linux

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