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