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