Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ctgen.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 /*
00037  *      Test generator for the Cray arithmetics
00038  */
00039 
00040 #include <stdio.h>
00041 #include <signal.h>
00042 #include <math.h>
00043 #include <setjmp.h>
00044 #include <complex.h>
00045 #include "arith.internal.h"
00046 
00047 
00048 /* Trap floating-point exceptions and set a flag */
00049 static volatile int fp_error = AR_STAT_OK;
00050 static int jmp_on_err = 0;
00051 static jmp_buf fperr_jmpbuf;
00052 void
00053 fperr (int sig) {
00054         fp_error |= AR_STAT_OVERFLOW;
00055         signal (sig, fperr);
00056         if (jmp_on_err)
00057                 longjmp (fperr_jmpbuf, 1);
00058 }
00059 
00060 void
00061 trapmathlibabort (void) {
00062         if (jmp_on_err) {
00063                 fp_error |= AR_STAT_UNDEFINED;
00064                 longjmp (fperr_jmpbuf, 1);
00065         }
00066         raise (SIGFPE);
00067 }
00068 
00069 
00070 /* "Interesting" 64-bit FP values */
00071 static unsigned long tvals [] = {
00072 
00073         00000000000000000000000,
00074         00400014000000000000000,
00075         01400014000000000000000,
00076         00400004000000000000000,
00077         01400004000000000000000,
00078         00400016000000000000000,
00079         01400016000000000000000,
00080         00400014000000000000001,
00081         01400014000000000000001,
00082         00200004000000000000000,
00083         00577774000000000000000,
00084         00600004000000000000000,
00085         00177774000000000000000,
00086         01200004000000000000000,
00087         01577774000000000000000,
00088         01600004000000000000000,
00089         01177774000000000000000,
00090         00400010000000000000001,
00091         01400010000000000000001,
00092         00400000000000000000001,
00093         01400000000000000000001,
00094         00200000000000000000001,
00095         00577770000000000000001,
00096         00600000000000000000001,
00097         00177770000000000000001,
00098         01200000000000000000001,
00099         01577770000000000000001,
00100         01600000000000000000001,
00101         01177770000000000000001,
00102         00400017777777777777777,
00103         01400017777777777777777,
00104         00400007777777777777777,
00105         01400007777777777777777,
00106         00400614000000000000000,
00107         01400614000000000000000,
00108         00400604000000000000000,
00109         01400604000000000000000,
00110         00400617777777777777777,
00111         01400617777777777777777,
00112         00400607777777777777777,
00113         01400607777777777777777,
00114         00400624000000000000000,
00115         01400624000000000000000,
00116         00400627777777777777777,
00117         01400627777777777777777,
00118         00400617777777777777777,
00119         01400617777777777777777,
00120         00000000000000000000001,
00121         00000000012340000000000,
00122         01777777777777777777777,
00123 
00124         0       /* must be last */
00125 };
00126 
00127 
00128 /* "Interesting" lower-order bits for 128-bit DP values */
00129 static unsigned long dtvals [] = {
00130 
00131         00000000000000000000000,
00132         00000004000000000000000,
00133         00000000000000000000001,
00134         00000007777777777777777,
00135         00000007777777777777776,
00136         00000000000001234123400,
00137 
00138         0       /* must be last */
00139 };
00140 
00141 
00142 /* "Interesting" integer values for exponents */
00143 static unsigned long ivals [] = {
00144 
00145         00000000000000000000000,
00146         00000000000000000000001,
00147         00000000000000000000002,
00148         00000000000000000000041,
00149         00000000000000000000077,
00150         00000000000000000000100,
00151         00777777777777777777777,
00152         01777777777777777777777,
00153         01777777777777777777776,
00154         01000000000000000000000,
00155 
00156         0       /* must be last */
00157 };
00158 
00159 
00160 /* Operations */
00161 void
00162 fadd (float *z, float *x, float *y) {
00163         *z = *x + *y;
00164 }
00165 
00166 void
00167 fsub (float *z, float *x, float *y) {
00168         *z = *x - *y;
00169 }
00170 
00171 void
00172 fmul (float *z, float *x, float *y) {
00173         *z = *x * *y;
00174 }
00175 
00176 void
00177 fdiv (float *z, float *x, float *y) {
00178         *z = *x / *y;
00179 }
00180 
00181 void
00182 dfadd (long double *z, long double *x, long double *y) {
00183         *z = *x + *y;
00184 }
00185 
00186 void
00187 dfsub (long double *z, long double *x, long double *y) {
00188         *z = *x - *y;
00189 }
00190 
00191 void
00192 dfmul (long double *z, long double *x, long double *y) {
00193         *z = *x * *y;
00194 }
00195 
00196 void
00197 dfdiv (long double *z, long double *x, long double *y) {
00198         *z = *x / *y;
00199 }
00200 
00201 extern void ARFMULT (float *, float *, float *);
00202 extern void ARRMULT (float *, float *, float *);
00203 extern void ARIMULT (float *, float *, float *);
00204 extern void ARQMULT (float *, float *, float *);
00205 extern void ARHRECIP (float *, float *);
00206 
00207 extern void ARSQRT (float *, float *);
00208 extern void ARDSQRT (long double *, long double *);
00209 extern void ARLOG (float *, float *);
00210 extern void ARDLOG (long double *, long double *);
00211 extern void AREXP (float *, float *);
00212 extern void ARDEXP (long double, long double *);
00213 extern void ARPOWII (int *, int *, int *);
00214 extern void ARPOWRI (float *, float *, long *);
00215 extern void ARPOWRR (float *, float *, float *);
00216 extern void ARPOWDI (long double *, long double *, long *);
00217 extern void ARPOWDR (long double *, long double *, float *);
00218 extern void ARPOWDD (long double *, long double *, long double *);
00219 extern void ARCABS (float *, double complex *);
00220 
00221 
00222 dotest64_1 (char *fn, void (*op)()) {
00223         int i;
00224         static volatile union { unsigned long lv; float fv; } u;
00225         float x, z;
00226         FILE *fp = fopen (fn, "w");
00227         if (!fp) {
00228                 fprintf (stderr, "can't open %s\n", fn);
00229                 exit (1);
00230         }
00231         for (i = 0; !i || tvals [i]; i++) {
00232                 u.lv = tvals [i];
00233                 x = u.fv;
00234                 u.lv = 0;
00235                 if (setjmp (fperr_jmpbuf))
00236                         z = 0;
00237                 else {
00238                         op (&z, &x);
00239                         u.fv = z;
00240                         if (!u.lv)
00241                                 fp_error |= AR_STAT_ZERO;
00242                         else if (u.lv >> 63)
00243                                 fp_error |= AR_STAT_NEGATIVE;
00244                 }
00245                 fprintf (fp, "$t %022o %022o %o\n", x, z, fp_error);
00246                 fp_error = AR_STAT_OK;
00247         }
00248         fclose (fp);
00249 }
00250 
00251 dotest64_c (char *fn, void (*op)()) {
00252         int i, j;
00253         static volatile union {
00254                 unsigned long lv [2];
00255                 double complex cv;
00256                 float fv;
00257         } u, v;
00258         float z;
00259         double complex x;
00260         FILE *fp = fopen (fn, "w");
00261         if (!fp) {
00262                 fprintf (stderr, "can't open %s\n", fn);
00263                 exit (1);
00264         }
00265         for (i = 0; !i || tvals [i]; i++) {
00266                 u.lv [0] = tvals [i];
00267                 for (j = 0; !j || tvals [j]; j++) {
00268                         u.lv [1] = tvals [j];
00269                         x = u.cv;
00270                         v.lv [0] = v.lv [1] = 0;
00271                         if (setjmp (fperr_jmpbuf))
00272                                 z = 0;
00273                         else {
00274                                 op (&z, &x);
00275                                 v.fv = z;
00276                                 if (!v.lv [0])
00277                                         fp_error |= AR_STAT_ZERO;
00278                         }
00279                         fprintf (fp, "$t %022o %022o %022o %o\n",
00280                                  x, z, fp_error);
00281                         fp_error = AR_STAT_OK;
00282                 }
00283         }
00284         fclose (fp);
00285 }
00286 
00287 dotest64_2 (char *fn, void (*op)()) {
00288         int i, j;
00289         static volatile union { unsigned long lv; float fv; } u;
00290         float x, y, z;
00291         FILE *fp = fopen (fn, "w");
00292         if (!fp) {
00293                 fprintf (stderr, "can't open %s\n", fn);
00294                 exit (1);
00295         }
00296         for (i = 0; !i || tvals [i]; i++) {
00297                 u.lv = tvals [i];
00298                 x = u.fv;
00299                 for (j = 0; !j || tvals [j]; j++) {
00300                         u.lv = tvals [j];
00301                         y = u.fv;
00302                         u.lv = 0;
00303                         if (setjmp (fperr_jmpbuf))
00304                                 z = 0;
00305                         else {
00306                                 op (&z, &x, &y);
00307                                 u.fv = z;
00308                                 if (!u.lv)
00309                                         fp_error |= AR_STAT_ZERO;
00310                                 else if (u.lv >> 63)
00311                                         fp_error |= AR_STAT_NEGATIVE;
00312                         }
00313                         fprintf (fp, "$t %022o %022o %022o %o\n",
00314                                  x, y, z, fp_error);
00315                         fp_error = AR_STAT_OK;
00316                 }
00317         }
00318         fclose (fp);
00319 }
00320 
00321 dotest64_i (char *fn, void (*op)()) {
00322         int i, j, y;
00323         static volatile union { unsigned long lv; float fv; } u;
00324         float x, z;
00325         FILE *fp = fopen (fn, "w");
00326         if (!fp) {
00327                 fprintf (stderr, "can't open %s\n", fn);
00328                 exit (1);
00329         }
00330         for (i = 0; !i || tvals [i]; i++) {
00331                 u.lv = tvals [i];
00332                 x = u.fv;
00333                 for (j = 0; !j || ivals [j]; j++) {
00334                         y = ivals [j];
00335                         u.lv = 0;
00336                         if (setjmp (fperr_jmpbuf))
00337                                 z = 0;
00338                         else {
00339                                 op (&z, &x, &y);
00340                                 u.fv = z;
00341                                 if (!u.lv)
00342                                         fp_error |= AR_STAT_ZERO;
00343                                 else if (u.lv >> 63)
00344                                         fp_error |= AR_STAT_NEGATIVE;
00345                         }
00346                         fprintf (fp, "$t %022o %022o %022o %o\n",
00347                                  x, y, z, fp_error);
00348                         fp_error = AR_STAT_OK;
00349                 }
00350         }
00351         fclose (fp);
00352 }
00353 
00354 dotest64_i2 (char *fn, void (*op)()) {
00355         int i, j;
00356         static volatile unsigned long x, y, z;
00357         FILE *fp = fopen (fn, "w");
00358         if (!fp) {
00359                 fprintf (stderr, "can't open %s\n", fn);
00360                 exit (1);
00361         }
00362         for (i = 0; !i || ivals [i]; i++) {
00363                 x = ivals [i];
00364                 for (j = 0; !j || ivals [j]; j++) {
00365                         y = ivals [j];
00366                         fp_error = AR_STAT_OK;
00367                         if (setjmp (fperr_jmpbuf))
00368                                 z = 0;
00369                         else {
00370                                 op (&z, &x, &y);
00371                                 if (!z)
00372                                         fp_error |= AR_STAT_ZERO;
00373                                 else if (z >> 63)
00374                                         fp_error |= AR_STAT_NEGATIVE;
00375                         }
00376                         fprintf (fp, "$t %022o %022o %022o %o\n",
00377                                  x, y, z, fp_error);
00378                         fp_error = AR_STAT_OK;
00379                 }
00380         }
00381         fclose (fp);
00382 }
00383 
00384 dotest128_1 (char *fn, void (*op)()) {
00385         int i, j;
00386         static volatile union { unsigned long lv [2]; long double fv; } u, v;
00387         long double x, z;
00388         FILE *fp = fopen (fn, "w");
00389         if (!fp) {
00390                 fprintf (stderr, "can't open %s\n", fn);
00391                 exit (1);
00392         }
00393         for (i = 0; !i || tvals [i]; i++)
00394                 for (j = 0; !j || dtvals [j]; j++) {
00395                         u.lv [0] = tvals [i];
00396                         u.lv [1] = dtvals [j];
00397                         x = u.fv;
00398                         v.lv [0] = v.lv [1] = 0;
00399                         if (setjmp (fperr_jmpbuf))
00400                                 z = 0;
00401                         else {
00402                                 op (&z, &x);
00403                                 v.fv = z;
00404                                 if (!(v.lv [0] | v.lv [1]))
00405                                         fp_error |= AR_STAT_ZERO;
00406                                 else if (v.lv [0] >> 63)
00407                                         fp_error |= AR_STAT_NEGATIVE;
00408                         }
00409                         fprintf (fp, "$t %022o %022o %022o %022o %o\n",
00410                                  u.lv [0], u.lv [1],
00411                                  v.lv [0], v.lv [1],
00412                                  fp_error);
00413                         fp_error = AR_STAT_OK;
00414                 }
00415         fclose (fp);
00416 }
00417 
00418 dotest128_2 (char *fn, void (*op)()) {
00419         int i, j, k;
00420         static volatile union { unsigned long lv [2]; long double fv; } u, v, w;
00421         long double x, y, z;
00422         FILE *fp = fopen (fn, "w");
00423         if (!fp) {
00424                 fprintf (stderr, "can't open %s\n", fn);
00425                 exit (1);
00426         }
00427         for (i = k = 0; !i || tvals [i]; i++) {
00428                 u.lv [0] = tvals [i];
00429                 u.lv [1] = dtvals [k++];
00430                 if (!dtvals [k])
00431                         k = 0;
00432                 x = u.fv;
00433                 for (j = 0; !j || tvals [j]; j++) {
00434                         v.lv [0] = tvals [j];
00435                         v.lv [1] = dtvals [k++];
00436                         if (!dtvals [k])
00437                                 k = 0;
00438                         y = v.fv;
00439                         w.lv [0] = w.lv [1] = 0;
00440                         if (setjmp (fperr_jmpbuf))
00441                                 z = 0;
00442                         else {
00443                                 op (&z, &x, &y);
00444                                 w.fv = z;
00445                                 if (!(w.lv [0] | w.lv [1]))
00446                                         fp_error |= AR_STAT_ZERO;
00447                                 else if (w.lv [0] >> 63)
00448                                         fp_error |= AR_STAT_NEGATIVE;
00449                         }
00450                         fprintf (fp, "$t %022o %022o %022o %022o %022o %022o %o\n",
00451                                  x, y, z, fp_error);
00452                         fp_error = AR_STAT_OK;
00453                 }
00454         }
00455         fclose (fp);
00456 }
00457 
00458 dotest128_r (char *fn, void (*op)()) {
00459         int i, j, k;
00460         static volatile union {
00461                 unsigned long lv [2];
00462                 long double fv;
00463                 float sv;
00464         } u, v, w;
00465         float y;
00466         long double x, z;
00467         FILE *fp = fopen (fn, "w");
00468         if (!fp) {
00469                 fprintf (stderr, "can't open %s\n", fn);
00470                 exit (1);
00471         }
00472         for (i = k = 0; !i || tvals [i]; i++) {
00473                 u.lv [0] = tvals [i];
00474                 u.lv [1] = dtvals [k++];
00475                 if (!dtvals [k])
00476                         k = 0;
00477                 x = u.fv;
00478                 for (j = 0; !j || tvals [j]; j++) {
00479                         v.lv [0] = tvals [j];
00480                         y = v.sv;
00481                         w.lv [0] = w.lv [1] = 0;
00482                         if (setjmp (fperr_jmpbuf))
00483                                 z = 0;
00484                         else {
00485                                 op (&z, &x, &y);
00486                                 w.fv = z;
00487                                 if (!(w.lv [0] | w.lv [1]))
00488                                         fp_error |= AR_STAT_ZERO;
00489                                 else if (w.lv [0] >> 63)
00490                                         fp_error |= AR_STAT_NEGATIVE;
00491                         }
00492                         fprintf (fp, "$t %022o %022o %022o %022o %022o %o\n",
00493                                  x, y, z, fp_error);
00494                         fp_error = AR_STAT_OK;
00495                 }
00496         }
00497         fclose (fp);
00498 }
00499 
00500 dotest128_i (char *fn, void (*op)()) {
00501         int i, j, k, y;
00502         static volatile union {
00503                 unsigned long lv [2];
00504                 long double fv;
00505         } u, v, w;
00506         long double x, z;
00507         FILE *fp = fopen (fn, "w");
00508         if (!fp) {
00509                 fprintf (stderr, "can't open %s\n", fn);
00510                 exit (1);
00511         }
00512         for (i = k = 0; !i || tvals [i]; i++) {
00513                 u.lv [0] = tvals [i];
00514                 u.lv [1] = dtvals [k++];
00515                 if (!dtvals [k])
00516                         k = 0;
00517                 x = u.fv;
00518                 for (j = 0; !j || ivals [j]; j++) {
00519                         y = ivals [j];
00520                         w.lv [0] = w.lv [1] = 0;
00521                         if (setjmp (fperr_jmpbuf))
00522                                 z = 0;
00523                         else {
00524                                 op (&z, &x, &y);
00525                                 w.fv = z;
00526                                 if (!(w.lv [0] | w.lv [1]))
00527                                         fp_error |= AR_STAT_ZERO;
00528                                 else if (w.lv [0] >> 63)
00529                                         fp_error |= AR_STAT_NEGATIVE;
00530                         }
00531                         fprintf (fp, "$t %022o %022o %022o %022o %022o %o\n",
00532                                  x, y, z, fp_error);
00533                         fp_error = AR_STAT_OK;
00534                 }
00535         }
00536         fclose (fp);
00537 }
00538 
00539 
00540 main () {
00541 
00542         signal (SIGFPE, fperr);
00543 #if _UNICOS < 8
00544         signal (SIGERR, fperr);
00545 #endif
00546 
00547         dotest64_2 ("results/cray1_add64", fadd);
00548         dotest64_2 ("results/cray1_sub64", fsub);
00549         dotest64_2 ("results/cray1_mul64", fmul);
00550         dotest64_2 ("results/cray1_recipiter", ARIMULT);
00551         dotest64_1 ("results/cray1_recip", ARHRECIP);
00552         dotest64_2 ("results/cray1_div64", fdiv);
00553         dotest128_2 ("results/cray1_add128", dfadd);
00554         dotest128_2 ("results/cray1_sub128", dfsub);
00555         dotest128_2 ("results/cray1_mul128", dfmul);
00556         dotest128_2 ("results/cray1_div128", dfdiv);
00557         jmp_on_err = 1;
00558         dotest64_c ("results/cray1_cabs", ARCABS);
00559         dotest64_1 ("results/cray1_sqrt", ARSQRT);
00560         dotest128_1 ("results/cray1_dsqrt", ARDSQRT);
00561         dotest64_1 ("results/cray1_log", ARLOG);
00562         dotest128_1 ("results/cray1_dlog", ARDLOG);
00563         dotest64_1 ("results/cray1_exp", AREXP);
00564         dotest128_1 ("results/cray1_dexp", ARDEXP);
00565         dotest64_2 ("results/cray1_powrr", ARPOWRR);
00566         dotest128_r ("results/cray1_powdr", ARPOWDR);
00567         dotest128_2 ("results/cray1_powdd", ARPOWDD);
00568         dotest64_i2 ("results/cray1_powii", ARPOWII);
00569         dotest64_i ("results/cray1_powri", ARPOWRI);
00570         dotest128_i ("results/cray1_powdi", ARPOWDI);
00571         jmp_on_err = 0;
00572 #undef U
00573 
00574         exit (0);
00575 }
00576 
00577 #define _fcdtocp(f)     ((char *)(((long)(f))&0xfc000000ffffffff))
00578 #define _fcdlen(f)      ((unsigned)((((long)(f))>>35)&0x7fffff))
00579 AR_NOINTRIN_ERROR(char* intrin_name) {
00580         int     i;
00581         char*   name = _fcdtocp(intrin_name);
00582         for(i=0; i<_fcdlen(intrin_name); i++)
00583                 if(!isalnum(name[i])) break;
00584         name[i] = '\0';
00585         ar_internal_error(2017, name, 1);
00586 }
00587 
00588 void
00589 ar_internal_error (int msgnum, char *file, int line) {
00590 
00591         PRINTMSG(0, msgnum, Internal, 0, file, line);
00592         /* PRINTMSG does not return for internal errors */
00593 }
00594 
00595 
00596 static char USMID [] = "\n%Z%%M%        %I%     %G% %U%\n";
00597 static char rcsid [] = "$Id: ctgen.c,v 1.1.1.1 2002-05-22 20:06:18 dsystem Exp $";
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines