about summary refs log tree commit diff
path: root/math
diff options
context:
space:
mode:
Diffstat (limited to 'math')
-rw-r--r--math/README.libm-test107
-rwxr-xr-xmath/gen-libm-test.pl20
2 files changed, 121 insertions, 6 deletions
diff --git a/math/README.libm-test b/math/README.libm-test
new file mode 100644
index 0000000000..af07622ccd
--- /dev/null
+++ b/math/README.libm-test
@@ -0,0 +1,107 @@
+README for libm-test math test suite
+====================================
+
+The libm-test math test suite tests a number of function points of
+math functions in the GNU C library.  The following sections contain a
+brief overview.  Please note that the test drivers and the Perl script
+"gen-libm-test.pl" have some options.  A full list of options is
+available with --help (for the test drivers) and -h for
+"gen-libm-test.pl".
+
+
+What is tested?
+===============
+The tests just evaluate the functions at specified points and compare
+the results with precomputed values and the requirements of the ISO
+C99 standard.
+
+Besides testing the special values mandated by IEEE 754 (infinities,
+NaNs and minus zero), some more or less random values are tested.
+
+Files that are part of libm-test
+================================
+
+The main file is "libm-test.inc".  It is platform and floating point
+format independent.  The file must be preprocessed by the Perl script
+"gen-libm-test.pl".  The results are "libm-test.c" and a file
+"libm-test-ulps.h" with platform specific deltas.
+
+The test drivers test-double.c, test-float.c, test-ldouble.c test the
+normal double, float and long double implementation of libm.  The test
+drivers with an i in it (test-idouble.c, test-ifloat.c,
+test-ildoubl.c) test the corresponding inline functions (where
+available - otherwise they also test the real functions in libm).
+
+"gen-libm-test.pl" needs a platform specific files with ULPs (Units of
+Last Precision).  The file is called "libm-test-ulps" and lives in
+platform specific sysdep directory.
+
+How can I generate "libm-test-ulps"?
+====================================
+
+The test drivers have an option "-u" to output an unsorted list of all
+epsilons that the functions have.  The output can be read in directly
+but it's better to pretty print it first.  "gen-libm-test.pl"  has an option
+to generate a pretty-printed and sorted new ULPs file from the output
+of the test drivers.
+
+To generate a new "libm-test-ulps" file, you can execute for example:
+test-double -u --ignore-max-ulp=yes
+This generates a file "ULPs" with all double ULPs in it, ignoring any
+previous calculated ULPs.
+Now move this away, e.g. "mv ULPs allULPs" and generate the ULPs
+for all other formats and concat all ULP files together (e.g. "cat
+ULPs >> allULPs").  As final step run "gen-libm-test.pl" with the file
+as input and ask to generate a pretty printed output in the file "NewUlps":
+  gen-libm-test.pl -u allULPs -n
+
+Now you can rename "NewUlps" to "libm-test-ulps" and move it into
+sysdeps.
+
+Contents of libm-test-ulps
+==========================
+Since libm-test-ulps can be generated automatically, just a few
+notes.  The file contains lines for single tests, like:
+Test "cos (pi/2) == 0":
+float:  1
+
+and lines for maximal errors of single functions, like:
+Function "yn":
+idouble:  6.0000
+
+The keywords are float, ifloat, double, idouble, ldouble and ildouble
+(the prefix i stands for inline).  You can also specify known
+failures, e.g.:
+
+Test "cos (pi/2) == 0":
+float:  1
+float: fail
+
+Adding tests to libm-test.inc
+=============================
+
+The tests are evaluated by a set of special test macros.  The macros
+start with "TEST_" followed by a specification the input values, an
+underscore and a specification of the output values.  As an example,
+the test macro for a function with input of type FLOAT (FLOAT is
+either float, double, long double) and output of type FLOAT is
+"TEST_f_f".  The macro's parameter are the name of the function, the
+input parameter, output parameter and optionally one exception
+parameter.
+
+The accepted parameter types are:
+- "f" for FLOAT
+- "b" for boolean - just tests if the output parameter evaluates to 0
+  or 1 (only for output).
+- "c" for complex.  This parameter needs two values, first the real,
+  then the imaginary part.
+- "i" for int.
+- "l" for long int.
+- "L" for long long int.
+- "F" for the address of a FLOAT (only as input parameter)
+- "I" for the address of an int (only as input parameter)
+
+Some functions need special handling.  For example gamma sets the
+global variable signgam and frexp takes an argument to &int.  This
+special treatment is coded in "gen-libm-test.pl" and used while
+parsing "libm-test.inc".
diff --git a/math/gen-libm-test.pl b/math/gen-libm-test.pl
index d380bbfe38..1237e51021 100755
--- a/math/gen-libm-test.pl
+++ b/math/gen-libm-test.pl
@@ -23,6 +23,8 @@
 # Note that functions and tests share the same namespace.
 
 # Information about tests are stored in: %results
+# $results{$test}{"kind"} is either "fct" or "test" and flags whether this
+# is a maximal error of a function or a single test.
 # $results{$test}{"type"} is the result type, e.g. normal or complex.
 # $results{$test}{"has_ulps"} is set if deltas exist.
 # $results{$test}{"has_fails"} is set if exptected failures exist.
@@ -102,7 +104,7 @@ if ($opt_h) {
   print "Usage: gen-libm-test.pl [OPTIONS]\n";
   print " -h         print this help, then exit\n";
   print " -o DIR     directory where generated files will be placed\n";
-  print " -n         generate sorted file NewUlps from libm-test-ulps\n";
+  print " -n         only generate sorted file NewUlps from libm-test-ulps\n";
   print " -u FILE    input file with ulps\n";
   exit 0;
 }
@@ -116,8 +118,8 @@ $output = "${output_dir}libm-test.c";
 $count = 0;
 
 &parse_ulps ($ulps_file);
-&generate_testfile ($input, $output);
-&output_ulps ("${output_dir}libm-test-ulps.h", $ulps_file);
+&generate_testfile ($input, $output) unless ($opt_n);
+&output_ulps ("${output_dir}libm-test-ulps.h", $ulps_file) unless ($opt_n);
 &print_ulps_file ("${output_dir}NewUlps") if ($opt_n);
 
 # Return a nicer representation
@@ -484,7 +486,7 @@ sub generate_testfile {
 # Parse ulps file
 sub parse_ulps {
   my ($file) = @_;
-  my ($test, $type, $float, $eps);
+  my ($test, $type, $float, $eps, $kind);
 
   # $type has the following values:
   # "normal": No complex variable
@@ -508,6 +510,7 @@ sub parse_ulps {
       }
       s/^.+\"(.*)\".*$/$1/;
       $test = $_;
+      $kind = 'test';
       next;
     }
     if (/^Function: /) {
@@ -521,6 +524,7 @@ sub parse_ulps {
 	$type = 'normal';
       }
       ($test) = ($_ =~ /^Function:\s*\"([a-zA-Z0-9_]+)\"/);
+      $kind = 'fct';
       next;
     }
     if (/^i?(float|double|ldouble):/) {
@@ -541,6 +545,7 @@ sub parse_ulps {
       } elsif ($type eq 'normal') {
 	$results{$test}{'type'} = 'normal';
       }
+      $results{$test}{'kind'} = $kind;
       next;
     }
     print "Skipping unknown entry: `$_'\n";
@@ -567,7 +572,9 @@ sub print_ulps_file {
   $last_fct = '';
   open NEWULP, ">$file" or die ("Can't open $file: $!");
   print NEWULP "# Begin of automatic generation\n";
-  foreach $test (sort @tests) {
+  # first the function calls
+  foreach $test (sort keys %results) {
+    next if ($results{$test}{'kind'} ne 'test');
     foreach $type ('real', 'imag', 'normal') {
       if (exists $results{$test}{$type}) {
 	if (defined $results{$test}) {
@@ -599,7 +606,8 @@ sub print_ulps_file {
   }
   print NEWULP "\n# Maximal error of functions:\n";
 
-  foreach $fct (sort @functions) {
+  foreach $fct (sort keys %results) {
+    next if ($results{$fct}{'kind'} ne 'fct');
     foreach $type ('real', 'imag', 'normal') {
       if (exists $results{$fct}{$type}) {
 	if ($type eq 'normal') {