* Makefile.in (tmp-igen): Pass -I $(srcdir) to igen.
authorMatthew Green <mrg@redhat.com>
Sat, 12 Jan 2002 10:21:12 +0000 (10:21 +0000)
committerMatthew Green <mrg@redhat.com>
Sat, 12 Jan 2002 10:21:12 +0000 (10:21 +0000)
* igen.c (main): Change -I to add include paths for :include:
files.
Implement -G as per sim/igen, with just gen-icache=N support.
Call load_insn_table() with the built include path.

* ld-insn.c (parse_include_entry): New. Load an :include: file.
(load_insn_table): New `includes' argument.  Look for :include:
entries and call parse_include_entry() for them.
(main): Adjust load_insn_table() call.
* ld-insn.h (model_include_fields): New enum.
(load_insn_table): Update prototype.
* table.c (struct _open_table, struct _table): Rework
structures to handle included files.
(table_push): Move the guts of table_open() here.

* table.c (struct _open table, struct table): Make table object an
indirect ptr to the current table file.
(current_line, new_table_entry, next_line): Make file arg type
open_table.
(table_open): Use table_push.
(table_entry_read): Point variable file at current table, at eof, pop
last open table.

* misc.h (NZALLOC): New macro. From sim/igen.

* table.h, table.c (table_push): New function.

sim/ppc/ChangeLog
sim/ppc/Makefile.in
sim/ppc/igen.c
sim/ppc/ld-insn.c
sim/ppc/ld-insn.h
sim/ppc/misc.h
sim/ppc/table.c
sim/ppc/table.h

index 24db4a9e425669c35d9058af10206d62d9a4f896..103a83c5352597dff873f382937e90cc443f39b6 100644 (file)
@@ -1,3 +1,33 @@
+2002-01-12  matthew green  <mrg@redhat.com>
+
+       * Makefile.in (tmp-igen): Pass -I $(srcdir) to igen.
+       * igen.c (main): Change -I to add include paths for :include:
+       files.
+       Implement -G as per sim/igen, with just gen-icache=N support.
+       Call load_insn_table() with the built include path.
+
+       * ld-insn.c (parse_include_entry): New. Load an :include: file.
+       (load_insn_table): New `includes' argument.  Look for :include:
+       entries and call parse_include_entry() for them.
+       (main): Adjust load_insn_table() call.
+       * ld-insn.h (model_include_fields): New enum.
+       (load_insn_table): Update prototype.
+       * table.c (struct _open_table, struct _table): Rework
+       structures to handle included files.
+       (table_push): Move the guts of table_open() here.
+
+       * table.c (struct _open table, struct table): Make table object an
+       indirect ptr to the current table file.
+       (current_line, new_table_entry, next_line): Make file arg type
+       open_table.
+       (table_open): Use table_push.
+       (table_entry_read): Point variable file at current table, at eof, pop
+       last open table.
+
+       * misc.h (NZALLOC): New macro. From sim/igen.
+
+       * table.h, table.c (table_push): New function.
+
 2002-01-04  matthew green  <mrg@redhat.com>
 
        * bits.c (LSMASKED64): New inline function.
index 0f7869389f8d415a3d41be4863cee7a467741dd0..6776992156718b763e7f238387ffb231d3b93123 100644 (file)
@@ -464,7 +464,7 @@ tmp-igen: igen ppc-instructions $(IGEN_OPCODE_RULES) ppc-cache-rules $(srcdir)/.
        ./igen  $(IGEN_FLAGS) \
                -o $(srcdir)/$(IGEN_OPCODE_RULES) \
                -k $(srcdir)/ppc-cache-rules \
-               -i $(srcdir)/ppc-instructions \
+               -I $(srcdir) -i $(srcdir)/ppc-instructions \
                -n icache.h    -hc tmp-icache.h \
                -n icache.c    -c  tmp-icache.c \
                -n semantics.h -hs tmp-semantics.h \
