diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index 24db4a9e42..103a83c535 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,3 +1,33 @@ +2002-01-12 matthew green + + * 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 * bits.c (LSMASKED64): New inline function. diff --git a/sim/ppc/Makefile.in b/sim/ppc/Makefile.in index 0f7869389f..6776992156 100644 --- a/sim/ppc/Makefile.in +++ b/sim/ppc/Makefile.in @@ -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 \ diff --git a/sim/ppc/igen.c b/sim/ppc/igen.c index ae81142fac..7008e961e0 100644 --- a/sim/ppc/igen.c +++ b/sim/ppc/igen.c @@ -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"); + } + } + } 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; diff --git a/sim/ppc/ld-insn.c b/sim/ppc/ld-insn.c index a190d85a83..28b6b55989 100644 --- a/sim/ppc/ld-insn.c +++ b/sim/ppc/ld-insn.c @@ -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); diff --git a/sim/ppc/ld-insn.h b/sim/ppc/ld-insn.h index e800f0dac2..06bf838b70 100644 --- a/sim/ppc/ld-insn.h +++ b/sim/ppc/ld-insn.h @@ -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; diff --git a/sim/ppc/misc.h b/sim/ppc/misc.h index 041bd6d2ca..50301fd64f 100644 --- a/sim/ppc/misc.h +++ b/sim/ppc/misc.h @@ -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); diff --git a/sim/ppc/table.c b/sim/ppc/table.c index 1994d0d3ce..d9538b3d7d 100644 --- a/sim/ppc/table.c +++ b/sim/ppc/table.c @@ -38,7 +38,8 @@ #include #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) diff --git a/sim/ppc/table.h b/sim/ppc/table.h index 509fb22870..863c925856 100644 --- a/sim/ppc/table.h +++ b/sim/ppc/table.h @@ -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);