home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
mitsch75.zip
/
scheme-7_5_17-src.zip
/
scheme-7.5.17
/
src
/
microcode
/
wsize.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-02
|
7KB
|
301 lines
/* -*-C-*-
$Id: wsize.c,v 9.34 1999/01/02 06:11:34 cph Exp $
Copyright (c) 1989-1999 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <signal.h>
#include "ansidecl.h"
/* #include "config.h" */
#ifndef TYPE_CODE_LENGTH
/* This MUST match object.h */
#define TYPE_CODE_LENGTH 8
#endif
#define ASCII_LOWER_A 0141
#define ASCII_UPPER_A 0101
#define boolean int
#define false 0
#define true 1
extern int errno;
extern PTR EXFUN (malloc, ());
extern void EXFUN (free, ());
/* The following hanky-panky courtesy of some buggy compilers. */
int
mul (x, y)
int x; int y;
{
return (x * y);
}
double
itod (n)
int n;
{
return ((double) (mul (n, 1)));
}
double
power (base, expo)
double base;
unsigned expo;
{
double result = (itod (1));
while (expo != 0)
{
if ((expo & 1) == 1)
{
result *= base;
expo -= 1;
}
else
{
base *= base;
expo >>= 1;
}
}
return (result);
}
/* Some machines do not set ERANGE by default. */
/* This attempts to fix this. */
#ifdef SIGFPE
# define setup_error() signal(SIGFPE, range_error)
void
range_error()
{
setup_error();
errno = ERANGE;
return;
}
#else /* not SIGFPE */
# define setup_error()
#endif /* SIGFPE */
/* Force program data to be relatively large. */
#define ARR_SIZE 20000
#define MEM_SIZE 400000
static long dummy[ARR_SIZE];
/* Structure used to find double alignment constraints. */
struct double_probe {
long field_1;
double field_2;
} proble_double[2];
/* Note: comments are printed in a weird way because some
C compilers eliminate them even from strings.
*/
main()
{
double accum[3], delta, dtemp, zero, one, two;
int count, expt_size, char_size, mant_size, double_size, extra;
unsigned long to_be_shifted;
unsigned bogus;
struct { long pad; char real_buffer[sizeof(long)]; } padding_buf;
char * buffer, * temp;
boolean confused;
buffer = &padding_buf.real_buffer[0];
confused = false;
setup_error ();
printf ("/%c CSCHEME configuration parameters. %c/\n", '*', '*');
printf ("/%c REMINDER: Insert these definitions in config.h. %c/\n\n",
'*', '*');
printf ("/%c REMINDER: Change the following definitions! %c/\n",
'*', '*');
printf ("#define MACHINE_TYPE \"Unknown machine, fix config.h\"\n");
printf ("#define FASL_INTERNAL_FORMAT FASL_UNKNOWN\n\n");
if ((((int) 'a') == ASCII_LOWER_A) &&
(((int) 'A') == ASCII_UPPER_A))
{
printf ("/%c The ASCII character set is used. %c/\n", '*', '*');
}
else
{
printf ("/%c The ASCII character set is NOT used. %c/\n", '*', '*');
printf ("/%c REMINDER: Change the following definition! %c/\n",
'*', '*');
}
for (bogus = ((unsigned) -1), count = 0;
bogus != 0;
count += 1)
{
bogus >>= 1;
}
char_size = (count / (sizeof(unsigned)));
temp = (malloc (MEM_SIZE * (sizeof(long))));
if (temp == NULL)
{
confused = true;
printf ("/%c CONFUSION: Could not allocate %d Objects. %c/\n",
'*', MEM_SIZE, '*');
printf ("/%c Will not assume that the Heap is in Low Memory. %c/\n",
'*', '*');
}
else
{
free (temp);
if (((unsigned long) temp) <
(1 << ((char_size * sizeof(long)) - TYPE_CODE_LENGTH)))
printf ("#define HEAP_IN_LOW_MEMORY 1\n");
else
printf ("/%c Heap is not in Low Memory. %c/\n", '*', '*');
}
to_be_shifted = -1;
if ((to_be_shifted >> 1) == to_be_shifted)
{
printf ("/%c unsigned longs use arithmetic shifting. %c/\n", '*', '*');
printf ("#define UNSIGNED_SHIFT_BUG\n");
}
else
{
printf ("/%c unsigned longs use logical shifting. %c/\n", '*', '*');
}
if ((sizeof(long)) == (sizeof(char)))
{
printf ("/%c sizeof(long) == sizeof(char); no byte order problems! %c/\n",
'*', '*');
}
else
{
buffer[0] = 1;
for (count = 1; count < sizeof(long); )
{
buffer[count++] = 0;
}
if (*((long *) &buffer[0]) == 1)
{
printf("#define VAX_BYTE_ORDER 1\n\n");
}
else
{
printf("/%c VAX_BYTE_ORDER not used. %c/\n\n", '*', '*');
}
}
double_size = (char_size*sizeof(double));
printf ("#define CHAR_BIT %d\n",
char_size);
if (sizeof(struct double_probe) == (sizeof(double) + sizeof(long)))
{
printf ("/%c Flonums have no special alignment constraints. %c/\n",
'*', '*');
}
else if ((sizeof(struct double_probe) != (2 * sizeof(double))) ||
((sizeof(double) % sizeof(long)) != 0))
{
confused = true;
printf ("/%c CONFUSION: Can't determine float alignment constraints! %c/\n",
'*', '*');
printf ("/%c Please define FLOATING_ALIGNMENT by hand. %c/\n", '*', '*');
}
else
{
printf ("#define FLOATING_ALIGNMENT 0x%lx\n", (sizeof(double)-1));
}
mant_size = 1;
zero = (itod (0));
one = (itod (1));
two = (itod (2));
accum[0] = one;
accum[1] = zero;
delta = (one / two);
while (true)
{
accum[2] = accum[1];
accum[1] = (accum[0] + delta);
if ((accum[1] == accum[0]) ||
(accum[2] == accum[1]) ||
(mant_size == double_size))
break;
delta = (delta / two);
mant_size += 1;
}
printf ("#define FLONUM_MANTISSA_BITS %d\n", mant_size);
for (errno = 0, expt_size = 0, bogus = 1, dtemp = zero;
((errno != ERANGE) && (expt_size <= double_size));
expt_size += 1, bogus <<= 1)
{
delta = dtemp;
dtemp = (power (two, bogus));
if (dtemp == delta)
break;
}
expt_size -= 1;
printf ("#define FLONUM_EXPT_SIZE %d\n", expt_size);
printf ("#define MAX_FLONUM_EXPONENT %d\n", ((1 << expt_size) - 1));
extra = ((2 + expt_size + mant_size) - double_size);
if (extra > 1)
{
confused = true;
printf ("/%c CONFUSION: Can't determine floating parameters! %c/\n",
'*', '*');
printf ("/%c Please fix above three parameters by hand. %c/\n", '*', '*');
}
else
{
printf ("/%c Floating point representation %s hidden bit. %c/\n", '*',
((extra == 1) ? "uses" : "does not use"), '*');
}
if (confused)
{
fprintf (stderr, "Please examine carefully the \"confused\" parameters.\n");
exit(1);
}
return;
}