Go to the documentation of this file.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(void)
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(void)
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(void)
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(void)
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(void)
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 void
00170 get_nanbits(unsigned int *b, int k)
00171 {
00172 union { double d; unsigned int z[2]; } u, u1, u2;
00173
00174 k = 2 - k;
00175 u1.z[k] = u2.z[k] = 0x7ff00000;
00176 u1.z[1-k] = u2.z[1-k] = 0;
00177 u.d = u1.d - u2.d;
00178 b[0] = u.z[0];
00179 b[1] = u.z[1];
00180 }
00181
00182 int
00183 main(void)
00184 {
00185 FILE *f;
00186 Akind *a = 0;
00187 int Ldef = 0;
00188 unsigned int nanbits[2];
00189
00190 fpinit_ASL();
00191 #ifdef WRITE_ARITH_H
00192 f = fopen("arith.h", "w");
00193 if (!f) {
00194 printf("Cannot open arith.h\n");
00195 return 1;
00196 }
00197 #else
00198 f = stdout;
00199 #endif
00200
00201 if (sizeof(double) == 2*sizeof(long))
00202 a = Lcheck();
00203 else if (sizeof(double) == 2*sizeof(int)) {
00204 Ldef = 1;
00205 a = icheck();
00206 }
00207 else if (sizeof(double) == sizeof(long))
00208 a = ccheck();
00209 if (a) {
00210 fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
00211 a->name, a->kind);
00212 if (Ldef)
00213 fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
00214 if (dalign)
00215 fprintf(f, "#define Double_Align\n");
00216 if (sizeof(char*) == 8)
00217 fprintf(f, "#define X64_bit_pointers\n");
00218 #ifndef NO_LONG_LONG
00219 if (sizeof(long long) < 8)
00220 #endif
00221 fprintf(f, "#define NO_LONG_LONG\n");
00222 if (a->kind <= 2) {
00223 if (fzcheck())
00224 fprintf(f, "#define Sudden_Underflow\n");
00225 t_nan = -a->kind;
00226 if (need_nancheck())
00227 fprintf(f, "#define NANCHECK\n");
00228 if (sizeof(double) == 2*sizeof(unsigned int)) {
00229 get_nanbits(nanbits, a->kind);
00230 fprintf(f, "#define QNaN0 0x%x\n", nanbits[0]);
00231 fprintf(f, "#define QNaN1 0x%x\n", nanbits[1]);
00232 }
00233 }
00234 return 0;
00235 }
00236 fprintf(f, "/* Unknown arithmetic */\n");
00237 return 1;
00238 }
00239
00240 #ifdef __sun
00241 #ifdef __i386
00242
00243 void fpsetprec(int x) { }
00244 #endif
00245 #endif