+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.
./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 \
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;
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);
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;
}
+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)
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);
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 */
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);
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;
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;
} while (0)
#define ZALLOC(TYPE) (TYPE*)zalloc(sizeof(TYPE))
+#define NZALLOC(TYPE,N) ((TYPE*) zalloc (sizeof(TYPE) * (N)))
extern void *zalloc
(long size);
#include <stdlib.h>
#endif
-struct _table {
+typedef struct _open_table open_table;
+struct _open_table {
size_t size;
char *buffer;
char *pos;
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) {
/* 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'
else
break;
}
- if (*file->pos == '\0')
- return NULL;
/* create this new entry */
entry = (table_entry*)zalloc(sizeof(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,
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);