* 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.
This commit is contained in:
Matthew Green 2002-01-12 10:21:12 +00:00
parent 3abd2e019d
commit 43c4bab055
8 changed files with 211 additions and 27 deletions

View 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.

View 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 \

View 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;

View 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);

View 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;

View 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);

View 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)

View 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);