Two major changes:
authorGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Sat, 30 Oct 1993 03:01:38 +0000 (03:01 +0000)
committerGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Sat, 30 Oct 1993 03:01:38 +0000 (03:01 +0000)
- Redo the way that descriptors are done to improve speed.
  The default clause in each switch statement is now the only way to
  get out of a block.
  All JUMPs merely jump back to the dispatch point.

- Divide initialization code into code and data, to allow splitting
  of the sources into two components.

v7/src/microcode/cmpauxmd/c.c
v7/src/microcode/cmpintmd/c.h

index 1c88497a61a0a66d886de46f84e54947975fc41b..02a5897bb621904ea25cdbd1335b1d87e56865a4 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: c.c,v 1.6 1993/10/27 23:50:09 gjr Exp $
+$Id: c.c,v 1.7 1993/10/30 03:01:30 gjr Exp $
 
 Copyright (c) 1992-1993 Massachusetts Institute of Technology
 
@@ -35,8 +35,6 @@ MIT in each case. */
 #include "liarc.h"
 #include "bignum.h"
 #include "bitstr.h"
-
-extern void EXFUN (lose_big_1, (char *, char *));
 \f
 #ifdef BUG_GCC_LONG_CALLS
 
@@ -70,35 +68,69 @@ extern char * interface_to_C_hook;
 extern void EXFUN (C_to_interface, (PTR));
 extern void EXFUN (interface_initialize, (void));
 extern SCHEME_OBJECT * EXFUN (initialize_C_compiled_block, (int, char *));
-extern void EXFUN (initialize_compiled_code_blocks, (void));
+extern int EXFUN (initialize_compiled_code_blocks, (void));
 extern void * scheme_hooks_low, * scheme_hooks_high;
 
-typedef SCHEME_OBJECT * EXFUN ((* compiled_block), (SCHEME_OBJECT *));
+#define TRAMPOLINE_FUDGE 20
+
+typedef SCHEME_OBJECT * EXFUN ((* code_block),
+                              (SCHEME_OBJECT *, unsigned long));
+
+typedef SCHEME_OBJECT * EXFUN ((* data_block), (unsigned long));
+
+struct compiled_entry_s
+{
+  code_block code;
+  unsigned long dispatch;
+};
+
+struct compiled_block_s
+{
+  char * name;
+  unsigned long dispatch;
+  data_block constructor;
+};
 
 int pc_zero_bits;
 char * interface_to_C_hook;
-static compiled_block * compiled_code_blocks;
-static char ** compiled_block_names;
-static int max_compiled_code_blocks, compiled_code_blocks_size;
-static SCHEME_OBJECT dummy_entry = SHARP_F;
+#define PSEUDO_STATIC
+PSEUDO_STATIC struct compiled_block_s * compiled_blocks;
+PSEUDO_STATIC struct compiled_entry_s * compiled_entries;
+PSEUDO_STATIC unsigned long max_compiled_entries, compiled_entries_size;
+PSEUDO_STATIC unsigned long max_compiled_blocks, compiled_blocks_size;
+static SCHEME_OBJECT dummy_entry = ((SCHEME_OBJECT) -1L);
 void
   * scheme_hooks_low = NULL,
   * scheme_hooks_high = NULL;
 
 SCHEME_OBJECT *
