xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/sh/divtab.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1*8feb0f0bSmrg /* Copyright (C) 2003-2020 Free Software Foundation, Inc.
236ac495dSmrg 
336ac495dSmrg This file is free software; you can redistribute it and/or modify it
436ac495dSmrg under the terms of the GNU General Public License as published by the
536ac495dSmrg Free Software Foundation; either version 3, or (at your option) any
636ac495dSmrg later version.
736ac495dSmrg 
836ac495dSmrg This file is distributed in the hope that it will be useful, but
936ac495dSmrg WITHOUT ANY WARRANTY; without even the implied warranty of
1036ac495dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1136ac495dSmrg General Public License for more details.
1236ac495dSmrg 
1336ac495dSmrg Under Section 7 of GPL version 3, you are granted additional
1436ac495dSmrg permissions described in the GCC Runtime Library Exception, version
1536ac495dSmrg 3.1, as published by the Free Software Foundation.
1636ac495dSmrg 
1736ac495dSmrg You should have received a copy of the GNU General Public License and
1836ac495dSmrg a copy of the GCC Runtime Library Exception along with this program;
1936ac495dSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2036ac495dSmrg <http://www.gnu.org/licenses/>.  */
2136ac495dSmrg 
2236ac495dSmrg 
2336ac495dSmrg /* Calculate division table for SH5Media integer division
2436ac495dSmrg    Contributed by Joern Rennecke
2536ac495dSmrg    joern.rennecke@superh.com  */
2636ac495dSmrg 
2736ac495dSmrg #include <stdio.h>
2836ac495dSmrg #include <math.h>
2936ac495dSmrg 
3036ac495dSmrg #define BITS 5
3136ac495dSmrg #define N_ENTRIES (1 << BITS)
3236ac495dSmrg #define CUTOFF_BITS 20
3336ac495dSmrg 
3436ac495dSmrg #define BIAS (-330)
3536ac495dSmrg 
3636ac495dSmrg double max_defect = 0.;
3736ac495dSmrg double max_defect_x;
3836ac495dSmrg 
3936ac495dSmrg double min_defect = 1e9;
4036ac495dSmrg double min_defect_x;
4136ac495dSmrg 
4236ac495dSmrg double max_defect2 = 0.;
4336ac495dSmrg double max_defect2_x;
4436ac495dSmrg 
4536ac495dSmrg double min_defect2 = 0.;
4636ac495dSmrg double min_defect2_x;
4736ac495dSmrg 
4836ac495dSmrg double min_defect3 = 01e9;
4936ac495dSmrg double min_defect3_x;
5036ac495dSmrg int min_defect3_val;
5136ac495dSmrg 
5236ac495dSmrg double max_defect3 = 0.;
5336ac495dSmrg double max_defect3_x;
5436ac495dSmrg int max_defect3_val;
5536ac495dSmrg 
5636ac495dSmrg static double
note_defect3(int val,double d2,double y2d,double x)5736ac495dSmrg note_defect3 (int val, double d2, double y2d, double x)
5836ac495dSmrg {
5936ac495dSmrg   int cutoff_val = val >> CUTOFF_BITS;
6036ac495dSmrg   double cutoff;
6136ac495dSmrg   double defect;
6236ac495dSmrg 
6336ac495dSmrg   if (val < 0)
6436ac495dSmrg     cutoff_val++;
6536ac495dSmrg   cutoff = (cutoff_val * (1<<CUTOFF_BITS) - val) * y2d;
6636ac495dSmrg   defect = cutoff + val * d2;
6736ac495dSmrg   if (val < 0)
6836ac495dSmrg     defect = - defect;
6936ac495dSmrg   if (defect > max_defect3)
7036ac495dSmrg     {
7136ac495dSmrg       max_defect3 = defect;
7236ac495dSmrg       max_defect3_x = x;
7336ac495dSmrg       max_defect3_val = val;
7436ac495dSmrg     }
7536ac495dSmrg   if (defect < min_defect3)
7636ac495dSmrg     {
7736ac495dSmrg       min_defect3 = defect;
7836ac495dSmrg       min_defect3_x = x;
7936ac495dSmrg       min_defect3_val = val;
8036ac495dSmrg     }
8136ac495dSmrg }
8236ac495dSmrg 
8336ac495dSmrg /* This function assumes 32-bit integers.  */
8436ac495dSmrg static double
calc_defect(double x,int constant,int factor)8536ac495dSmrg calc_defect (double x, int constant, int factor)
8636ac495dSmrg {
8736ac495dSmrg   double y0 = (constant - (int) floor ((x * factor * 64.))) / 16384.;
8836ac495dSmrg   double y1 = 2 * y0 -y0 * y0 * (x + BIAS / (1.*(1LL<<30)));
8936ac495dSmrg   double y2d0, y2d;
9036ac495dSmrg   int y2d1;
9136ac495dSmrg   double d, d2;
9236ac495dSmrg 
9336ac495dSmrg   y1 = floor (y1 * (1024 * 1024 * 1024)) / (1024 * 1024 * 1024);
9436ac495dSmrg   d = y1 - 1 / x;
9536ac495dSmrg   if (d > max_defect)
9636ac495dSmrg     {
9736ac495dSmrg       max_defect = d;
9836ac495dSmrg       max_defect_x = x;
9936ac495dSmrg     }
10036ac495dSmrg   if (d < min_defect)
10136ac495dSmrg     {
10236ac495dSmrg       min_defect = d;
10336ac495dSmrg       min_defect_x = x;
10436ac495dSmrg     }
10536ac495dSmrg   y2d0 = floor (y1 * x * (1LL << 60-16));
10636ac495dSmrg   y2d1 = (int) (long long) y2d0;
10736ac495dSmrg   y2d = - floor ((y1 - y0 / (1<<30-14)) * y2d1) / (1LL<<44);
10836ac495dSmrg   d2 = y1 + y2d - 1/x;
10936ac495dSmrg   if (d2 > max_defect2)
11036ac495dSmrg     {
11136ac495dSmrg       max_defect2 = d2;
11236ac495dSmrg       max_defect2_x = x;
11336ac495dSmrg     }
11436ac495dSmrg   if (d2 < min_defect2)
11536ac495dSmrg     {
11636ac495dSmrg       min_defect2 = d2;
11736ac495dSmrg       min_defect2_x = x;
11836ac495dSmrg     }
11936ac495dSmrg   /* zero times anything is trivially zero.  */
12036ac495dSmrg   note_defect3 ((1 << CUTOFF_BITS) - 1, d2, y2d, x);
12136ac495dSmrg   note_defect3 (1 << CUTOFF_BITS, d2, y2d, x);
12236ac495dSmrg   note_defect3 ((1U << 31) - (1 << CUTOFF_BITS), d2, y2d, x);
12336ac495dSmrg   note_defect3 ((1U << 31) - 1, d2, y2d, x);
12436ac495dSmrg   note_defect3 (-1, d2, y2d, x);
12536ac495dSmrg   note_defect3 (-(1 << CUTOFF_BITS), d2, y2d, x);
12636ac495dSmrg   note_defect3 ((1U << 31) - (1 << CUTOFF_BITS) + 1, d2, y2d, x);
12736ac495dSmrg   note_defect3 (-(1U << 31), d2, y2d, x);
12836ac495dSmrg   return d;
12936ac495dSmrg }
13036ac495dSmrg 
13136ac495dSmrg int
main()13236ac495dSmrg main ()
13336ac495dSmrg {
13436ac495dSmrg   int i;
13536ac495dSmrg   unsigned char factors[N_ENTRIES];
13636ac495dSmrg   short constants[N_ENTRIES];
13736ac495dSmrg   int steps = N_ENTRIES / 2;
13836ac495dSmrg   double step = 1. / steps;
13936ac495dSmrg   double eps30 = 1. / (1024 * 1024 * 1024);
14036ac495dSmrg 
14136ac495dSmrg   for (i = 0; i < N_ENTRIES; i++)
14236ac495dSmrg     {
14336ac495dSmrg       double x_low = (i < steps ? 1. : -3.) + i * step;
14436ac495dSmrg       double x_high = x_low + step - eps30;
14536ac495dSmrg       double x_med;
14636ac495dSmrg       int factor, constant;
14736ac495dSmrg       double low_defect, med_defect, high_defect, max_defect;
14836ac495dSmrg 
14936ac495dSmrg       factor = (1./x_low- 1./x_high) / step * 256. + 0.5;
15036ac495dSmrg       if (factor == 256)
15136ac495dSmrg 	factor = 255;
15236ac495dSmrg       factors[i] = factor;
15336ac495dSmrg       /* Use minimum of error function for x_med.  */
15436ac495dSmrg       x_med = sqrt (256./factor);
15536ac495dSmrg       if (x_low < 0)
15636ac495dSmrg 	x_med = - x_med;
15736ac495dSmrg       low_defect = 1. / x_low + x_low * factor / 256.;
15836ac495dSmrg       high_defect = 1. / x_high + x_high * factor / 256.;
15936ac495dSmrg       med_defect = 1. / x_med + x_med * factor / 256.;
16036ac495dSmrg       max_defect
16136ac495dSmrg 	= ((low_defect > high_defect) ^ (x_med < 0)) ? low_defect : high_defect;
16236ac495dSmrg       constant = (med_defect + max_defect) * 0.5 * 16384. + 0.5;
16336ac495dSmrg       if (constant < -32768 || constant > 32767)
16436ac495dSmrg 	abort ();
16536ac495dSmrg       constants[i] = constant;
16636ac495dSmrg       calc_defect (x_low, constant, factor);
16736ac495dSmrg       calc_defect (x_med, constant, factor);
16836ac495dSmrg       calc_defect (x_high, constant, factor);
16936ac495dSmrg     }
17036ac495dSmrg     printf ("/* This table has been generated by divtab.c .\n");
17136ac495dSmrg     printf ("Defects for bias %d:\n", BIAS);
17236ac495dSmrg     printf ("   Max defect: %e at %e\n", max_defect, max_defect_x);
17336ac495dSmrg     printf ("   Min defect: %e at %e\n", min_defect, min_defect_x);
17436ac495dSmrg     printf ("   Max 2nd step defect: %e at %e\n", max_defect2, max_defect2_x);
17536ac495dSmrg     printf ("   Min 2nd step defect: %e at %e\n", min_defect2, min_defect2_x);
17636ac495dSmrg     printf ("   Max div defect: %e at %d:%e\n", max_defect3, max_defect3_val,
17736ac495dSmrg 						max_defect3_x);
17836ac495dSmrg     printf ("   Min div defect: %e at %d:%e\n", min_defect3, min_defect3_val,
17936ac495dSmrg 						min_defect3_x);
18036ac495dSmrg     printf ("   Defect at 1: %e\n",
18136ac495dSmrg 	    calc_defect (1., constants[0], factors[0]));
18236ac495dSmrg     printf ("   Defect at -2: %e */\n",
18336ac495dSmrg 	    calc_defect (-2., constants[steps], factors[steps]));
18436ac495dSmrg     printf ("\t.section\t.rodata\n");
18536ac495dSmrg     printf ("\t.balign 2\n");
18636ac495dSmrg     printf ("/* negative division constants */\n");
18736ac495dSmrg     for (i = steps; i < 2 * steps; i++)
18836ac495dSmrg       printf ("\t.word\t%d\n", constants[i]);
18936ac495dSmrg     printf ("/* negative division factors */\n");
19036ac495dSmrg     for (i = steps; i < 2*steps; i++)
19136ac495dSmrg       printf ("\t.byte\t%d\n", factors[i]);
19236ac495dSmrg     printf ("\t.skip %d\n", steps);
19336ac495dSmrg     printf ("\t.global	GLOBAL(div_table):\n");
19436ac495dSmrg     printf ("GLOBAL(div_table):\n");
19536ac495dSmrg     printf ("\t.skip %d\n", steps);
19636ac495dSmrg     printf ("/* positive division factors */\n");
19736ac495dSmrg     for (i = 0; i < steps; i++)
19836ac495dSmrg       printf ("\t.byte\t%d\n", factors[i]);
19936ac495dSmrg     printf ("/* positive division constants */\n");
20036ac495dSmrg     for (i = 0; i < steps; i++)
20136ac495dSmrg       printf ("\t.word\t%d\n", constants[i]);
20236ac495dSmrg   exit (0);
20336ac495dSmrg }
204