Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
itgen.c
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 #include <stdio.h>
00037 #include <math.h>
00038 #include <signal.h>
00039 #include "arith.internal.h"
00040 
00041 #define uint32  unsigned long
00042 #define float64 double
00043 #define float32 float
00044 #define sqrt64 sqrt
00045 #define log64 log
00046 #define exp64 exp
00047 #define pow64 pow
00048 
00049 #ifdef __svr4__
00050 extern void cdiv32_ ();
00051 extern void cdiv64_ ();
00052 #endif
00053 
00054 /* Trap floating-point exceptions and set a flag */
00055 static volatile int fp_error = AR_STAT_OK;
00056 void
00057 fperr (int sig) {
00058 
00059         fp_error = AR_STAT_UNDEFINED;
00060         signal (SIGFPE, fperr);
00061 
00062 }
00063 
00064 /* Prevent printing of math library error message */
00065 int matherr (struct exception *X) {
00066         return 1;
00067 }
00068 
00069 
00070 /* Big-endian 64-bit IEEE FP - sign, expo, upper 20 bits of coeff, lower 32 */
00071 #define V(sign,expo,c0,c1)      ((uint32)(sign)<<31) | ((uint32)(expo)<<20) | (c0), (c1),
00072 
00073 static uint32 t64vals [] = {
00074 
00075         V(0,0,0,0)
00076         V(1,0,0,0)
00077         V(0,01777,0,0)
00078         V(1,01777,0,0)
00079         V(0,01777,02000000,0)
00080         V(1,01777,02000000,0)
00081         V(0,01777,0,1)
00082         V(1,01777,0,1)
00083         V(0,01777,03777777,037777777777)
00084         V(1,01777,03777777,037777777777)
00085         V(0,01776,03777777,037777777777)
00086         V(1,01776,03777777,037777777777)
00087         V(0,02064,0,0)
00088         V(1,02064,0,0)
00089         V(0,01710,0,0)
00090         V(1,01710,0,0)
00091         V(0,02064,03777777,037777777777)
00092         V(1,02064,03777777,037777777777)
00093         V(0,01710,03777777,037777777777)
00094         V(1,01710,03777777,037777777777)
00095         V(0,1,0,0)
00096         V(1,1,0,0)
00097         V(0,03776,0,0)
00098         V(1,03776,0,0)
00099         V(0,03776,03777777,037777777777)
00100         V(1,03776,03777777,037777777777)
00101         V(0,03777,0,0)
00102         V(1,03777,0,0)
00103         V(0,03777,03777777,037777777777)
00104         V(1,03777,03777777,037777777777)
00105         V(0,0,02000000,0)
00106         V(1,0,02000000,0)
00107         V(0,0,0,1)
00108         V(1,0,0,1)
00109         V(0,0,00123400,0)
00110 
00111         0       /* must be last */
00112 };
00113 
00114 #undef V
00115 
00116 
00117 /* Big-endian 32-bit IEEE FP - sign, expo, coeff */
00118 #define V(sign,expo,coeff)      ((uint32)(sign)<<31) | ((uint32)(expo)<<23) | (coeff),
00119 
00120 static uint32 t32vals [] = {
00121 
00122         V(0,0,0)
00123         V(1,0,0)
00124         V(0,0177,0)
00125         V(1,0177,0)
00126         V(0,0177,020000000)
00127         V(1,0177,020000000)
00128         V(0,0177,0)
00129         V(1,0177,0)
00130         V(0,0177,037777777)
00131         V(1,0177,037777777)
00132         V(0,0176,037777777)
00133         V(1,0176,037777777)
00134         V(0,0264,0)
00135         V(1,0264,0)
00136         V(0,0110,0)
00137         V(1,0110,0)
00138         V(0,0264,037777777)
00139         V(1,0264,037777777)
00140         V(0,0110,037777777)
00141         V(1,0110,037777777)
00142         V(0,1,0)
00143         V(1,1,0)
00144         V(0,0376,0)
00145         V(1,0376,0)
00146         V(0,0376,037777777)
00147         V(1,0376,037777777)
00148         V(0,0377,0)
00149         V(1,0377,0)
00150         V(0,0377,037777777)
00151         V(1,0377,037777777)
00152         V(0,0,020000000)
00153         V(1,0,020000000)
00154         V(0,0,0)
00155         V(1,0,0)
00156         V(0,0,001234000)
00157 
00158         0       /* must be last */
00159 
00160 };
00161 
00162 #undef V
00163 
00164 
00165 static
00166 float64
00167 fadd64 (float64 x, float64 y) {
00168         return x + y;
00169 }
00170 
00171 static
00172 float64
00173 fsub64 (float64 x, float64 y) {
00174         return x - y;
00175 }
00176 
00177 static
00178 float64
00179 fmul64 (float64 x, float64 y) {
00180         return x * y;
00181 }
00182 
00183 static
00184 float64
00185 fdiv64 (float64 x, float64 y) {
00186         return x / y;
00187 }
00188 
00189 static
00190 float64
00191 fcmp64 (float64 x, float64 y) {
00192         if(isnan(x) || isnan(y)) {
00193                 fp_error = AR_STAT_UNDEFINED;
00194                 return -2.0;
00195         }
00196         if(x==y)
00197                 return 0;
00198         if(x<y)
00199                 return -1.0;
00200         return 1.0;
00201 }
00202 
00203 static
00204 float32
00205 fadd32 (float32 x, float32 y) {
00206         return x + y;
00207 }
00208 
00209 static
00210 float32
00211 fsub32 (float32 x, float32 y) {
00212         return x - y;
00213 }
00214 
00215 static
00216 float32
00217 fmul32 (float32 x, float32 y) {
00218         return x * y;
00219 }
00220 
00221 static
00222 float32
00223 fdiv32 (float32 x, float32 y) {
00224         return x / y;
00225 }
00226 
00227 static
00228 float32
00229 fcmp32 (float32 x, float32 y) {
00230         if(isnan(x) || isnan(y)) {
00231                 fp_error = AR_STAT_UNDEFINED;
00232                 return -2.0;
00233         }
00234         if(x==y)
00235                 return 0;
00236         if(x<y)
00237                 return -1.0;
00238         return 1.0;
00239 }
00240 
00241 static
00242 float64
00243 f32to64 (float32 x) {
00244         return x;
00245 }
00246 
00247 static
00248 float32
00249 f64to32 (float64 x) {
00250         return x;
00251 }
00252 
00253 
00254 static
00255 prieee64 (FILE *fp, float64 val) {
00256         union { uint32 lv [2]; float64 fv; } u;
00257         u.fv = val;
00258         fprintf (fp, " %011lo%o%010lo",
00259                  u.lv [0] >> 1,
00260                  ((u.lv [0] & 1) << 2) | (u.lv [1] >> 30),
00261                  u.lv [1] & 07777777777);
00262 }
00263 
00264 
00265 static
00266 prieee32 (FILE *fp, float32 val) {
00267         union { uint32 lv; float32 fv; } u;
00268         u.fv = val;
00269         fprintf (fp, " %011lo", u.lv);
00270 }
00271 
00272 
00273 static
00274 setstat64 (float64 val) {
00275         union { uint32 lv [2]; float64 fv; } u;
00276         u.fv = val;
00277         if (val == (1.0/0.0) || val == (-1.0/0.0))
00278                 fp_error |= AR_STAT_OVERFLOW;
00279         if (isnan (val))
00280                 fp_error |= AR_STAT_UNDEFINED;
00281         else if (!(u.lv [0] | u.lv [1]))
00282                 fp_error |= AR_STAT_ZERO;
00283         else if (!-val)
00284                 fp_error |= AR_STAT_ZERO | AR_STAT_NEGATIVE;
00285         else if (val < 0)
00286                 fp_error |= AR_STAT_NEGATIVE;
00287 }
00288 
00289 
00290 static
00291 setstat32 (float32 val) {
00292         union { uint32 lv; float32 fv; } u;
00293         u.fv = val;
00294         if (val == (1.0/0.0) || val == (-1.0/0.0))
00295                 fp_error |= AR_STAT_OVERFLOW;
00296         if (isnan (val))
00297                 fp_error |= AR_STAT_UNDEFINED;
00298         else if (!u.lv)
00299                 fp_error |= AR_STAT_ZERO;
00300         else if (!-val)
00301                 fp_error |= AR_STAT_ZERO | AR_STAT_NEGATIVE;
00302         else if (val < 0)
00303                 fp_error |= AR_STAT_NEGATIVE;
00304 }
00305 
00306 
00307 dotest64_2 (char *fn, float64 (*op)(float64, float64)) {
00308 
00309         int i, j;
00310         union { uint32 lv [2]; float64 fv; } u;
00311         float64 x, y, z;
00312         FILE *fp = fopen (fn, "w");
00313 
00314         if (!fp) {
00315                 fprintf (stderr, "can't open %s\n", fn);
00316                 exit (1);
00317         }
00318 
00319         for (i = 0; !i || t64vals [i]; i++) {
00320                 u.lv [0] = t64vals [i++];
00321                 u.lv [1] = t64vals [i];
00322                 x = u.fv;
00323                 for (j = 0; !j || t64vals [j]; j++) {
00324                         u.lv [0] = t64vals [j++];
00325                         u.lv [1] = t64vals [j];
00326                         y = u.fv;
00327                         z = op (x, y);
00328                         setstat64 (z);
00329                         fprintf (fp, "$t");
00330                         prieee64 (fp, x);
00331                         prieee64 (fp, y);
00332                         prieee64 (fp, z);
00333                         fprintf (fp, " %o\n", fp_error);
00334                         fp_error = AR_STAT_OK;
00335                 }
00336         }
00337 
00338         fclose (fp);
00339 }
00340 
00341 
00342 dotest64_2c (char *fn, void (*op)(float64*, float64*, float64*)) {
00343 
00344         int i, j;
00345         int save_status;
00346         union { uint32 lv [2]; float64 fv; } u;
00347         float64 x[2], y[2], z[2];
00348         FILE *fp = fopen (fn, "w");
00349 
00350         if (!fp) {
00351                 fprintf (stderr, "can't open %s\n", fn);
00352                 exit (1);
00353         }
00354 
00355         for (i = 0; !i || t64vals [i]; i++) {
00356                 u.lv [0] = t64vals [i++];
00357                 u.lv [1] = t64vals [i];
00358                 x[0] = u.fv;
00359                 x[1] = u.fv*(4.0-(i&7));
00360                 for (j = 0; !j || t64vals [j]; j++) {
00361                         u.lv [0] = t64vals [j++];
00362                         u.lv [1] = t64vals [j];
00363                         y[0] = u.fv;
00364                         y[1] = u.fv*((i*3)-2.0);
00365                         op (z, x, y);
00366                         setstat64 (z[0]);
00367                         save_status = fp_error;
00368                         setstat64 (z[1]);
00369                         save_status &= fp_error&AR_STAT_ZERO;
00370                         fp_error = save_status | (fp_error&(
00371                                    (AR_STAT_OVERFLOW | AR_STAT_UNDEFINED |
00372                                     AR_STAT_UNDERFLOW | AR_STAT_INVALID_TYPE)));
00373                         fprintf (fp, "$t");
00374                         prieee64 (fp, x[0]);
00375                         prieee64 (fp, x[1]);
00376                         prieee64 (fp, y[0]);
00377                         prieee64 (fp, y[1]);
00378                         prieee64 (fp, z[0]);
00379                         prieee64 (fp, z[1]);
00380                         fprintf (fp, " %o\n", fp_error);
00381                         fp_error = AR_STAT_OK;
00382                 }
00383         }
00384 
00385         fclose (fp);
00386 }
00387 
00388 
00389 
00390 dotest64_1 (char *fn, float64 (*op)(float64)) {
00391 
00392         int i, j;
00393         union { uint32 lv [2]; float64 fv; } u;
00394         float64 x, z;
00395         FILE *fp = fopen (fn, "w");
00396 
00397         if (!fp) {
00398                 fprintf (stderr, "can't open %s\n", fn);
00399                 exit (1);
00400         }
00401 
00402         for (i = 0; !i || t64vals [i]; i++) {
00403                 u.lv [0] = t64vals [i++];
00404                 u.lv [1] = t64vals [i];
00405                 x = u.fv;
00406                 z = op (x);
00407                 setstat64 (z);
00408                 fprintf (fp, "$t");
00409                 prieee64 (fp, x);
00410                 prieee64 (fp, z);
00411                 fprintf (fp, " %o\n", fp_error);
00412                 fp_error = AR_STAT_OK;
00413         }
00414 
00415         fclose (fp);
00416 }
00417 
00418 
00419 dotest64_1s (char *fn, float64 (*op)(float32)) {
00420 
00421         int i, j;
00422         union { uint32 lv; float64 fv; } u;
00423         float32 x;
00424         float64 z;
00425         FILE *fp = fopen (fn, "w");
00426 
00427         if (!fp) {
00428                 fprintf (stderr, "can't open %s\n", fn);
00429                 exit (1);
00430         }
00431 
00432         for (i = 0; !i || t32vals [i]; i++) {
00433                 u.lv = t32vals [i];
00434                 x = u.fv;
00435                 z = op (x);
00436                 setstat64 (z);
00437                 fprintf (fp, "$t");
00438                 prieee32 (fp, x);
00439                 prieee64 (fp, z);
00440                 fprintf (fp, " %o\n", fp_error);
00441                 fp_error = AR_STAT_OK;
00442         }
00443 
00444         fclose (fp);
00445 }
00446 
00447 
00448 dotest32_2 (char *fn, float32 (*op)(float32, float32)) {
00449 
00450         int i, j;
00451         union { uint32 lv; float32 fv; } u;
00452         float32 x, y, z;
00453         FILE *fp = fopen (fn, "w");
00454 
00455         if (!fp) {
00456                 fprintf (stderr, "can't open %s\n", fn);
00457                 exit (1);
00458         }
00459 
00460         for (i = 0; !i || t32vals [i]; i++) {
00461                 u.lv = t32vals [i];
00462                 x = u.fv;
00463                 for (j = 0; !j || t32vals [j]; j++) {
00464                         u.lv = t32vals [j];
00465                         y = u.fv;
00466                         z = op (x, y);
00467                         setstat32 (z);
00468                         fprintf (fp, "$t");
00469                         prieee32 (fp, x);
00470                         prieee32 (fp, y);
00471                         prieee32 (fp, z);
00472                         fprintf (fp, " %o\n", fp_error);
00473                         fp_error = AR_STAT_OK;
00474                 }
00475         }
00476 
00477         fclose (fp);
00478 }
00479 
00480 
00481 dotest32_2c (char *fn, void (*op)(float32*, float32*, float32*)) {
00482 
00483         int i, j;
00484         int save_status;
00485         union { uint32 lv; float32 fv; } u;
00486         float32 x[2], y[2], z[2];
00487         FILE *fp = fopen (fn, "w");
00488 
00489         if (!fp) {
00490                 fprintf (stderr, "can't open %s\n", fn);
00491                 exit (1);
00492         }
00493 
00494         for (i = 0; !i || t32vals [i]; i++) {
00495                 u.lv = t32vals [i];
00496                 x[0] = u.fv;
00497                 x[1] = -u.fv;
00498                 for (j = 0; !j || t32vals [j]; j++) {
00499                         u.lv = t32vals [j];
00500                         y[0] = u.fv-0.001;
00501                         y[1] = u.fv+0.01;
00502                         op (z, x, y);
00503                         setstat32 (z[0]);
00504                         save_status = fp_error;
00505                         fp_error &= ~AR_STAT_ZERO;
00506                         setstat32 (z[1]);
00507                         save_status &= fp_error&AR_STAT_ZERO;
00508                         fp_error = save_status | (fp_error&(
00509                                    (AR_STAT_OVERFLOW | AR_STAT_UNDEFINED |
00510                                     AR_STAT_UNDERFLOW | AR_STAT_INVALID_TYPE)));
00511                         fprintf (fp, "$t");
00512                         prieee32 (fp, x[0]);
00513                         prieee32 (fp, x[1]);
00514                         prieee32 (fp, y[0]);
00515                         prieee32 (fp, y[1]);
00516                         prieee32 (fp, z[0]);
00517                         prieee32 (fp, z[1]);
00518                         fprintf (fp, " %o\n", fp_error);
00519                         fp_error = AR_STAT_OK;
00520                 }
00521         }
00522 
00523         fclose (fp);
00524 }
00525 
00526 
00527 dotest32_1s (char *fn, float32 (*op)(float64)) {
00528 
00529         int i, j;
00530         union { uint32 lv [2]; float64 fv; } u;
00531         float64 x;
00532         float32 z;
00533         FILE *fp = fopen (fn, "w");
00534 
00535         if (!fp) {
00536                 fprintf (stderr, "can't open %s\n", fn);
00537                 exit (1);
00538         }
00539 
00540         for (i = 0; !i || t64vals [i]; i++) {
00541                 u.lv [0] = t64vals [i++];
00542                 u.lv [1] = t64vals [i];
00543                 x = u.fv;
00544                 z = op (x);
00545                 setstat32 (z);
00546                 fprintf (fp, "$t");
00547                 prieee64 (fp, x);
00548                 prieee32 (fp, z);
00549                 fprintf (fp, " %o\n", fp_error);
00550                 fp_error = AR_STAT_OK;
00551         }
00552 
00553         fclose (fp);
00554 }
00555 
00556 
00557 main () {
00558         signal (SIGFPE, fperr);
00559 
00560         dotest64_2 ("results/ieee_add64", fadd64);
00561         dotest64_2 ("results/ieee_sub64", fsub64);
00562         dotest64_2 ("results/ieee_mul64", fmul64);
00563         dotest64_2 ("results/ieee_div64", fdiv64);
00564         dotest64_2 ("results/ieee_cmp64", fcmp64);
00565         dotest64_1s ("results/ieee_32to64", f32to64);
00566         dotest32_2 ("results/ieee_add32", fadd32);
00567         dotest32_2 ("results/ieee_sub32", fsub32);
00568         dotest32_2 ("results/ieee_mul32", fmul32);
00569         dotest32_2 ("results/ieee_div32", fdiv32);
00570         dotest32_2 ("results/ieee_cmp32", fcmp32);
00571         dotest32_1s ("results/ieee_64to32", f64to32);
00572 
00573 #ifdef __svr4__
00574         dotest32_2c ("results/ieee_cdiv32", cdiv32_);
00575         dotest64_2c ("results/ieee_cdiv64", cdiv64_);
00576    #define U "_solaris"
00577 #else
00578    #define U "_sunOS"
00579 #endif
00580         dotest64_1 ("results/ieee_sqrt64" U, sqrt64);
00581         dotest64_1 ("results/ieee_log64" U, log64);
00582         dotest64_1 ("results/ieee_exp64" U, exp64);
00583         dotest64_2 ("results/ieee_powrr64" U, pow64);
00584 #undef U
00585 
00586         exit (0);
00587 }
00588 
00589 
00590 static char USMID [] = "\n%Z%%M%        %I%     %G% %U%\n";
00591 static char rcsid [] = "$Id: itgen.c,v 1.1.1.1 2002-05-22 20:06:19 dsystem Exp $";
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines