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