Embedded Artistry libc
C Standard Library Support for Bare-metal Systems
arithchk.c
Go to the documentation of this file.
1 /****************************************************************
2 Copyright (C) 1997, 1998 Lucent Technologies
3 All Rights Reserved
4 
5 Permission to use, copy, modify, and distribute this software and
6 its documentation for any purpose and without fee is hereby
7 granted, provided that the above copyright notice appear in all
8 copies and that both that the copyright notice and this
9 permission notice and warranty disclaimer appear in supporting
10 documentation, and that the name of Lucent or any of its entities
11 not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior
13 permission.
14 
15 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 THIS SOFTWARE.
23 ****************************************************************/
24 
25 /* Try to deduce arith.h from arithmetic properties. */
26 
27 #include <stdio.h>
28 
29 static int dalign;
30 typedef struct Akind
31 {
32  char* name;
33  int kind;
34 } Akind;
35 
36 static Akind IEEE_8087 = {"IEEE_8087", 1}, IEEE_MC68k = {"IEEE_MC68k", 2}, IBM = {"IBM", 3},
37  VAX = {"VAX", 4}, CRAY = {"CRAY", 5};
38 
39 static Akind* Lcheck()
40 {
41  union
42  {
43  double d;
44  long L[2];
45  } u;
46  struct
47  {
48  double d;
49  long L;
50  } x[2];
51 
52  if(sizeof(x) > 2 * (sizeof(double) + sizeof(long)))
53  dalign = 1;
54  u.L[0] = u.L[1] = 0;
55  u.d = 1e13;
56  if(u.L[0] == 1117925532 && u.L[1] == -448790528)
57  return &IEEE_MC68k;
58  if(u.L[1] == 1117925532 && u.L[0] == -448790528)
59  return &IEEE_8087;
60  if(u.L[0] == -2065213935 && u.L[1] == 10752)
61  return &VAX;
62  if(u.L[0] == 1267827943 && u.L[1] == 704643072)
63  return &IBM;
64  return 0;
65 }
66 
67 static Akind* icheck()
68 {
69  union
70  {
71  double d;
72  int L[2];
73  } u;
74  struct
75  {
76  double d;
77  int L;
78  } x[2];
79 
80  if(sizeof(x) > 2 * (sizeof(double) + sizeof(int)))
81  dalign = 1;
82  u.L[0] = u.L[1] = 0;
83  u.d = 1e13;
84  if(u.L[0] == 1117925532 && u.L[1] == -448790528)
85  return &IEEE_MC68k;
86  if(u.L[1] == 1117925532 && u.L[0] == -448790528)
87  return &IEEE_8087;
88  if(u.L[0] == -2065213935 && u.L[1] == 10752)
89  return &VAX;
90  if(u.L[0] == 1267827943 && u.L[1] == 704643072)
91  return &IBM;
92  return 0;
93 }
94 
95 static Akind* ccheck()
96 {
97  union
98  {
99  double d;
100  long L;
101  } u;
102  long Cray1;
103 
104  /* Cray1 = 4617762693716115456 -- without overflow on non-Crays */
105  Cray1 = printf("") < 0 ? 0 : 4617762;
106  if(printf("%ld", Cray1) >= 0)
107  Cray1 = 1000000 * Cray1 + 693716;
108  if(printf("%ld", Cray1) >= 0)
109  Cray1 = 1000000 * Cray1 + 115456;
110  u.d = 1e13;
111  if(u.L == Cray1)
112  return &CRAY;
113  return 0;
114 }
115 
116 static int fzcheck()
117 {
118  double a, b;
119  int i;
120 
121  a = 1.;
122  b = .1;
123  for(i = 155;; b *= b, i >>= 1)
124  {
125  if(i & 1)
126  {
127  a *= b;
128  if(i == 1)
129  break;
130  }
131  }
132  b = a * a;
133  return b == 0.;
134 }
135 
136 int main()
137 {
138  Akind* a = 0;
139  int Ldef = 0;
140  FILE* f;
141 
142 #ifdef WRITE_ARITH_H /* for Symantec's buggy "make" */
143  f = fopen("arith.h", "w");
144  if(!f)
145  {
146  printf("Cannot open arith.h\n");
147  return 1;
148  }
149 #else
150  f = stdout;
151 #endif
152 
153  if(sizeof(double) == 2 * sizeof(long))
154  a = Lcheck();
155  else if(sizeof(double) == 2 * sizeof(int))
156  {
157  Ldef = 1;
158  a = icheck();
159  }
160  else if(sizeof(double) == sizeof(long))
161  a = ccheck();
162  if(a)
163  {
164  fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n", a->name, a->kind);
165  if(Ldef)
166  fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
167  if(dalign)
168  fprintf(f, "#define Double_Align\n");
169  if(sizeof(char*) == 8)
170  fprintf(f, "#define X64_bit_pointers\n");
171 #ifndef NO_LONG_LONG
172  if(sizeof(long long) < 8)
173 #endif
174  fprintf(f, "#define NO_LONG_LONG\n");
175  if(a->kind <= 2 && fzcheck())
176  fprintf(f, "#define Sudden_Underflow\n");
177 #ifdef WRITE_ARITH_H
178  fclose(f);
179 #endif
180  return 0;
181  }
182  fprintf(f, "/* Unknown arithmetic */\n");
183 
184 #ifdef WRITE_ARITH_H
185  fclose(f);
186 #endif
187 
188  return 1;
189 }
static Akind * icheck()
Definition: arithchk.c:67
static Akind IEEE_8087
Definition: arithchk.c:36
int fclose(FILE *)
static Akind * ccheck()
Definition: arithchk.c:95
static Akind CRAY
Definition: arithchk.c:37
static Akind VAX
Definition: arithchk.c:37
int kind
Definition: arithchk.c:33
static int dalign
Definition: arithchk.c:29
int main()
Definition: arithchk.c:136
static Akind * Lcheck()
Definition: arithchk.c:39
struct Akind Akind
FILE * fopen(const char *__restrict, const char *__restrict)
static Akind IEEE_MC68k
Definition: arithchk.c:36
static Akind IBM
Definition: arithchk.c:36
char * name
Definition: arithchk.c:32
int fprintf(FILE *__restrict, const char *__restrict,...)
static int fzcheck()
Definition: arithchk.c:116
Definition: arithchk.c:30