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 >
C/C++ Source or Header  |  1999-01-02  |  7KB  |  301 lines

  1. /* -*-C-*-
  2.  
  3. $Id: wsize.c,v 9.34 1999/01/02 06:11:34 cph Exp $
  4.  
  5. Copyright (c) 1989-1999 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <math.h>
  24. #include <errno.h>
  25. #include <signal.h>
  26. #include "ansidecl.h"
  27. /* #include "config.h" */
  28.  
  29. #ifndef TYPE_CODE_LENGTH
  30. /* This MUST match object.h */
  31. #define TYPE_CODE_LENGTH    8
  32. #endif
  33.  
  34. #define ASCII_LOWER_A        0141
  35. #define ASCII_UPPER_A        0101
  36.  
  37. #define boolean            int
  38. #define false            0
  39. #define true            1
  40.  
  41. extern int errno;
  42. extern PTR EXFUN (malloc, ());
  43. extern void EXFUN (free, ());
  44.  
  45. /* The following hanky-panky courtesy of some buggy compilers. */
  46.  
  47. int
  48. mul (x, y)
  49.      int x; int y;
  50. {
  51.   return (x * y);
  52. }
  53.  
  54. double
  55. itod (n)
  56.      int n;
  57. {
  58.   return ((double) (mul (n, 1)));
  59. }
  60.  
  61. double
  62. power (base, expo)
  63.      double base;
  64.      unsigned expo;
  65. {
  66.   double result = (itod (1));
  67.   while (expo != 0)
  68.   {
  69.     if ((expo & 1) == 1)
  70.     {
  71.       result *= base;
  72.       expo -= 1;
  73.     }
  74.     else
  75.     {
  76.       base *= base;
  77.       expo >>= 1;
  78.     }
  79.   }
  80.   return (result);
  81. }
  82.  
  83. /* Some machines do not set ERANGE by default. */
  84. /* This attempts to fix this. */
  85.  
  86. #ifdef SIGFPE
  87.  
  88. #  define setup_error()        signal(SIGFPE, range_error)
  89.  
  90. void
  91. range_error()
  92. {
  93.   setup_error();
  94.   errno = ERANGE;
  95.   return;
  96. }
  97.  
  98. #else /* not SIGFPE */
  99.  
  100. #  define setup_error()
  101.  
  102. #endif /* SIGFPE */
  103.  
  104. /* Force program data to be relatively large. */
  105.  
  106. #define ARR_SIZE        20000
  107. #define MEM_SIZE        400000
  108.  
  109. static long dummy[ARR_SIZE];
  110.  
  111. /* Structure used to find double alignment constraints. */
  112.  
  113. struct double_probe {
  114.   long field_1;
  115.   double field_2;
  116. } proble_double[2];
  117.  
  118. /* Note: comments are printed in a weird way because some
  119.    C compilers eliminate them even from strings.
  120. */
  121.  
  122. main()
  123. {
  124.   double accum[3], delta, dtemp, zero, one, two;
  125.   int count, expt_size, char_size, mant_size, double_size, extra;
  126.   unsigned long to_be_shifted;
  127.   unsigned bogus;
  128.   struct { long pad; char real_buffer[sizeof(long)]; } padding_buf;
  129.   char * buffer, * temp;
  130.   boolean confused;
  131.  
  132.   buffer = &padding_buf.real_buffer[0];
  133.   confused = false;
  134.   setup_error ();
  135.  
  136.   printf ("/%c CSCHEME configuration parameters. %c/\n", '*', '*');
  137.   printf ("/%c REMINDER: Insert these definitions in config.h. %c/\n\n",
  138.       '*', '*');
  139.  
  140.   printf ("/%c REMINDER: Change the following definitions! %c/\n",
  141.       '*', '*');
  142.   printf ("#define MACHINE_TYPE          \"Unknown machine, fix config.h\"\n");
  143.   printf ("#define FASL_INTERNAL_FORMAT   FASL_UNKNOWN\n\n");
  144.  
  145.   if ((((int) 'a') == ASCII_LOWER_A) &&
  146.       (((int) 'A') == ASCII_UPPER_A))
  147.   {
  148.     printf ("/%c The ASCII character set is used. %c/\n", '*', '*');
  149.   }
  150.   else
  151.   {
  152.     printf ("/%c The ASCII character set is NOT used. %c/\n", '*', '*');
  153.     printf ("/%c REMINDER: Change the following definition! %c/\n",
  154.         '*', '*');
  155.   }
  156.  
  157.   for (bogus = ((unsigned) -1), count = 0;
  158.        bogus != 0;
  159.        count += 1)
  160.   {
  161.     bogus >>= 1;
  162.   }
  163.  
  164.   char_size = (count / (sizeof(unsigned)));
  165.  
  166.   temp = (malloc (MEM_SIZE * (sizeof(long))));
  167.   if (temp == NULL)
  168.   {
  169.     confused = true;
  170.     printf ("/%c CONFUSION: Could not allocate %d Objects. %c/\n",
  171.         '*', MEM_SIZE, '*');
  172.     printf ("/%c Will not assume that the Heap is in Low Memory. %c/\n",
  173.         '*', '*');
  174.   }
  175.   else
  176.   {
  177.     free (temp);
  178.     if (((unsigned long) temp) <
  179.     (1 << ((char_size * sizeof(long)) - TYPE_CODE_LENGTH)))
  180.       printf ("#define HEAP_IN_LOW_MEMORY     1\n");
  181.     else
  182.       printf ("/%c Heap is not in Low Memory. %c/\n", '*', '*');
  183.   }
  184.  
  185.   to_be_shifted = -1;
  186.   if ((to_be_shifted >> 1) == to_be_shifted)
  187.   {
  188.     printf ("/%c unsigned longs use arithmetic shifting. %c/\n", '*', '*');
  189.     printf ("#define UNSIGNED_SHIFT_BUG\n");
  190.   }
  191.   else
  192.   {
  193.     printf ("/%c unsigned longs use logical shifting. %c/\n", '*', '*');
  194.   }
  195.  
  196.   if ((sizeof(long)) == (sizeof(char)))
  197.   {
  198.     printf ("/%c sizeof(long) == sizeof(char); no byte order problems! %c/\n",
  199.         '*', '*');
  200.   }
  201.   else
  202.   {
  203.     buffer[0] = 1;
  204.     for (count = 1; count < sizeof(long); )
  205.     {
  206.       buffer[count++] = 0;
  207.     }
  208.     if (*((long *) &buffer[0]) == 1)
  209.     {
  210.       printf("#define VAX_BYTE_ORDER         1\n\n");
  211.     }
  212.     else
  213.     {
  214.       printf("/%c VAX_BYTE_ORDER not used. %c/\n\n", '*', '*');
  215.     }
  216.   }
  217.  
  218.   double_size = (char_size*sizeof(double));
  219.  
  220.   printf ("#define CHAR_BIT               %d\n",
  221.       char_size);
  222.  
  223.   if (sizeof(struct double_probe) == (sizeof(double) + sizeof(long)))
  224.   {
  225.     printf ("/%c Flonums have no special alignment constraints. %c/\n",
  226.         '*', '*');
  227.   }
  228.   else if ((sizeof(struct double_probe) != (2 * sizeof(double))) ||
  229.        ((sizeof(double) % sizeof(long)) != 0))
  230.   {
  231.     confused = true;
  232.     printf ("/%c CONFUSION: Can't determine float alignment constraints! %c/\n",
  233.         '*', '*');
  234.     printf ("/%c Please define FLOATING_ALIGNMENT by hand. %c/\n", '*', '*');
  235.   }
  236.   else
  237.   {
  238.     printf ("#define FLOATING_ALIGNMENT     0x%lx\n", (sizeof(double)-1));
  239.   }
  240.  
  241.   mant_size = 1;
  242.  
  243.   zero = (itod (0));
  244.   one = (itod (1));
  245.   two = (itod (2));
  246.  
  247.   accum[0] = one;
  248.   accum[1] = zero;
  249.   delta = (one / two);
  250.  
  251.   while (true)
  252.   {
  253.     accum[2] = accum[1];
  254.     accum[1] = (accum[0] + delta);
  255.     if ((accum[1] == accum[0]) ||
  256.     (accum[2] == accum[1]) ||
  257.     (mant_size == double_size))
  258.       break;
  259.     delta = (delta / two);
  260.     mant_size += 1;
  261.   }
  262.  
  263.   printf ("#define FLONUM_MANTISSA_BITS   %d\n", mant_size);
  264.  
  265.   for (errno = 0, expt_size = 0, bogus = 1, dtemp = zero;
  266.        ((errno != ERANGE) && (expt_size <= double_size));
  267.        expt_size += 1, bogus <<= 1)
  268.   {
  269.     delta = dtemp;
  270.     dtemp = (power (two, bogus));
  271.     if (dtemp == delta)
  272.       break;
  273.   }
  274.  
  275.   expt_size -= 1;
  276.  
  277.   printf ("#define FLONUM_EXPT_SIZE       %d\n", expt_size);
  278.   printf ("#define MAX_FLONUM_EXPONENT    %d\n", ((1 << expt_size) - 1));
  279.  
  280.   extra = ((2 + expt_size + mant_size) - double_size);
  281.  
  282.   if (extra > 1)
  283.   {
  284.     confused = true;
  285.     printf ("/%c CONFUSION: Can't determine floating parameters! %c/\n",
  286.         '*', '*');
  287.     printf ("/%c Please fix above three parameters by hand. %c/\n", '*', '*');
  288.   }
  289.   else
  290.   {
  291.     printf ("/%c Floating point representation %s hidden bit. %c/\n", '*',
  292.         ((extra == 1) ? "uses" : "does not use"), '*');
  293.   }
  294.   if (confused)
  295.   {
  296.     fprintf (stderr, "Please examine carefully the \"confused\" parameters.\n");
  297.     exit(1);
  298.   }
  299.   return;
  300. }
  301.