diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/config/sh/divtab.c | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/config/sh/divtab.c')
-rw-r--r-- | gcc/config/sh/divtab.c | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/gcc/config/sh/divtab.c b/gcc/config/sh/divtab.c new file mode 100644 index 000000000..f8db2f508 --- /dev/null +++ b/gcc/config/sh/divtab.c @@ -0,0 +1,200 @@ +/* Copyright (C) 2003, 2009 Free Software Foundation, Inc. + +This file is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This file is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + + +/* Calculate division table for SH5Media integer division + Contributed by Joern Rennecke + joern.rennecke@superh.com */ + +#include <stdio.h> +#include <math.h> + +#define BITS 5 +#define N_ENTRIES (1 << BITS) +#define CUTOFF_BITS 20 + +#define BIAS (-330) + +double max_defect = 0.; +double max_defect_x; + +double min_defect = 1e9; +double min_defect_x; + +double max_defect2 = 0.; +double max_defect2_x; + +double min_defect2 = 0.; +double min_defect2_x; + +double min_defect3 = 01e9; +double min_defect3_x; +int min_defect3_val; + +double max_defect3 = 0.; +double max_defect3_x; +int max_defect3_val; + +static double note_defect3 (int val, double d2, double y2d, double x) +{ + int cutoff_val = val >> CUTOFF_BITS; + double cutoff; + double defect; + + if (val < 0) + cutoff_val++; + cutoff = (cutoff_val * (1<<CUTOFF_BITS) - val) * y2d; + defect = cutoff + val * d2; + if (val < 0) + defect = - defect; + if (defect > max_defect3) + { + max_defect3 = defect; + max_defect3_x = x; + max_defect3_val = val; + } + if (defect < min_defect3) + { + min_defect3 = defect; + min_defect3_x = x; + min_defect3_val = val; + } +} + +/* This function assumes 32-bit integers. */ +static double +calc_defect (double x, int constant, int factor) +{ + double y0 = (constant - (int) floor ((x * factor * 64.))) / 16384.; + double y1 = 2 * y0 -y0 * y0 * (x + BIAS / (1.*(1LL<<30))); + double y2d0, y2d; + int y2d1; + double d, d2; + + y1 = floor (y1 * (1024 * 1024 * 1024)) / (1024 * 1024 * 1024); + d = y1 - 1 / x; + if (d > max_defect) + { + max_defect = d; + max_defect_x = x; + } + if (d < min_defect) + { + min_defect = d; + min_defect_x = x; + } + y2d0 = floor (y1 * x * (1LL << 60-16)); + y2d1 = (int) (long long) y2d0; + y2d = - floor ((y1 - y0 / (1<<30-14)) * y2d1) / (1LL<<44); + d2 = y1 + y2d - 1/x; + if (d2 > max_defect2) + { + max_defect2 = d2; + max_defect2_x = x; + } + if (d2 < min_defect2) + { + min_defect2 = d2; + min_defect2_x = x; + } + /* zero times anything is trivially zero. */ + note_defect3 ((1 << CUTOFF_BITS) - 1, d2, y2d, x); + note_defect3 (1 << CUTOFF_BITS, d2, y2d, x); + note_defect3 ((1U << 31) - (1 << CUTOFF_BITS), d2, y2d, x); + note_defect3 ((1U << 31) - 1, d2, y2d, x); + note_defect3 (-1, d2, y2d, x); + note_defect3 (-(1 << CUTOFF_BITS), d2, y2d, x); + note_defect3 ((1U << 31) - (1 << CUTOFF_BITS) + 1, d2, y2d, x); + note_defect3 (-(1U << 31), d2, y2d, x); + return d; +} + +int +main () +{ + int i; + unsigned char factors[N_ENTRIES]; + short constants[N_ENTRIES]; + int steps = N_ENTRIES / 2; + double step = 1. / steps; + double eps30 = 1. / (1024 * 1024 * 1024); + + for (i = 0; i < N_ENTRIES; i++) + { + double x_low = (i < steps ? 1. : -3.) + i * step; + double x_high = x_low + step - eps30; + double x_med; + int factor, constant; + double low_defect, med_defect, high_defect, max_defect; + + factor = (1./x_low- 1./x_high) / step * 256. + 0.5; + if (factor == 256) + factor = 255; + factors[i] = factor; + /* Use minimum of error function for x_med. */ + x_med = sqrt (256./factor); + if (x_low < 0) + x_med = - x_med; + low_defect = 1. / x_low + x_low * factor / 256.; + high_defect = 1. / x_high + x_high * factor / 256.; + med_defect = 1. / x_med + x_med * factor / 256.; + max_defect + = ((low_defect > high_defect) ^ (x_med < 0)) ? low_defect : high_defect; + constant = (med_defect + max_defect) * 0.5 * 16384. + 0.5; + if (constant < -32768 || constant > 32767) + abort (); + constants[i] = constant; + calc_defect (x_low, constant, factor); + calc_defect (x_med, constant, factor); + calc_defect (x_high, constant, factor); + } + printf ("/* This table has been generated by divtab.c .\n"); + printf ("Defects for bias %d:\n", BIAS); + printf (" Max defect: %e at %e\n", max_defect, max_defect_x); + printf (" Min defect: %e at %e\n", min_defect, min_defect_x); + printf (" Max 2nd step defect: %e at %e\n", max_defect2, max_defect2_x); + printf (" Min 2nd step defect: %e at %e\n", min_defect2, min_defect2_x); + printf (" Max div defect: %e at %d:%e\n", max_defect3, max_defect3_val, max_defect3_x); + printf (" Min div defect: %e at %d:%e\n", min_defect3, min_defect3_val, min_defect3_x); + printf (" Defect at 1: %e\n", + calc_defect (1., constants[0], factors[0])); + printf (" Defect at -2: %e */\n", + calc_defect (-2., constants[steps], factors[steps])); + printf ("\t.section\t.rodata\n"); + printf ("\t.balign 2\n"); + printf ("/* negative division constants */\n"); + for (i = steps; i < 2 * steps; i++) + printf ("\t.word\t%d\n", constants[i]); + printf ("/* negative division factors */\n"); + for (i = steps; i < 2*steps; i++) + printf ("\t.byte\t%d\n", factors[i]); + printf ("\t.skip %d\n", steps); + printf ("\t.global GLOBAL(div_table):\n"); + printf ("GLOBAL(div_table):\n"); + printf ("\t.skip %d\n", steps); + printf ("/* positive division factors */\n"); + for (i = 0; i < steps; i++) + printf ("\t.byte\t%d\n", factors[i]); + printf ("/* positive division constants */\n"); + for (i = 0; i < steps; i++) + printf ("\t.word\t%d\n", constants[i]); + exit (0); +} |