-DEFUN (trampoline_procedure, (trampoline), SCHEME_OBJECT * trampoline)
+DEFUN (trampoline_procedure, (trampoline, dispatch),
+       SCHEME_OBJECT * trampoline AND unsigned long dispatch)
 {
-  return (invoke_utility ((LABEL_TAG (trampoline)),
+  return (invoke_utility (((int) (* ((unsigned long *) trampoline))),
                          ((long) (TRAMPOLINE_STORAGE (trampoline))),
                          0, 0, 0));
 }
-\f
-void
+
+int
 DEFUN_VOID (NO_SUBBLOCKS)
 {
-  return;
+  return (0);
 }
 
+SCHEME_OBJECT *
+DEFUN (no_data, (base_dispatch), unsigned long base_dispatch)
+{
+  return ((SCHEME_OBJECT *) NULL);
+}
+
+SCHEME_OBJECT *
+DEFUN (uninitialized_data, (base_dispatch), unsigned long base_dispatch)
+{
+  /* Not yet assigned.  Cannot construct data. */
+  error_external_return ();
+}
+\f
 PTR
 DEFUN (lrealloc, (ptr, size),
        PTR ptr
@@ -113,105 +145,163 @@ DEFUN (lrealloc, (ptr, size),
     return (realloc (ptr, size));
 }
 
-int
-DEFUN (declare_compiled_code, (name, decl_proc, code_proc),
-       char * name
-       AND void EXFUN ((* decl_proc), (void))
-       AND SCHEME_OBJECT * EXFUN ((* code_proc), (SCHEME_OBJECT *)))
-{  
-  int index;
-
-  index = max_compiled_code_blocks;
-  max_compiled_code_blocks += 1;
-  if ((MAKE_LABEL_WORD (index, 0)) == dummy_entry)
-    return (0);
-
-  if (index >= compiled_code_blocks_size)
-  {
-    compiled_block * new_blocks;
-    char ** new_names;
-    compiled_code_blocks_size = ((compiled_code_blocks_size == 0)
-                                ? 10
-                                : (compiled_code_blocks_size * 2));
-    new_blocks =
-      ((compiled_block *)
-       (lrealloc (compiled_code_blocks,
-                 (compiled_code_blocks_size * (sizeof (compiled_block))))));
-    
-    new_names =
-      ((char **)
-       (lrealloc (compiled_block_names,
-                 (compiled_code_blocks_size * (sizeof (char *))))));
-
-    if ((new_blocks == ((compiled_block *) NULL))
-       || (new_names == ((char **) NULL)))
-      return (0);
-    compiled_code_blocks = new_blocks;
-    compiled_block_names = new_names;
-  }
-  compiled_code_blocks[index] = (code_proc);
-  compiled_block_names[index] = name;
-  (* decl_proc) ();
-  return (index);
-}
-
 void
 DEFUN_VOID (interface_initialize)
 {
+  extern long MAX_TRAMPOLINE;
   int i, pow, del;
   
   for (i = 0, pow = 1, del = ((sizeof (SCHEME_OBJECT)) / (sizeof (char)));
-       pow < del;
-       i+= 1)
+       pow < del; i+= 1)
     pow = (pow << 1);
   
   if (pow != del)
-    lose_big ("initialize_compiler: not a power of two");
-
+  {
+    /* Not a power of two -- ill-defined pc_zero_bits. */
+    outf_fatal ("interface_initialize: bad (sizeof (SCHEME_OBJECT)).\n");
+    Microcode_Termination (TERM_EXIT);
+  }
   pc_zero_bits = i;  
 
-  dummy_entry = (MAKE_LABEL_WORD (-1, 0));
   interface_to_C_hook = ((char *) &dummy_entry);
-  max_compiled_code_blocks = 0;
-  compiled_code_blocks_size = 0;
-  compiled_code_blocks = ((compiled_block *) NULL);
-  compiled_block_names = ((char **) NULL);
-  (void) declare_compiled_code ("", NO_SUBBLOCKS, trampoline_procedure);
-
-  initialize_compiled_code_blocks ();
+  max_compiled_entries = 0;
+  compiled_entries_size = 0;
+  compiled_entries = ((struct compiled_entry_s *) NULL);
+  compiled_blocks = ((struct compiled_block_s *) NULL);
+  
+  if (((declare_compiled_code ("#trampoline_code_block",
+                              (MAX_TRAMPOLINE + TRAMPOLINE_FUDGE),
+                              NO_SUBBLOCKS,
+                              trampoline_procedure))
+       != 0)
+#if 0
+      /* trampoline block is special. */
 
+      || ((declare_compiled_data ("#trampoline_code_block",
+                                 NO_SUBBLOCKS,
+                                 no_data))
+         != 0)
+#endif
+      || (initialize_compiled_code_blocks ()) != 0)
+  {
+    outf_fatal ("interface_initialize: error initializing compiled code.\n");
+    Microcode_Termination (TERM_EXIT);
+  }
   return;
 }
 \f
+int
+DEFUN (declare_compiled_code,
+       (name, nentries, decl_code, code_proc),
+       char * name
+       AND unsigned long nentries
+       AND int EXFUN ((* decl_code), (void))
+       AND SCHEME_OBJECT * EXFUN ((* code_proc),
+                                 (SCHEME_OBJECT *, unsigned long)))
+{
+  unsigned long dispatch = max_compiled_entries;
+  unsigned long n_dispatch = (dispatch + nentries);
+  unsigned long block_index = max_compiled_blocks;
+
+  if (n_dispatch < dispatch)
+    /* Wrap around */
+    return (-1);
+    
+  if (n_dispatch > compiled_entries_size)
+  {
+    struct compiled_entry_s * new_entries;
+    unsigned long new_entries_size = ((compiled_entries_size == 0)
+                                     ? 100
+                                     : ((compiled_entries_size * 3) / 2));
+    new_entries = ((struct compiled_entry_s *)
+                  (lrealloc (compiled_entries,
+                             (new_entries_size
+                              * (sizeof (struct compiled_entry_s))))));
+    if (new_entries == ((struct compiled_entry_s *) NULL))
+      return (-1);
+    compiled_entries_size = new_entries_size;
+    compiled_entries = new_entries;
+  }
+
+  if (block_index >= compiled_blocks_size)
+  {
+    struct compiled_block_s * new_blocks;
+    unsigned long new_blocks_size = ((compiled_blocks_size == 0)
+                                    ? 10
+                                    : ((compiled_blocks_size * 3) / 2));
+    new_blocks = ((struct compiled_block_s *)
+                 (lrealloc (compiled_blocks,
+                            (new_blocks_size
+                             * (sizeof (struct compiled_block_s))))));
+    if (new_blocks == ((struct compiled_block_s *) NULL))
+      return (-1);
+    compiled_blocks_size = new_blocks_size;
+    compiled_blocks = new_blocks;
+  }
+
+  max_compiled_entries = n_dispatch;
+  max_compiled_blocks = (block_index + 1);
+  
+  compiled_blocks[block_index].name = name;
+  compiled_blocks[block_index].dispatch = dispatch;
+  compiled_blocks[block_index].constructor = uninitialized_data;
+
+  for (block_index = dispatch; block_index < n_dispatch; block_index++)
+  {
+    compiled_entries[block_index].code = code_proc;
+    compiled_entries[block_index].dispatch = dispatch;
+  }
+
+  return (* decl_code) ();
+}
+\f
 /* For now this is a linear search.
    Not that it matters much, but we could easily
    make it binary.
  */
 
-int
+unsigned long
 DEFUN (find_compiled_block, (name), char * name)
 {
-  int i;
+  unsigned long i;
   
-  for (i = 1; i < max_compiled_code_blocks; i++)
-  {
-    if ((strcmp (name, compiled_block_names[i])) == 0)
+  for (i = 1; i < max_compiled_blocks; i++)
+    if ((strcmp (name, compiled_blocks[i].name)) == 0)
       return (i);
-  }
   return (0);
 }
 
+int
+DEFUN (declare_compiled_data,
+       (name, decl_data, data_proc),
+       char * name
+       AND int EXFUN ((* decl_data), (void))
+       AND SCHEME_OBJECT * EXFUN ((* data_proc), (unsigned long)))
+{
+  unsigned long slot = (find_compiled_block (name));
+
+  if (slot == 0)
+    return (-1);
+  
+  if ((compiled_blocks[slot].constructor != uninitialized_data)
+      && (compiled_blocks[slot].constructor != data_proc))
+    return (-1);
+
+  compiled_blocks[slot].constructor = data_proc;
+  return (* decl_data) ();  
+}
+
 SCHEME_OBJECT
 DEFUN (initialize_subblock, (name), char * name)
 {
-  SCHEME_OBJECT id, * ep, * block;
-  int slot = (find_compiled_block (name));
+  SCHEME_OBJECT * ep, * block;
+  unsigned long slot = (find_compiled_block (name));
 
   if (slot == 0)
     error_external_return ();
 
-  id = (MAKE_LABEL_WORD (slot, 0));
-  ep = ((* (compiled_code_blocks[slot])) (&id));
+  ep = ((* compiled_blocks[slot].constructor)
+       (compiled_blocks[slot].dispatch));
   Get_Compiled_Block (block, ep);
   return (MAKE_POINTER_OBJECT (TC_COMPILED_CODE_BLOCK, block));
 }
@@ -220,41 +310,39 @@ SCHEME_OBJECT *
 DEFUN (initialize_C_compiled_block, (argno, name),
        int argno AND char * name)
 {
-  int slot;
-  SCHEME_OBJECT id;
+  unsigned long slot;
+
   slot = (find_compiled_block (name));
   if (slot == 0)
     return ((SCHEME_OBJECT *) NULL);
 
-  id = (MAKE_LABEL_WORD (slot, 0));
-  return ((* (compiled_code_blocks[slot])) (&id));
+  return ((* compiled_blocks[slot].constructor)
+         (compiled_blocks[slot].dispatch));
 }
 \f
 void
 DEFUN (C_to_interface, (in_entry), PTR in_entry)
 {
+  extern long C_return_value;
   SCHEME_OBJECT * entry = ((SCHEME_OBJECT *) in_entry);
+
   while (1)
   {
-    unsigned int proc_index = ((unsigned int) (LABEL_PROCEDURE (entry)));
+    unsigned long entry_index = (* ((unsigned long *) entry));
 
-    if (proc_index >= ((unsigned int) max_compiled_code_blocks))
+    if (entry_index < ((unsigned long) max_compiled_entries))
+      entry = ((* (compiled_entries[entry_index].code))
+              (entry, compiled_entries[entry_index].dispatch));
+    else
     {
       if (entry != &dummy_entry)
-#if 0
       {
        /* We need to export C_return_value before enabling this code. */
        Store_Expression ((SCHEME_OBJECT) entry);
        C_return_value = (ERR_EXECUTE_MANIFEST_VECTOR);
-       return;
       }
-#else
-       lose_big ("C_to_interface: non-existent procedure");
-#endif
       return;
     }
-    else
-      entry = ((* (compiled_code_blocks [proc_index])) (entry));
   }
 }
 
@@ -280,37 +368,53 @@ DEFUN (multiply_with_overflow, (x, y, res), long x AND long y AND long * res)
   if (ans == SHARP_F)
   {
     /* Bogus... */
-    * res = (x * y);
+    (* res) = (x * y);
     return (1);
   }
   else
   {
-    * res = (FIXNUM_TO_LONG (ans));
+    (* res) = (FIXNUM_TO_LONG (ans));
     return (0);
   }
 }
 
-void
-DEFUN (lose_big, (msg), char * msg)
+static unsigned int
+DEFUN (hex_digit_to_int, (h_digit), char h_digit)
 {
-  fprintf (stderr, "\nlose_big: %s.\n", msg);
-  Microcode_Termination (TERM_EXIT);
-  /*NOTREACHED*/
-}
+  unsigned int digit = ((unsigned int) h_digit);
 
-void
-DEFUN (lose_big_1, (msg, arg), char * msg AND char * arg)
-{
-  fprintf (stderr, "\nlose_big: %s (%s).\n", msg, arg);
-  Microcode_Termination (TERM_EXIT);
-  /*NOTREACHED*/
+  return (((digit >= '0') && (digit <= '9'))
+         ? (digit - '0')
+         : (((digit >= 'A') && (digit <= 'F'))
+            ? ((digit - 'A') + 10)
+            : ((digit - 'a') + 10)));
 }
 
-void
-DEFUN_VOID (error_band_already_built)
+SCHEME_OBJECT
+DEFUN (digit_string_to_bit_string, (n_bits, n_digits, digits),
+       long n_bits AND long n_digits AND char * digits)
 {
-  lose_big ("Trying to initilize data with the wrong binary.");
-  /*NOTREACHED*/  
+  extern void EXFUN (clear_bit_string, (SCHEME_OBJECT));
+  extern SCHEME_OBJECT EXFUN (allocate_bit_string, (long));
+  extern void EXFUN (bit_string_set, (SCHEME_OBJECT, long, int));
+  SCHEME_OBJECT result = (allocate_bit_string (n_bits));
+  unsigned int digit, mask;
+  long i, posn;
+  int j;
+
+  posn = 0;
+  clear_bit_string (result);
+
+  for (i = 0; i < n_digits; i++)
+  {
+    digit = (hex_digit_to_int (*digits++));
+    for (j = 0, mask = 1;
+        j < 4;
+        j++, mask = (mask << 1), posn++)
+      if ((digit & mask) != 0)
+       bit_string_set (result, posn, 1);
+  }
+  return (result);
 }
 \f
 /* This avoids consing the string and symbol if it already exists. */
@@ -329,18 +433,6 @@ DEFUN (memory_to_symbol, (length, string),
   return (string_to_symbol (memory_to_string (length, string)));
 }
 
-static unsigned int
-DEFUN (hex_digit_to_int, (h_digit), char h_digit)
-{
-  unsigned int digit = ((unsigned int) h_digit);
-
-  return (((digit >= '0') && (digit <= '9'))
-         ? (digit - '0')
-         : (((digit >= 'A') && (digit <= 'F'))
-            ? ((digit - 'A') + 10)
-            : ((digit - 'a') + 10)));
-}
-
 static unsigned int
 DEFUN (digit_string_producer, (digit_ptr), char ** digit_ptr)
 {
@@ -361,33 +453,6 @@ DEFUN (digit_string_to_integer, (negative_p, n_digits, digits),
                                  16,
                                  ((int) negative_p)));
 }