index ae81142fac563f31d186a5ce8fd57961a6f4538f..7008e961e0a8f3e6800113bc88306ceb0ab93af0 100644 (file)
@@ -347,6 +347,7 @@ main(int argc,
   decode_table *decode_rules = NULL;
   filter *filters = NULL;
   insn_table *instructions = NULL;
+  table_include *includes = NULL;
   char *real_file_name = NULL;
   int is_header = 0;
   int ch;
@@ -405,9 +406,49 @@ main(int argc,
     case 'E':
       generate_expanded_instructions = 1;
       break;
+    case 'G':
+      {
+       int enable_p;
+       char *argp;
+       if (strncmp (optarg, "no-", strlen ("no-")) == 0)
+         {
+           argp = optarg + strlen ("no-");
+           enable_p = 0;
+         }
+       else if (strncmp (optarg, "!", strlen ("!")) == 0)
+         {
+           argp = optarg + strlen ("no-");
+           enable_p = 0;
+         }
+       else
+         {
+           argp = optarg;
+           enable_p = 1;
+         }
+        if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0)
+          {
+            switch (argp[strlen ("gen-icache")])
+              {
+              case '=':
+               icache_size = atoi (argp + strlen ("gen-icache") + 1);
+               code |= generate_with_icache;
+                break;
+              case '\0':
+               code |= generate_with_icache;
+                break;
+              default:
+                error (NULL, "Expecting -Ggen-icache or -Ggen-icache=<N>\n");
+              }
+          }
+       }
     case 'I':
-      icache_size = a2i(optarg);
-      code |= generate_with_icache;
+      {
+       table_include **dir = &includes;
+       while ((*dir) != NULL)
+         dir = &(*dir)->next;
+       (*dir) = ZALLOC (table_include);
+       (*dir)->dir = strdup (optarg);
+      }
       break;
     case 'N':
       generate_smp = a2i(optarg);
@@ -439,7 +480,7 @@ main(int argc,
        fprintf(stderr, "Must specify decode and cache tables\n");
        exit (1);
       }
-      instructions = load_insn_table(optarg, decode_rules, filters);
+      instructions = load_insn_table(optarg, decode_rules, filters, includes);
       fprintf(stderr, "\texpanding ...\n");
       insn_table_expand_insns(instructions);
       break;
index a190d85a83f3cc0bb8431f59c1d5350d0f8b213d..28b6b5598979218317c99e23c5599059f0affbab 100644 (file)
@@ -191,6 +191,24 @@ parse_insn_format(table_entry *entry,
 }
 
 
+void
+parse_include_entry (table *file,
+                     table_entry *file_entry,
+                    filter *filters,
+                    table_include *includes)
+{
+  /* parse the include file_entry */
+  if (file_entry->nr_fields < 4)
+    error ("Incorrect nr fields for include record\n");
+  /* process it */
+  if (!is_filtered_out(file_entry->fields[include_flags], filters))
+    {
+      table_push (file, includes,
+                file_entry->fields[include_path],
+               file_entry->nr_fields, file_entry->nr_fields);
+    }
+}
+
 static void
 model_table_insert(insn_table *table,
                   table_entry *file_entry)
@@ -313,7 +331,8 @@ insn_table_insert_insn(insn_table *table,
 insn_table *
 load_insn_table(const char *file_name,
                decode_table *decode_rules,
-               filter *filters)
+               filter *filters,
+               table_include *includes)
 {
   table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);
   insn_table *table = ZALLOC(insn_table);
@@ -343,6 +362,10 @@ load_insn_table(const char *file_name,
     else if (it_is("model-data", file_entry->fields[insn_flags])) {
       model_table_insert_specific(table, file_entry, &model_data, &last_model_data);
     }
+    else if (it_is("include", file_entry->fields[insn_form])
+             && !is_filtered_out(file_entry->fields[insn_flags], filters)) {
+      parse_include_entry (file, file_entry, filters, includes);
+    }
     else {
       insn_fields *fields;
       /* skip instructions that aren't relevant to the mode */
@@ -915,7 +938,7 @@ main(int argc, char **argv)
   hi_bit_nr = a2i(argv[2]);
   ASSERT(hi_bit_nr < insn_bit_size);
   decode_rules = load_decode_table(argv[3], hi_bit_nr);
-  instructions = load_insn_table(argv[4], decode_rules, filters);
+  instructions = load_insn_table(argv[4], decode_rules, filters, NULL);
   insn_table_expand_insns(instructions);
 
   dump_insn_table(instructions, 0, -1);
index e800f0dac23681502eb55a9f0849ade4811f3066..06bf838b70ebfca1754896434ec1745d9b08f383 100644 (file)
@@ -134,6 +134,11 @@ typedef enum {
   model_default = insn_comment,
 } model_table_fields;
 
+typedef enum {
+  include_flags = insn_flags,
+  include_path = insn_name,
+} model_include_fields;
+
 typedef struct _insn insn;
 struct _insn {
   table_entry *file_entry;
@@ -183,7 +188,8 @@ typedef enum {
 extern insn_table *load_insn_table
 (const char *file_name,
  decode_table *decode_rules,
- filter *filters);
+ filter *filters,
+ table_include *includes);
 
 model *models;
 model *last_model;
index 041bd6d2cacf0addb8561d0646580defcb111f55..50301fd64fc2886091d4f4189e3e006463a7aedb 100644 (file)
@@ -58,6 +58,7 @@ do { \
 } while (0)
 
 #define ZALLOC(TYPE) (TYPE*)zalloc(sizeof(TYPE))
+#define NZALLOC(TYPE,N) ((TYPE*) zalloc (sizeof(TYPE) * (N)))
 
 extern void *zalloc
 (long size);
index 1994d0d3ce01073e5fd5fa86c81227c09531d376..d9538b3d7d87a4f9c8bf63db3013da8debb85927 100644 (file)
@@ -38,7 +38,8 @@
 #include <stdlib.h>
 #endif
 
-struct _table {
+typedef struct _open_table open_table;
+struct _open_table {
   size_t size;
   char *buffer;
   char *pos;
@@ -46,32 +47,70 @@ struct _table {
   int nr_fields;
   int nr_model_fields;
   char *file_name;
+  open_table *parent;
+  table *root;
+};
+struct _table {
+  open_table *current;
 };
 
-extern table *
-table_open(const char *file_name,
-          int nr_fields,
-          int nr_model_fields)
+void
+table_push (table *root,
+           table_include *includes,
+           const char *file_name,
+           int nr_fields,
+           int nr_model_fields)
+
 {
   int fd;
   struct stat stat_buf;
-  table *file;
+  open_table *file;
+  table_include dummy;
+  table_include *include = &dummy;
   int nr;
 
+  /* dummy up a search of this directory */
+  dummy.next = includes;
+  dummy.dir = "";
+
   /* create a file descriptor */
-  file = ZALLOC(table);
+  file = ZALLOC (open_table);
   ASSERT(file != NULL);
   file->nr_fields = nr_fields;
   file->nr_model_fields = nr_model_fields;
-
-  /* save the file name */
-  file->file_name = (char*)zalloc(strlen(file_name) + 1);
-  ASSERT(file->file_name != NULL);
-  strcpy(file->file_name, file_name);
-
-  /* open the file */
-  fd = open(file->file_name, O_RDONLY, 0);
-  ASSERT(fd >= 0);
+  file->root = root;
+  file->parent = root->current;
+  root->current = file;
+  
+  while (1)
+    {
+      /* save the file name */
+      char *dup_name = NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
+      if (dup_name == NULL)
+       {
+         perror (file_name);
+         exit (1);
+       }
+      if (include->dir[0] != '\0')
+       {
+         strcat (dup_name, include->dir);
+         strcat (dup_name, "/");
+       }
+      strcat (dup_name, file_name);
+      file->file_name = dup_name;
+      /* open the file */
+      fd = open (dup_name, O_RDONLY, 0);
+      if (fd >= 0)
+       break;
+      /* zfree (dup_name); */
+      if (include->next == NULL)
+       {
+         error ("Problem opening file `%s'\n", file_name);
+         perror (file_name);
+         exit (1);
+       }
+      include = include->next;
+  }
 
   /* determine the size */
   if (fstat(fd, &stat_buf) < 0) {
@@ -102,18 +141,47 @@ table_open(const char *file_name,
 
   /* done */
   close(fd);
-  return file;
 }
 
+extern table *
+table_open(const char *file_name,
+          int nr_fields,
+          int nr_model_fields)
+{
+  table *root;
+
+  /* create a file descriptor */
+  root = ZALLOC (table);
+  if (root == NULL)
+    {
+      perror (file_name);
+      exit (1);
+    }
+
+  table_push (root, NULL, file_name, nr_fields, nr_model_fields);
+  return root;
+}
 
 extern table_entry *
-table_entry_read(table *file)
+table_entry_read(table *root)
 {
+  open_table *file = root->current;
   int field;
   table_entry *entry;
 
   /* skip comments/blanks */
   while(1) {
+    /* end-of-file? */
+    while (*file->pos == '\0')
+      {
+        if (file->parent != NULL)
+          {
+            file = file->parent;
+            root->current = file;
+          }
+        else
+          return NULL;
+      }
     /* leading white space */
     while (*file->pos != '\0'
           && *file->pos != '\n'
@@ -133,8 +201,6 @@ table_entry_read(table *file)
     else
       break;
   }
-  if (*file->pos == '\0')
-    return NULL;
 
   /* create this new entry */
   entry = (table_entry*)zalloc(sizeof(table_entry)
index 509fb22870eac391e83b6f25177434900c85027b..863c9258560841fb52ecd57c8680b7e46cf62fcf 100644 (file)
@@ -42,6 +42,13 @@ struct _table_entry {
   char *fields[0];      /* User defined */
 };
 
+/* List of directories to search when opening a pushed file.  Current
+   directory is always searched first */
+typedef struct _table_include table_include;
+struct _table_include {
+  char *dir;
+  table_include *next;
+};
 
 extern table *table_open
 (const char *file_name,
@@ -51,6 +58,16 @@ extern table *table_open
 extern table_entry *table_entry_read
 (table *file);
 
+/* Push the the state of the current file and open FILE_NAME.  When
+   the end of FILE_NAME is reached, return to the pushed file */
+
+extern void table_push
+(table *file,
+ table_include *search,
+ const char *file_name,
+ int nr_fields,
+ int nr_model_fields);
+
 extern void dump_table_entry
 (table_entry *entry,
  int indent);