00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdio.h>
00028 #include <math.h>
00029 #include <errno.h>
00030
00031 #ifdef NO_FPINIT
00032 #define fpinit_ASL()
00033 #else
00034 #ifndef KR_headers
00035 extern
00036 #ifdef __cplusplus
00037 "C"
00038 #endif
00039 void fpinit_ASL(void);
00040 #endif
00041 #endif
00042
00043 static int dalign;
00044 typedef struct
00045 Akind {
00046 char *name;
00047 int kind;
00048 } Akind;
00049
00050 static Akind
00051 IEEE_8087 = { "IEEE_8087", 1 },
00052 IEEE_MC68k = { "IEEE_MC68k", 2 },
00053 IBM = { "IBM", 3 },
00054 VAX = { "VAX", 4 },
00055 CRAY = { "CRAY", 5};
00056
00057 static double t_nan;
00058
00059 static Akind *
00060 Lcheck()
00061 {
00062 union {
00063 double d;
00064 long L[2];
00065 } u;
00066 struct {
00067 double d;
00068 long L;
00069 } x[2];
00070
00071 if (sizeof(x) > 2*(sizeof(double) + sizeof(long)))
00072 dalign = 1;
00073 u.L[0] = u.L[1] = 0;
00074 u.d = 1e13;
00075 if (u.L[0] == 1117925532 && u.L[1] == -448790528)
00076 return &IEEE_MC68k;
00077 if (u.L[1] == 1117925532 && u.L[0] == -448790528)
00078 return &IEEE_8087;
00079 if (u.L[0] == -2065213935 && u.L[1] == 10752)
00080 return &VAX;
00081 if (u.L[0] == 1267827943 && u.L[1] == 704643072)
00082 return &IBM;
00083 return 0;
00084 }
00085
00086 static Akind *
00087 icheck()
00088 {
00089 union {
00090 double d;
00091 int L[2];
00092 } u;
00093 struct {
00094 double d;
00095 int L;
00096 } x[2];
00097
00098 if (sizeof(x) > 2*(sizeof(double) + sizeof(int)))
00099 dalign = 1;
00100 u.L[0] = u.L[1] = 0;
00101 u.d = 1e13;
00102 if (u.L[0] == 1117925532 && u.L[1] == -448790528)
00103 return &IEEE_MC68k;
00104 if (u.L[1] == 1117925532 && u.L[0] == -448790528)
00105 return &IEEE_8087;
00106 if (u.L[0] == -2065213935 && u.L[1] == 10752)
00107 return &VAX;
00108 if (u.L[0] == 1267827943 && u.L[1] == 704643072)
00109 return &IBM;
00110 return 0;
00111 }
00112
00113 char *emptyfmt = "";
00114
00115 static Akind *
00116 ccheck()
00117 {
00118 union {
00119 double d;
00120 long L;
00121 } u;
00122 long Cray1;
00123
00124
00125 Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762;
00126 if (printf(emptyfmt, Cray1) >= 0)
00127 Cray1 = 1000000*Cray1 + 693716;
00128 if (printf(emptyfmt, Cray1) >= 0)
00129 Cray1 = 1000000*Cray1 + 115456;
00130 u.d = 1e13;
00131 if (u.L == Cray1)
00132 return &CRAY;
00133 return 0;
00134 }
00135
00136 static int
00137 fzcheck()
00138 {
00139 double a, b;
00140 int i;
00141
00142 a = 1.;
00143 b = .1;
00144 for(i = 155;; b *= b, i >>= 1) {
00145 if (i & 1) {
00146 a *= b;
00147 if (i == 1)
00148 break;
00149 }
00150 }
00151 b = a * a;
00152 return b == 0.;
00153 }
00154
00155 static int
00156 need_nancheck()
00157 {
00158 double t;
00159
00160 errno = 0;
00161 t = log(t_nan);
00162 if (errno == 0)
00163 return 1;
00164 errno = 0;
00165 t = sqrt(t_nan);
00166 return errno == 0;
00167 }
00168
00169 main()
00170 {
00171 FILE *f;
00172 Akind *a = 0;
00173 int Ldef = 0;
00174
00175 fpinit_ASL();
00176 #ifdef WRITE_ARITH_H
00177 f = fopen("arith.h", "w");
00178 if (!f) {
00179 printf("Cannot open arith.h\n");
00180 return 1;
00181 }
00182 #else
00183 f = stdout;
00184 #endif
00185
00186 if (sizeof(double) == 2*sizeof(long))
00187 a = Lcheck();
00188 else if (sizeof(double) == 2*sizeof(int)) {
00189 Ldef = 1;
00190 a = icheck();
00191 }
00192 else if (sizeof(double) == sizeof(long))
00193 a = ccheck();
00194 if (a) {
00195 fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
00196 a->name, a->kind);
00197 if (Ldef)
00198 fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
00199 if (dalign)
00200 fprintf(f, "#define Double_Align\n");
00201 if (sizeof(char*) == 8)
00202 fprintf(f, "#define X64_bit_pointers\n");
00203 #ifndef NO_LONG_LONG
00204 if (sizeof(long long) < 8)
00205 #endif
00206 fprintf(f, "#define NO_LONG_LONG\n");
00207 if (a->kind <= 2) {
00208 if (fzcheck())
00209 fprintf(f, "#define Sudden_Underflow\n");
00210 t_nan = -a->kind;
00211 if (need_nancheck())
00212 fprintf(f, "#define NANCHECK\n");
00213 }
00214 return 0;
00215 }
00216 fprintf(f, "/* Unknown arithmetic */\n");
00217 return 1;
00218 }
00219
00220 #ifdef __sun
00221 #ifdef __i386
00222
00223 void fpsetprec(int x) { }
00224 #endif
00225 #endif