-
-SCHEME_OBJECT
-DEFUN (digit_string_to_bit_string, (n_bits, n_digits, digits),
-       long n_bits AND long n_digits AND char * digits)
-{
-  extern void EXFUN (clear_bit_string, (SCHEME_OBJECT));
-  extern SCHEME_OBJECT EXFUN (allocate_bit_string, (long));
-  extern void EXFUN (bit_string_set, (SCHEME_OBJECT, long, int));
-  SCHEME_OBJECT result = (allocate_bit_string (n_bits));
-  unsigned int digit, mask;
-  long i, posn;
-  int j;
-
-  posn = 0;
-  clear_bit_string (result);
-
-  for (i = 0; i < n_digits; i++)
-  {
-    digit = (hex_digit_to_int (*digits++));
-    for (j = 0, mask = 1;
-        j < 4;
-        j++, mask = (mask << 1), posn++)
-      if ((digit & mask) != 0)
-       bit_string_set (result, posn, 1);
-  }
-  return (result);
-}
 \f
 #ifdef USE_STDARG
 
@@ -397,9 +462,11 @@ DEFUN (rconsm, (nargs, tail DOTS),
 {
   va_list arg_ptr;
   va_start (arg_ptr, tail);
+
   {
     int i;
     SCHEME_OBJECT result = tail;
+
     for (i = 1; i < nargs; i++)
       result = (cons ((va_arg (arg_ptr, SCHEME_OBJECT)),
                      result));
@@ -426,6 +493,7 @@ va_dcl
   {
     int i;
     SCHEME_OBJECT result = tail;
+
     for (i = 1; i < nargs; i++)
       result = (cons ((va_arg (arg_ptr, SCHEME_OBJECT)),
                      result));
index 789ee65ea4f2eae1f72b9b9b8a408347911cf3ce..bf51fae6603abb1f9a0d1c7e5059e62a0cbd5b54 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: c.h,v 1.3 1993/06/24 04:00:33 gjr Exp $
+$Id: c.h,v 1.4 1993/10/30 03:01:38 gjr Exp $
 
 Copyright (c) 1992-1993 Massachusetts Institute of Technology
 
@@ -40,23 +40,6 @@ MIT in each case. */
 \f
 #define COMPILER_PROCESSOR_TYPE                        COMPILER_LOSING_C_TYPE
 
-#define HALF_OBJECT_LENGTH (OBJECT_LENGTH / 2)
-#define HALF_OBJECT_LOW_MASK ((((unsigned long) 1) << HALF_OBJECT_LENGTH) - 1)
-#define HALF_OBJECT_HIGH_MASK (HALF_OBJECT_LOW_MASK << HALF_OBJECT_LENGTH)
-
-#define MAKE_LABEL_WORD(proc_tag,dispatch)                             \
-((SCHEME_OBJECT)                                                       \
- (((((unsigned long) proc_tag) & HALF_OBJECT_LOW_MASK)                 \
-   << HALF_OBJECT_LENGTH)                                              \
-  | (((unsigned long) dispatch) & HALF_OBJECT_LOW_MASK)))
-
-#define LABEL_PROCEDURE(pc)                                            \
-(((* ((unsigned long *) (pc))) >> HALF_OBJECT_LENGTH)                  \
- & HALF_OBJECT_LOW_MASK)
-
-#define LABEL_TAG(pc)                                                  \
-((* ((unsigned long *) (pc))) & HALF_OBJECT_LOW_MASK)
-
 #define WRITE_LABEL_DESCRIPTOR(entry,kind,offset) do                   \
 {                                                                      \
   SCHEME_OBJECT * ent = ((SCHEME_OBJECT *) (entry));                   \
@@ -107,10 +90,13 @@ extern int pc_zero_bits;
   ((((SCHEME_OBJECT *) (tramp_entry)) - TRAMPOLINE_BLOCK_TO_ENTRY) +   \
    (2 + TRAMPOLINE_ENTRY_SIZE)) 
 
+/* This depends on knowledge that the trampoline block is the first
+   compiled code block.
+ */
+
 #define STORE_TRAMPOLINE_ENTRY(entry_address, index) do                        \
 {                                                                      \
-  ((SCHEME_OBJECT *) (entry_address))[0]                               \
-    = (MAKE_LABEL_WORD (0, (index)));                                  \
+  ((SCHEME_OBJECT *) (entry_address))[0] = ((SCHEME_OBJECT) (index));  \
 } while (0)
 
 /* An execute cache contains a compiled entry for the callee,