2002-11-21 Andrew Cagney <ac131313@redhat.com>
* filter.c: Re-indent. * filter.h, filter_host.h, gen-engine.c, gen-engine.h: Ditto. * gen-icache.c, gen-icache.h, gen-idecode.c: Ditto. * gen-idecode.h, gen-itable.c, gen-itable.h: Ditto. * gen-model.c, gen-model.h, gen-semantics.c: Ditto. * gen-semantics.h, gen-support.c, gen-support.h: Ditto. * gen.c, gen.h, igen.c, igen.h, ld-cache.c, ld-cache.h: Ditto. * ld-decode.c, ld-decode.h, ld-insn.c, ld-insn.h, lf.c: Ditto. * lf.h, misc.c, misc.h, table.c, table.h: Ditto.
This commit is contained in:
parent
feaee4bdbb
commit
4e0bf4c4d0
|
@ -1,3 +1,15 @@
|
|||
2002-11-21 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* filter.c: Re-indent.
|
||||
* filter.h, filter_host.h, gen-engine.c, gen-engine.h: Ditto.
|
||||
* gen-icache.c, gen-icache.h, gen-idecode.c: Ditto.
|
||||
* gen-idecode.h, gen-itable.c, gen-itable.h: Ditto.
|
||||
* gen-model.c, gen-model.h, gen-semantics.c: Ditto.
|
||||
* gen-semantics.h, gen-support.c, gen-support.h: Ditto.
|
||||
* gen.c, gen.h, igen.c, igen.h, ld-cache.c, ld-cache.h: Ditto.
|
||||
* ld-decode.c, ld-decode.h, ld-insn.c, ld-insn.h, lf.c: Ditto.
|
||||
* lf.h, misc.c, misc.h, table.c, table.h: Ditto.
|
||||
|
||||
2002-11-21 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* Makefile.in: Update copyright. IGEN contributed to the FSF.
|
||||
|
|
|
@ -38,15 +38,15 @@
|
|||
#include "lf.h"
|
||||
#include "filter.h"
|
||||
|
||||
struct _filter {
|
||||
struct _filter
|
||||
{
|
||||
char *member;
|
||||
filter *next;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
filter_parse (filter **filters,
|
||||
const char *filt)
|
||||
filter_parse (filter **filters, const char *filt)
|
||||
{
|
||||
while (strlen (filt) > 0)
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ filter_parse (filter **filters,
|
|||
filter **last;
|
||||
/* break out a member of the filter list */
|
||||
const char *flag = filt;
|
||||
unsigned /*size_t*/ len;
|
||||
unsigned /*size_t */ len;
|
||||
filt = strchr (filt, ',');
|
||||
if (filt == NULL)
|
||||
{
|
||||
|
@ -68,13 +68,12 @@ filter_parse (filter **filters,
|
|||
}
|
||||
/* find an insertion point - sorted order */
|
||||
last = filters;
|
||||
while (*last != NULL
|
||||
&& strncmp (flag, (*last)->member, len) > 0)
|
||||
while (*last != NULL && strncmp (flag, (*last)->member, len) > 0)
|
||||
last = &(*last)->next;
|
||||
if (*last != NULL
|
||||
&& strncmp (flag, (*last)->member, len) == 0
|
||||
&& strlen ((*last)->member) == len)
|
||||
continue; /* duplicate */
|
||||
continue; /* duplicate */
|
||||
/* create an entry for that member */
|
||||
new_filter = ZALLOC (filter);
|
||||
new_filter->member = NZALLOC (char, len + 1);
|
||||
|
@ -87,14 +86,13 @@ filter_parse (filter **filters,
|
|||
|
||||
|
||||
void
|
||||
filter_add (filter **set,
|
||||
filter *add)
|
||||
filter_add (filter **set, filter *add)
|
||||
{
|
||||
while (add != NULL)
|
||||
{
|
||||
int cmp;
|
||||
if (*set == NULL)
|
||||
cmp = 1; /* set->member > add->member */
|
||||
cmp = 1; /* set->member > add->member */
|
||||
else
|
||||
cmp = strcmp ((*set)->member, add->member);
|
||||
if (cmp > 0)
|
||||
|
@ -112,7 +110,7 @@ filter_add (filter **set,
|
|||
/* already in set */
|
||||
add = add->next;
|
||||
}
|
||||
else /* cmp < 0 */
|
||||
else /* cmp < 0 */
|
||||
{
|
||||
/* not reached insertion point */
|
||||
set = &(*set)->next;
|
||||
|
@ -122,8 +120,7 @@ filter_add (filter **set,
|
|||
|
||||
|
||||
int
|
||||
filter_is_subset (filter *superset,
|
||||
filter *subset)
|
||||
filter_is_subset (filter *superset, filter *subset)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
@ -131,21 +128,20 @@ filter_is_subset (filter *superset,
|
|||
if (subset == NULL)
|
||||
return 1;
|
||||
if (superset == NULL)
|
||||
return 0; /* subset isn't finished */
|
||||
return 0; /* subset isn't finished */
|
||||
cmp = strcmp (subset->member, superset->member);
|
||||
if (cmp < 0)
|
||||
return 0; /* not found */
|
||||
return 0; /* not found */
|
||||
else if (cmp == 0)
|
||||
subset = subset->next; /* found */
|
||||
subset = subset->next; /* found */
|
||||
else if (cmp > 0)
|
||||
superset = superset->next; /* later in list? */
|
||||
superset = superset->next; /* later in list? */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
filter_is_common (filter *l,
|
||||
filter *r)
|
||||
filter_is_common (filter *l, filter *r)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
@ -158,7 +154,7 @@ filter_is_common (filter *l,
|
|||
if (cmp < 0)
|
||||
l = l->next;
|
||||
else if (cmp == 0)
|
||||
return 1; /* common member */
|
||||
return 1; /* common member */
|
||||
else if (cmp > 0)
|
||||
r = r->next;
|
||||
}
|
||||
|
@ -166,8 +162,7 @@ filter_is_common (filter *l,
|
|||
|
||||
|
||||
int
|
||||
filter_is_member (filter *filt,
|
||||
const char *flag)
|
||||
filter_is_member (filter *filt, const char *flag)
|
||||
{
|
||||
int index = 1;
|
||||
while (filt != NULL)
|
||||
|
@ -182,68 +177,72 @@ filter_is_member (filter *filt,
|
|||
|
||||
|
||||
int
|
||||
is_filtered_out (filter *filters,
|
||||
const char *flags)
|
||||
is_filtered_out (filter *filters, const char *flags)
|
||||
{
|
||||
while (strlen(flags) > 0) {
|
||||
int present;
|
||||
filter *filt = filters;
|
||||
/* break the string up */
|
||||
char *end = strchr(flags, ',');
|
||||
char *next;
|
||||
unsigned /*size_t*/ len;
|
||||
if (end == NULL) {
|
||||
end = strchr(flags, '\0');
|
||||
next = end;
|
||||
while (strlen (flags) > 0)
|
||||
{
|
||||
int present;
|
||||
filter *filt = filters;
|
||||
/* break the string up */
|
||||
char *end = strchr (flags, ',');
|
||||
char *next;
|
||||
unsigned /*size_t */ len;
|
||||
if (end == NULL)
|
||||
{
|
||||
end = strchr (flags, '\0');
|
||||
next = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
next = end + 1;
|
||||
}
|
||||
len = end - flags;
|
||||
/* check that it is present */
|
||||
present = 0;
|
||||
filt = filters;
|
||||
while (filt != NULL)
|
||||
{
|
||||
if (strncmp (flags, filt->member, len) == 0
|
||||
&& strlen (filt->member) == len)
|
||||
{
|
||||
present = 1;
|
||||
break;
|
||||
}
|
||||
filt = filt->next;
|
||||
}
|
||||
if (!present)
|
||||
return 1;
|
||||
flags = next;
|
||||
}
|
||||
else {
|
||||
next = end + 1;
|
||||
}
|
||||
len = end - flags;
|
||||
/* check that it is present */
|
||||
present = 0;
|
||||
filt = filters;
|
||||
while (filt != NULL) {
|
||||
if (strncmp(flags, filt->member, len) == 0
|
||||
&& strlen(filt->member) == len) {
|
||||
present = 1;
|
||||
break;
|
||||
}
|
||||
filt = filt->next;
|
||||
}
|
||||
if (!present)
|
||||
return 1;
|
||||
flags = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int
|
||||
it_is (const char *flag,
|
||||
const char *flags)
|
||||
it_is (const char *flag, const char *flags)
|
||||
{
|
||||
int flag_len = strlen(flag);
|
||||
while (*flags != '\0') {
|
||||
if (!strncmp(flags, flag, flag_len)
|
||||
&& (flags[flag_len] == ',' || flags[flag_len] == '\0'))
|
||||
return 1;
|
||||
while (*flags != ',') {
|
||||
if (*flags == '\0')
|
||||
return 0;
|
||||
int flag_len = strlen (flag);
|
||||
while (*flags != '\0')
|
||||
{
|
||||
if (!strncmp (flags, flag, flag_len)
|
||||
&& (flags[flag_len] == ',' || flags[flag_len] == '\0'))
|
||||
return 1;
|
||||
while (*flags != ',')
|
||||
{
|
||||
if (*flags == '\0')
|
||||
return 0;
|
||||
flags++;
|
||||
}
|
||||
flags++;
|
||||
}
|
||||
flags++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
char *
|
||||
filter_next (filter *set,
|
||||
char *member)
|
||||
filter_next (filter *set, char *member)
|
||||
{
|
||||
while (set != NULL)
|
||||
{
|
||||
|
@ -256,10 +255,7 @@ filter_next (filter *set,
|
|||
|
||||
|
||||
void
|
||||
dump_filter (lf *file,
|
||||
char *prefix,
|
||||
filter *set,
|
||||
char *suffix)
|
||||
dump_filter (lf *file, char *prefix, filter *set, char *suffix)
|
||||
{
|
||||
char *member;
|
||||
lf_printf (file, "%s", prefix);
|
||||
|
@ -281,20 +277,21 @@ dump_filter (lf *file,
|
|||
|
||||
#ifdef MAIN
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
filter *subset = NULL;
|
||||
filter *superset = NULL;
|
||||
lf *l;
|
||||
int i;
|
||||
if (argc < 2) {
|
||||
printf("Usage: filter <subset> <filter> ...\n");
|
||||
exit (1);
|
||||
}
|
||||
if (argc < 2)
|
||||
{
|
||||
printf ("Usage: filter <subset> <filter> ...\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* load the filter up */
|
||||
filter_parse (&subset, argv[1]);
|
||||
for (i = 2; i < argc; i++)
|
||||
for (i = 2; i < argc; i++)
|
||||
filter_parse (&superset, argv[i]);
|
||||
|
||||
/* dump various info */
|
||||
|
@ -352,7 +349,7 @@ main(int argc, char **argv)
|
|||
dump_filter (l, "{", superset, " }");
|
||||
lf_printf (l, "\n");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,62 +28,44 @@ typedef struct _filter filter;
|
|||
|
||||
/* parse the list merging any flags into the filter */
|
||||
|
||||
extern void filter_parse
|
||||
(filter **filters,
|
||||
const char *filt);
|
||||
extern void filter_parse (filter **filters, const char *filt);
|
||||
|
||||
|
||||
/* add the second filter to the first */
|
||||
|
||||
extern void filter_add
|
||||
(filter **filters,
|
||||
filter *add);
|
||||
extern void filter_add (filter **filters, filter *add);
|
||||
|
||||
|
||||
|
||||
/* returns true if SUB is a strict subset of SUPER. For an empty set
|
||||
is a member of any set */
|
||||
|
||||
extern int filter_is_subset
|
||||
(filter *superset,
|
||||
filter *subset);
|
||||
extern int filter_is_subset (filter *superset, filter *subset);
|
||||
|
||||
|
||||
/* return true if there is at least one member common to the two
|
||||
filters */
|
||||
|
||||
extern int filter_is_common
|
||||
(filter *l,
|
||||
filter *r);
|
||||
extern int filter_is_common (filter *l, filter *r);
|
||||
|
||||
|
||||
/* returns the index (pos + 1) if the name is in the filter. */
|
||||
|
||||
extern int filter_is_member
|
||||
(filter *set,
|
||||
const char *flag);
|
||||
extern int filter_is_member (filter *set, const char *flag);
|
||||
|
||||
|
||||
/* returns true if one of the flags is not present in the filter.
|
||||
=== !filter_is_subset (filter_parse (NULL, flags), filters) */
|
||||
int is_filtered_out
|
||||
(filter *filters,
|
||||
const char *flags);
|
||||
int is_filtered_out (filter *filters, const char *flags);
|
||||
|
||||
|
||||
/* returns the next member of the filter set that follows MEMBER.
|
||||
Member does not need to be an elememt of the filter set. Next of
|
||||
"" is the first non-empty member */
|
||||
char *filter_next
|
||||
(filter *set,
|
||||
char *member);
|
||||
char *filter_next (filter *set, char *member);
|
||||
|
||||
|
||||
|
||||
/* for debugging */
|
||||
|
||||
extern void dump_filter
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
filter *filt,
|
||||
char *suffix);
|
||||
extern void dump_filter (lf *file, char *prefix, filter *filt, char *suffix);
|
||||
|
|
|
@ -25,6 +25,5 @@
|
|||
#define _FILTER_HOST_H
|
||||
|
||||
/* Remove directory part from filename */
|
||||
extern const char *
|
||||
filter_filename(const char *filename);
|
||||
extern const char *filter_filename (const char *filename);
|
||||
#endif
|
||||
|
|
|
@ -65,25 +65,25 @@ print_engine_issue_postfix_hook (lf *file)
|
|||
|
||||
|
||||
static void
|
||||
print_run_body (lf *file,
|
||||
gen_entry *table)
|
||||
print_run_body (lf *file, gen_entry *table)
|
||||
{
|
||||
/* Output the function to execute real code:
|
||||
|
||||
|
||||
Unfortunatly, there are multiple cases to consider vis:
|
||||
|
||||
|
||||
<icache> X <smp>
|
||||
|
||||
|
||||
Consequently this function is written in multiple different ways */
|
||||
|
||||
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
if (!options.gen.smp)
|
||||
{
|
||||
lf_printf (file, "%sinstruction_address cia;\n", options.module.global.prefix.l);
|
||||
lf_printf (file, "%sinstruction_address cia;\n",
|
||||
options.module.global.prefix.l);
|
||||
}
|
||||
lf_printf (file, "int current_cpu = next_cpu_nr;\n");
|
||||
|
||||
|
||||
if (options.gen.icache)
|
||||
{
|
||||
lf_printf (file, "/* flush the icache of a possible break insn */\n");
|
||||
|
@ -93,10 +93,10 @@ print_run_body (lf *file,
|
|||
lf_printf (file, " cpu_flush_icache (STATE_CPU (sd, cpu_nr));\n");
|
||||
lf_printf (file, "}\n");
|
||||
}
|
||||
|
||||
|
||||
if (!options.gen.smp)
|
||||
{
|
||||
|
||||
|
||||
lf_putstr (file, "\
|
||||
/* CASE 1: NO SMP (with or with out instruction cache).\n\
|
||||
\n\
|
||||
|
@ -124,16 +124,16 @@ cache. */\n\
|
|||
lf_putstr (file, "while (1)\n");
|
||||
lf_putstr (file, " {\n");
|
||||
lf_indent (file, +4);
|
||||
|
||||
|
||||
lf_printf (file, "%sinstruction_address nia;\n",
|
||||
options.module.global.prefix.l);
|
||||
|
||||
lf_printf (file, "\n");
|
||||
if (!options.gen.icache)
|
||||
{
|
||||
lf_printf (file, "%sinstruction_word instruction_0 = IMEM%d (cia);\n",
|
||||
options.module.global.prefix.l,
|
||||
options.insn_bit_size);
|
||||
lf_printf (file,
|
||||
"%sinstruction_word instruction_0 = IMEM%d (cia);\n",
|
||||
options.module.global.prefix.l, options.insn_bit_size);
|
||||
print_engine_issue_prefix_hook (file);
|
||||
print_idecode_body (file, table, "nia = ");
|
||||
print_engine_issue_postfix_hook (file);
|
||||
|
@ -146,7 +146,8 @@ cache. */\n\
|
|||
lf_putstr (file, " {\n");
|
||||
lf_indent (file, -4);
|
||||
lf_putstr (file, "/* cache hit */\n");
|
||||
lf_putstr (file, "idecode_semantic *const semantic = cache_entry->semantic;\n");
|
||||
lf_putstr (file,
|
||||
"idecode_semantic *const semantic = cache_entry->semantic;\n");
|
||||
lf_putstr (file, "cia = semantic (cpu, cache_entry, cia);\n");
|
||||
/* tail */
|
||||
lf_indent (file, -4);
|
||||
|
@ -162,7 +163,8 @@ cache. */\n\
|
|||
lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n",
|
||||
options.insn_bit_size);
|
||||
lf_putstr (file, "if (WITH_MON != 0)\n");
|
||||
lf_putstr (file, " mon_event (mon_event_icache_miss, cpu, cia);\n");
|
||||
lf_putstr (file,
|
||||
" mon_event (mon_event_icache_miss, cpu, cia);\n");
|
||||
if (options.gen.semantic_icache)
|
||||
{
|
||||
lf_putstr (file, "{\n");
|
||||
|
@ -183,7 +185,7 @@ cache. */\n\
|
|||
lf_indent (file, -4);
|
||||
lf_putstr (file, " }\n");
|
||||
}
|
||||
|
||||
|
||||
/* update the cpu if necessary */
|
||||
switch (options.gen.nia)
|
||||
{
|
||||
|
@ -210,10 +212,10 @@ cache. */\n\
|
|||
lf_indent (file, -4);
|
||||
lf_printf (file, " }\n");
|
||||
}
|
||||
|
||||
|
||||
if (options.gen.smp)
|
||||
{
|
||||
|
||||
|
||||
lf_putstr (file, "\
|
||||
/* CASE 2: SMP (With or without ICACHE)\n\
|
||||
\n\
|
||||
|
@ -223,9 +225,10 @@ cpu1 will normally be the next cpu that is run. Cpu0 being restarted\n\
|
|||
after all the other CPU's and the event queue have been processed */\n\
|
||||
\n\
|
||||
");
|
||||
|
||||
|
||||
lf_putstr (file, "\n");
|
||||
lf_printf (file, "/* have ensured that the event queue is NOT next */\n");
|
||||
lf_printf (file,
|
||||
"/* have ensured that the event queue is NOT next */\n");
|
||||
lf_printf (file, "SIM_ASSERT (current_cpu >= 0);\n");
|
||||
lf_printf (file, "SIM_ASSERT (current_cpu <= nr_cpus - 1);\n");
|
||||
lf_printf (file, "SIM_ASSERT (nr_cpus <= MAX_NR_PROCESSORS);\n");
|
||||
|
@ -247,7 +250,7 @@ after all the other CPU's and the event queue have been processed */\n\
|
|||
lf_putstr (file, "CIA_SET (cpu, cia);\n");
|
||||
print_engine_issue_postfix_hook (file);
|
||||
}
|
||||
|
||||
|
||||
if (options.gen.icache)
|
||||
{
|
||||
lf_putstr (file, "engine_cache *cache_entry =\n");
|
||||
|
@ -258,8 +261,10 @@ after all the other CPU's and the event queue have been processed */\n\
|
|||
lf_indent (file, +2);
|
||||
lf_putstr (file, "\n");
|
||||
lf_putstr (file, "/* cache hit */\n");
|
||||
lf_putstr (file, "engine_semantic *semantic = cache_entry->semantic;\n");
|
||||
lf_putstr (file, "cia = semantic(processor, cache_entry, cia);\n");
|
||||
lf_putstr (file,
|
||||
"engine_semantic *semantic = cache_entry->semantic;\n");
|
||||
lf_putstr (file,
|
||||
"cia = semantic(processor, cache_entry, cia);\n");
|
||||
/* tail */
|
||||
lf_putstr (file, "cpu_set_program_counter(processor, cia);\n");
|
||||
lf_putstr (file, "\n");
|
||||
|
@ -278,13 +283,14 @@ after all the other CPU's and the event queue have been processed */\n\
|
|||
lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n",
|
||||
options.insn_bit_size);
|
||||
lf_putstr (file, "if (WITH_MON != 0)\n");
|
||||
lf_putstr (file, " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
|
||||
lf_putstr (file,
|
||||
" mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
|
||||
if (options.gen.semantic_icache)
|
||||
{
|
||||
lf_putstr (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
print_engine_issue_prefix_hook (file);
|
||||
print_idecode_body(file, table, "cia =");
|
||||
print_idecode_body (file, table, "cia =");
|
||||
print_engine_issue_postfix_hook (file);
|
||||
lf_indent (file, -2);
|
||||
lf_putstr (file, "}\n");
|
||||
|
@ -292,8 +298,9 @@ after all the other CPU's and the event queue have been processed */\n\
|
|||
else
|
||||
{
|
||||
print_engine_issue_prefix_hook (file);
|
||||
print_idecode_body(file, table, "semantic = ");
|
||||
lf_putstr (file, "cia = semantic(processor, cache_entry, cia);\n");
|
||||
print_idecode_body (file, table, "semantic = ");
|
||||
lf_putstr (file,
|
||||
"cia = semantic(processor, cache_entry, cia);\n");
|
||||
print_engine_issue_postfix_hook (file);
|
||||
}
|
||||
/* tail */
|
||||
|
@ -303,7 +310,7 @@ after all the other CPU's and the event queue have been processed */\n\
|
|||
}
|
||||
lf_putstr (file, "}\n");
|
||||
}
|
||||
|
||||
|
||||
lf_putstr (file, "\n");
|
||||
lf_putstr (file, "current_cpu += 1;\n");
|
||||
lf_putstr (file, "if (current_cpu == nr_cpus)\n");
|
||||
|
@ -314,13 +321,13 @@ after all the other CPU's and the event queue have been processed */\n\
|
|||
lf_putstr (file, " }\n");
|
||||
lf_putstr (file, " current_cpu = 0;\n");
|
||||
lf_putstr (file, " }\n");
|
||||
|
||||
|
||||
/* tail */
|
||||
lf_indent (file, -4);
|
||||
lf_putstr (file, " }\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
lf_indent (file, -2);
|
||||
lf_putstr (file, "}\n");
|
||||
}
|
||||
|
@ -330,8 +337,7 @@ after all the other CPU's and the event queue have been processed */\n\
|
|||
|
||||
#if 0
|
||||
static void
|
||||
print_jump (lf *file,
|
||||
int is_tail)
|
||||
print_jump (lf *file, int is_tail)
|
||||
{
|
||||
if (!options.gen.smp)
|
||||
{
|
||||
|
@ -342,7 +348,7 @@ print_jump (lf *file,
|
|||
lf_putstr (file, " }\n");
|
||||
lf_putstr (file, "}\n");
|
||||
}
|
||||
|
||||
|
||||
if (options.gen.smp)
|
||||
{
|
||||
if (is_tail)
|
||||
|
@ -359,7 +365,7 @@ print_jump (lf *file,
|
|||
lf_putstr (file, "processor = processors[current_cpu];\n");
|
||||
lf_putstr (file, "nia = cpu_get_program_counter(processor);\n");
|
||||
}
|
||||
|
||||
|
||||
if (options.gen.icache)
|
||||
{
|
||||
lf_putstr (file, "cache_entry = cpu_icache_entry(processor, nia);\n");
|
||||
|
@ -367,16 +373,17 @@ print_jump (lf *file,
|
|||
lf_putstr (file, " /* cache hit */\n");
|
||||
lf_putstr (file, " goto *cache_entry->semantic;\n");
|
||||
lf_putstr (file, "}\n");
|
||||
if (is_tail) {
|
||||
lf_putstr (file, "goto cache_miss;\n");
|
||||
}
|
||||
if (is_tail)
|
||||
{
|
||||
lf_putstr (file, "goto cache_miss;\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!options.gen.icache && is_tail)
|
||||
{
|
||||
lf_printf (file, "goto engine;\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -384,10 +391,9 @@ print_jump (lf *file,
|
|||
#if 0
|
||||
static void
|
||||
print_jump_insn (lf *file,
|
||||
insn_entry *instruction,
|
||||
insn_entry * instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
opcode_field *opcodes,
|
||||
cache_entry *cache_rules)
|
||||
opcode_field *opcodes, cache_entry *cache_rules)
|
||||
{
|
||||
insn_opcodes opcode_path;
|
||||
|
||||
|
@ -398,9 +404,8 @@ print_jump_insn (lf *file,
|
|||
lf_printf (file, "\n");
|
||||
print_my_defines (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
expanded_bits);
|
||||
|
||||
instruction->format_name, expanded_bits);
|
||||
|
||||
/* output the icache entry */
|
||||
if (options.gen.icache)
|
||||
{
|
||||
|
@ -409,24 +414,18 @@ print_jump_insn (lf *file,
|
|||
print_function_name (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
expanded_bits,
|
||||
function_name_prefix_icache);
|
||||
NULL, expanded_bits, function_name_prefix_icache);
|
||||
lf_printf (file, ":\n");
|
||||
lf_indent (file, +1);
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
lf_putstr (file, "const unsigned_word cia = nia;\n");
|
||||
print_itrace (file, instruction, 1/*putting-value-in-cache*/);
|
||||
print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
|
||||
print_idecode_validate (file, instruction, &opcode_path);
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
print_icache_body (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
cache_rules,
|
||||
0, /*use_defines*/
|
||||
print_icache_body (file, instruction, expanded_bits, cache_rules, 0, /*use_defines */
|
||||
put_values_in_icache);
|
||||
lf_printf (file, "cache_entry->address = nia;\n");
|
||||
lf_printf (file, "cache_entry->semantic = &&");
|
||||
|
@ -434,16 +433,13 @@ print_jump_insn (lf *file,
|
|||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
expanded_bits,
|
||||
function_name_prefix_semantics);
|
||||
expanded_bits, function_name_prefix_semantics);
|
||||
lf_printf (file, ";\n");
|
||||
if (options.gen.semantic_icache)
|
||||
{
|
||||
print_semantic_body (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
&opcode_path);
|
||||
print_jump(file, 1/*is-tail*/);
|
||||
instruction, expanded_bits, &opcode_path);
|
||||
print_jump (file, 1 /*is-tail */ );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -452,8 +448,7 @@ print_jump_insn (lf *file,
|
|||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
expanded_bits,
|
||||
function_name_prefix_semantics);
|
||||
expanded_bits, function_name_prefix_semantics);
|
||||
lf_printf (file, "; */\n");
|
||||
}
|
||||
lf_indent (file, -2);
|
||||
|
@ -461,16 +456,14 @@ print_jump_insn (lf *file,
|
|||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
}
|
||||
|
||||
|
||||
/* print the semantics */
|
||||
lf_printf (file, "\n");
|
||||
lf_indent (file, -1);
|
||||
print_function_name (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
expanded_bits,
|
||||
function_name_prefix_semantics);
|
||||
NULL, expanded_bits, function_name_prefix_semantics);
|
||||
lf_printf (file, ":\n");
|
||||
lf_indent (file, +1);
|
||||
lf_printf (file, "{\n");
|
||||
|
@ -484,12 +477,8 @@ print_jump_insn (lf *file,
|
|||
? define_variables
|
||||
: declare_variables),
|
||||
(options.gen.icache
|
||||
? get_values_from_icache
|
||||
: do_not_use_icache));
|
||||
print_semantic_body (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
&opcode_path);
|
||||
? get_values_from_icache : do_not_use_icache));
|
||||
print_semantic_body (file, instruction, expanded_bits, &opcode_path);
|
||||
if (options.gen.direct_access)
|
||||
print_icache_body (file,
|
||||
instruction,
|
||||
|
@ -497,9 +486,8 @@ print_jump_insn (lf *file,
|
|||
cache_rules,
|
||||
undef_variables,
|
||||
(options.gen.icache
|
||||
? get_values_from_icache
|
||||
: do_not_use_icache));
|
||||
print_jump(file, 1/*is tail*/);
|
||||
? get_values_from_icache : do_not_use_icache));
|
||||
print_jump (file, 1 /*is tail */ );
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
}
|
||||
|
@ -508,18 +496,14 @@ print_jump_insn (lf *file,
|
|||
|
||||
#if 0
|
||||
static void
|
||||
print_jump_definition (lf *file,
|
||||
gen_entry *entry,
|
||||
int depth,
|
||||
void *data)
|
||||
print_jump_definition (lf *file, gen_entry *entry, int depth, void *data)
|
||||
{
|
||||
cache_entry *cache_rules = (cache_entry*)data;
|
||||
cache_entry *cache_rules = (cache_entry *) data;
|
||||
if (entry->opcode_rule->with_duplicates)
|
||||
{
|
||||
ASSERT (entry->nr_insns == 1
|
||||
&& entry->opcode == NULL
|
||||
&& entry->parent != NULL
|
||||
&& entry->parent->opcode != NULL);
|
||||
&& entry->parent != NULL && entry->parent->opcode != NULL);
|
||||
ASSERT (entry->nr_insns == 1
|
||||
&& entry->opcode == NULL
|
||||
&& entry->parent != NULL
|
||||
|
@ -527,17 +511,11 @@ print_jump_definition (lf *file,
|
|||
&& entry->parent->opcode_rule != NULL);
|
||||
print_jump_insn (file,
|
||||
entry->insns->insn,
|
||||
entry->expanded_bits,
|
||||
entry->opcode,
|
||||
cache_rules);
|
||||
entry->expanded_bits, entry->opcode, cache_rules);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
print_jump_insn (file,
|
||||
entry->insns->insn,
|
||||
NULL,
|
||||
NULL,
|
||||
cache_rules);
|
||||
print_jump_insn (file, entry->insns->insn, NULL, NULL, cache_rules);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -545,9 +523,7 @@ print_jump_definition (lf *file,
|
|||
|
||||
#if 0
|
||||
static void
|
||||
print_jump_internal_function (lf *file,
|
||||
function_entry *function,
|
||||
void *data)
|
||||
print_jump_internal_function (lf *file, function_entry * function, void *data)
|
||||
{
|
||||
if (function->is_internal)
|
||||
{
|
||||
|
@ -580,9 +556,7 @@ print_jump_internal_function (lf *file,
|
|||
#if 0
|
||||
static void
|
||||
print_jump_body (lf *file,
|
||||
gen_entry *entry,
|
||||
insn_table *isa,
|
||||
cache_entry *cache_rules)
|
||||
gen_entry *entry, insn_table *isa, cache_entry *cache_rules)
|
||||
{
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
|
@ -599,10 +573,10 @@ print_jump_body (lf *file,
|
|||
{
|
||||
lf_putstr (file, "int current_cpu = -1;\n");
|
||||
}
|
||||
|
||||
|
||||
/* all the switches and tables - they know about jumping */
|
||||
print_idecode_lookups (file, entry, cache_rules);
|
||||
|
||||
|
||||
/* start the simulation up */
|
||||
if (options.gen.icache)
|
||||
{
|
||||
|
@ -613,17 +587,17 @@ print_jump_body (lf *file,
|
|||
lf_putstr (file, " cpu_flush_icache(processors[cpu_nr]);\n");
|
||||
lf_putstr (file, "}\n");
|
||||
}
|
||||
|
||||
|
||||
lf_putstr (file, "\n");
|
||||
lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
|
||||
|
||||
|
||||
lf_putstr (file, "\n");
|
||||
lf_putstr (file, "if (setjmp(halt))\n");
|
||||
lf_putstr (file, " return;\n");
|
||||
|
||||
|
||||
lf_putstr (file, "\n");
|
||||
lf_putstr (file, "setjmp(restart);\n");
|
||||
|
||||
|
||||
lf_putstr (file, "\n");
|
||||
if (!options.gen.smp)
|
||||
{
|
||||
|
@ -634,7 +608,7 @@ print_jump_body (lf *file,
|
|||
{
|
||||
lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
|
||||
}
|
||||
|
||||
|
||||
if (!options.gen.icache)
|
||||
{
|
||||
lf_printf (file, "\n");
|
||||
|
@ -642,36 +616,34 @@ print_jump_body (lf *file,
|
|||
lf_printf (file, "engine:\n");
|
||||
lf_indent (file, +1);
|
||||
}
|
||||
|
||||
print_jump(file, 0/*is_tail*/);
|
||||
|
||||
|
||||
print_jump (file, 0 /*is_tail */ );
|
||||
|
||||
if (options.gen.icache)
|
||||
{
|
||||
lf_indent (file, -1);
|
||||
lf_printf (file, "cache_miss:\n");
|
||||
lf_indent (file, +1);
|
||||
}
|
||||
|
||||
print_engine_issue_prefix_hook (file);
|
||||
|
||||
print_engine_issue_prefix_hook (file);
|
||||
lf_putstr (file, "instruction\n");
|
||||
lf_putstr (file, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
|
||||
lf_putstr (file,
|
||||
" = vm_instruction_map_read(cpu_instruction_map(processor),\n");
|
||||
lf_putstr (file, " processor, nia);\n");
|
||||
print_engine_issue_prefix_hook (file);
|
||||
print_idecode_body (file, entry, "/*IGORE*/");
|
||||
print_engine_issue_postfix_hook (file);
|
||||
|
||||
|
||||
/* print out a table of all the internals functions */
|
||||
function_entry_traverse (file, isa->functions,
|
||||
print_jump_internal_function,
|
||||
NULL);
|
||||
|
||||
print_jump_internal_function, NULL);
|
||||
|
||||
/* print out a table of all the instructions */
|
||||
ERROR ("Use the list of semantic functions, not travere_tree");
|
||||
gen_entry_traverse_tree (file, entry,
|
||||
1,
|
||||
NULL, /* start */
|
||||
print_jump_definition, /* leaf */
|
||||
NULL, /* end */
|
||||
gen_entry_traverse_tree (file, entry, 1, NULL, /* start */
|
||||
print_jump_definition, /* leaf */
|
||||
NULL, /* end */
|
||||
cache_rules);
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
|
@ -701,11 +673,8 @@ print_engine_run_function_header (lf *file,
|
|||
lf_printf (file, "void (*");
|
||||
break;
|
||||
}
|
||||
indent = print_function_name (file,
|
||||
"run",
|
||||
NULL, /* format name */
|
||||
processor,
|
||||
NULL, /* expanded bits */
|
||||
indent = print_function_name (file, "run", NULL, /* format name */
|
||||
processor, NULL, /* expanded bits */
|
||||
function_name_prefix_engine);
|
||||
switch (decl_type)
|
||||
{
|
||||
|
@ -742,9 +711,7 @@ print_engine_run_function_header (lf *file,
|
|||
|
||||
void
|
||||
gen_engine_h (lf *file,
|
||||
gen_table *gen,
|
||||
insn_table *isa,
|
||||
cache_entry *cache_rules)
|
||||
gen_table *gen, insn_table *isa, cache_entry *cache_rules)
|
||||
{
|
||||
gen_list *entry;
|
||||
for (entry = gen->tables; entry != NULL; entry = entry->next)
|
||||
|
@ -752,17 +719,14 @@ gen_engine_h (lf *file,
|
|||
print_engine_run_function_header (file,
|
||||
(options.gen.multi_sim
|
||||
? entry->model->name
|
||||
: NULL),
|
||||
is_function_declaration);
|
||||
: NULL), is_function_declaration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gen_engine_c(lf *file,
|
||||
gen_table *gen,
|
||||
insn_table *isa,
|
||||
cache_entry *cache_rules)
|
||||
gen_engine_c (lf *file,
|
||||
gen_table *gen, insn_table *isa, cache_entry *cache_rules)
|
||||
{
|
||||
gen_list *entry;
|
||||
/* the intro */
|
||||
|
@ -781,24 +745,22 @@ gen_engine_c(lf *file,
|
|||
{
|
||||
case generate_calls:
|
||||
print_idecode_lookups (file, entry->table, cache_rules);
|
||||
|
||||
|
||||
/* output the main engine routine */
|
||||
print_engine_run_function_header (file,
|
||||
(options.gen.multi_sim
|
||||
? entry->model->name
|
||||
: NULL),
|
||||
is_function_definition);
|
||||
: NULL), is_function_definition);
|
||||
print_run_body (file, entry->table);
|
||||
break;
|
||||
|
||||
|
||||
case generate_jumps:
|
||||
ERROR ("Jumps currently unimplemented");
|
||||
#if 0
|
||||
print_engine_run_function_header (file,
|
||||
entry->processor,
|
||||
is_function_definition);
|
||||
print_jump_body (file, entry->table,
|
||||
isa, cache_rules);
|
||||
print_jump_body (file, entry->table, isa, cache_rules);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -22,19 +22,10 @@
|
|||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
extern void gen_engine_h
|
||||
(lf *file,
|
||||
gen_table *gen,
|
||||
insn_table *isa,
|
||||
cache_entry *cache_rules);
|
||||
(lf *file, gen_table *gen, insn_table *isa, cache_entry *cache_rules);
|
||||
|
||||
extern void gen_engine_c
|
||||
(lf *file,
|
||||
gen_table *gen,
|
||||
insn_table *isa,
|
||||
cache_entry *cache_rules);
|
||||
(lf *file, gen_table *gen, insn_table *isa, cache_entry *cache_rules);
|
||||
|
||||
extern void print_engine_run_function_header
|
||||
(lf *file,
|
||||
char *processor,
|
||||
function_decl_type decl_type);
|
||||
|
||||
(lf *file, char *processor, function_decl_type decl_type);
|
||||
|
|
|
@ -47,13 +47,12 @@ print_icache_function_header (lf *file,
|
|||
int is_function_definition,
|
||||
int nr_prefetched_words)
|
||||
{
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "\n");
|
||||
lf_print__function_type_function (file, print_icache_function_type,
|
||||
"EXTERN_ICACHE", " ");
|
||||
print_function_name (file,
|
||||
basename, format_name, NULL,
|
||||
expanded_bits,
|
||||
function_name_prefix_icache);
|
||||
expanded_bits, function_name_prefix_icache);
|
||||
lf_printf (file, "\n(");
|
||||
print_icache_function_formal (file, nr_prefetched_words);
|
||||
lf_printf (file, ")");
|
||||
|
@ -65,16 +64,15 @@ print_icache_function_header (lf *file,
|
|||
|
||||
void
|
||||
print_icache_declaration (lf *file,
|
||||
insn_entry *insn,
|
||||
insn_entry * insn,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
int nr_prefetched_words)
|
||||
insn_opcodes *opcodes, int nr_prefetched_words)
|
||||
{
|
||||
print_icache_function_header (file,
|
||||
insn->name,
|
||||
insn->format_name,
|
||||
expanded_bits,
|
||||
0/* is not function definition */,
|
||||
0 /* is not function definition */ ,
|
||||
nr_prefetched_words);
|
||||
}
|
||||
|
||||
|
@ -99,7 +97,7 @@ print_icache_extraction (lf *file,
|
|||
char *reason;
|
||||
ASSERT (format_name != NULL);
|
||||
ASSERT (entry_name != NULL);
|
||||
|
||||
|
||||
/* figure out exactly what should be going on here */
|
||||
switch (cache_type)
|
||||
{
|
||||
|
@ -129,30 +127,27 @@ print_icache_extraction (lf *file,
|
|||
{
|
||||
reason = "cache";
|
||||
what_to_declare = ((what_to_do & put_values_in_icache)
|
||||
? declare_variables
|
||||
: what_to_declare);
|
||||
? declare_variables : what_to_declare);
|
||||
}
|
||||
else
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
abort (); /* Bad switch. */
|
||||
abort (); /* Bad switch. */
|
||||
}
|
||||
|
||||
|
||||
/* For the type, default to a simple unsigned */
|
||||
if (entry_type == NULL || strlen (entry_type) == 0)
|
||||
entry_type = "unsigned";
|
||||
|
||||
|
||||
/* look through the set of expanded sub fields to see if this field
|
||||
has been given a constant value */
|
||||
for (bits = expanded_bits;
|
||||
bits != NULL;
|
||||
bits = bits->next)
|
||||
for (bits = expanded_bits; bits != NULL; bits = bits->next)
|
||||
{
|
||||
if (bits->field == cur_field)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Define a storage area for the cache element */
|
||||
switch (what_to_declare)
|
||||
{
|
||||
|
@ -180,8 +175,8 @@ print_icache_extraction (lf *file,
|
|||
lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* define a value for that storage area as determined by what is in
|
||||
the cache */
|
||||
if (bits != NULL
|
||||
|
@ -193,11 +188,11 @@ print_icache_extraction (lf *file,
|
|||
{
|
||||
/* The cache rule is specifying what to do with a simple
|
||||
instruction field.
|
||||
|
||||
Because of instruction expansion, the field is either a
|
||||
constant value or equal to the specified constant (boolean
|
||||
comparison). (The latter indicated by bits->value == 0).
|
||||
|
||||
|
||||
Because of instruction expansion, the field is either a
|
||||
constant value or equal to the specified constant (boolean
|
||||
comparison). (The latter indicated by bits->value == 0).
|
||||
|
||||
The case of a field not being equal to the specified boolean
|
||||
value is handled later. */
|
||||
expression = "constant field";
|
||||
|
@ -226,52 +221,55 @@ print_icache_extraction (lf *file,
|
|||
"_is_",
|
||||
strlen ("_is_")) == 0
|
||||
&& ((bits->opcode->is_boolean
|
||||
&& ((unsigned) atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
|
||||
== bits->opcode->boolean_constant))
|
||||
&& ((unsigned)
|
||||
atol (entry_name + strlen (single_insn_field) +
|
||||
strlen ("_is_")) == bits->opcode->boolean_constant))
|
||||
|| (!bits->opcode->is_boolean)))
|
||||
{
|
||||
/* The cache rule defines an entry for the comparison between a
|
||||
single instruction field and a constant. The value of the
|
||||
comparison in someway matches that of the opcode field that
|
||||
was made constant through expansion. */
|
||||
single instruction field and a constant. The value of the
|
||||
comparison in someway matches that of the opcode field that
|
||||
was made constant through expansion. */
|
||||
expression = "constant compare";
|
||||
if (bits->opcode->is_boolean)
|
||||
{
|
||||
lf_printf (file, "%d /* %s == %d */",
|
||||
bits->value == 0,
|
||||
single_insn_field,
|
||||
bits->opcode->boolean_constant);
|
||||
single_insn_field, bits->opcode->boolean_constant);
|
||||
}
|
||||
else if (bits->opcode->last < bits->field->last)
|
||||
{
|
||||
lf_printf (file, "%d /* %s == %d */",
|
||||
(atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
|
||||
== (bits->value << (bits->field->last - bits->opcode->last))),
|
||||
(atol
|
||||
(entry_name + strlen (single_insn_field) +
|
||||
strlen ("_is_")) ==
|
||||
(bits->
|
||||
value << (bits->field->last - bits->opcode->last))),
|
||||
single_insn_field,
|
||||
(bits->value << (bits->field->last - bits->opcode->last)));
|
||||
(bits->
|
||||
value << (bits->field->last - bits->opcode->last)));
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf (file, "%d /* %s == %d */",
|
||||
(atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
|
||||
== bits->value),
|
||||
single_insn_field,
|
||||
(atol
|
||||
(entry_name + strlen (single_insn_field) +
|
||||
strlen ("_is_")) == bits->value), single_insn_field,
|
||||
bits->value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* put the field in the local variable, possibly also enter it
|
||||
into the cache */
|
||||
into the cache */
|
||||
expression = "extraction";
|
||||
/* handle the cache */
|
||||
if ((what_to_do & get_values_from_icache)
|
||||
|| (what_to_do & put_values_in_icache))
|
||||
{
|
||||
lf_printf (file, "cache_entry->crack.%s.%s",
|
||||
format_name,
|
||||
entry_name);
|
||||
if (what_to_do & put_values_in_icache) /* also put it in the cache? */
|
||||
format_name, entry_name);
|
||||
if (what_to_do & put_values_in_icache) /* also put it in the cache? */
|
||||
{
|
||||
lf_printf (file, " = ");
|
||||
}
|
||||
|
@ -282,10 +280,11 @@ print_icache_extraction (lf *file,
|
|||
if (cur_field != NULL)
|
||||
{
|
||||
if (entry_expression != NULL && strlen (entry_expression) > 0)
|
||||
error (line, "Instruction field entry with nonempty expression\n");
|
||||
if (cur_field->first == 0 && cur_field->last == options.insn_bit_size - 1)
|
||||
lf_printf (file, "(instruction_%d)",
|
||||
cur_field->word_nr);
|
||||
error (line,
|
||||
"Instruction field entry with nonempty expression\n");
|
||||
if (cur_field->first == 0
|
||||
&& cur_field->last == options.insn_bit_size - 1)
|
||||
lf_printf (file, "(instruction_%d)", cur_field->word_nr);
|
||||
else if (cur_field->last == options.insn_bit_size - 1)
|
||||
lf_printf (file, "MASKED%d (instruction_%d, %d, %d)",
|
||||
options.insn_bit_size,
|
||||
|
@ -305,7 +304,7 @@ print_icache_extraction (lf *file,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (what_to_declare)
|
||||
{
|
||||
case define_variables:
|
||||
|
@ -325,12 +324,11 @@ print_icache_extraction (lf *file,
|
|||
|
||||
void
|
||||
print_icache_body (lf *file,
|
||||
insn_entry *instruction,
|
||||
insn_entry * instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
cache_entry *cache_rules,
|
||||
icache_decl_type what_to_declare,
|
||||
icache_body_type what_to_do,
|
||||
int nr_prefetched_words)
|
||||
icache_body_type what_to_do, int nr_prefetched_words)
|
||||
{
|
||||
/* extract instruction fields */
|
||||
lf_printf (file, "/* Extraction: %s\n", instruction->name);
|
||||
|
@ -365,8 +363,8 @@ print_icache_body (lf *file,
|
|||
}
|
||||
lf_printf (file, "\n ");
|
||||
print_insn_words (file, instruction);
|
||||
lf_printf(file, " */\n");
|
||||
|
||||
lf_printf (file, " */\n");
|
||||
|
||||
/* pass zero - fetch from memory any missing instructions.
|
||||
|
||||
Some of the instructions will have already been fetched (in the
|
||||
|
@ -387,13 +385,12 @@ print_icache_body (lf *file,
|
|||
case define_variables:
|
||||
case declare_variables:
|
||||
for (word_nr = nr_prefetched_words;
|
||||
word_nr < instruction->nr_words;
|
||||
word_nr++)
|
||||
word_nr < instruction->nr_words; word_nr++)
|
||||
{
|
||||
/* FIXME - should be using print_icache_extraction? */
|
||||
lf_printf (file, "%sinstruction_word instruction_%d UNUSED = ",
|
||||
options.module.global.prefix.l,
|
||||
word_nr);
|
||||
lf_printf (file,
|
||||
"%sinstruction_word instruction_%d UNUSED = ",
|
||||
options.module.global.prefix.l, word_nr);
|
||||
lf_printf (file, "IMEM%d_IMMED (cia, %d)",
|
||||
options.insn_bit_size, word_nr);
|
||||
lf_printf (file, ";\n");
|
||||
|
@ -404,21 +401,17 @@ print_icache_body (lf *file,
|
|||
|
||||
/* if putting the instruction words in the cache, define references
|
||||
for them */
|
||||
if (options.gen.insn_in_icache) {
|
||||
/* FIXME: is the instruction_word type correct? */
|
||||
print_icache_extraction (file,
|
||||
instruction->format_name,
|
||||
cache_value,
|
||||
"insn", /* name */
|
||||
"instruction_word", /* type */
|
||||
"instruction", /* expression */
|
||||
NULL, /* origin */
|
||||
NULL, /* line */
|
||||
NULL, NULL,
|
||||
what_to_declare,
|
||||
what_to_do);
|
||||
}
|
||||
lf_printf(file, "\n");
|
||||
if (options.gen.insn_in_icache)
|
||||
{
|
||||
/* FIXME: is the instruction_word type correct? */
|
||||
print_icache_extraction (file, instruction->format_name, cache_value, "insn", /* name */
|
||||
"instruction_word", /* type */
|
||||
"instruction", /* expression */
|
||||
NULL, /* origin */
|
||||
NULL, /* line */
|
||||
NULL, NULL, what_to_declare, what_to_do);
|
||||
}
|
||||
lf_printf (file, "\n");
|
||||
|
||||
/* pass one - process instruction fields.
|
||||
|
||||
|
@ -426,9 +419,7 @@ print_icache_body (lf *file,
|
|||
the cache */
|
||||
{
|
||||
insn_word_entry *word;
|
||||
for (word = instruction->words;
|
||||
word != NULL;
|
||||
word = word->next)
|
||||
for (word = instruction->words; word != NULL; word = word->next)
|
||||
{
|
||||
insn_field_entry *cur_field;
|
||||
for (cur_field = word->first;
|
||||
|
@ -444,12 +435,12 @@ print_icache_body (lf *file,
|
|||
overriding the default cache action for an
|
||||
instruction field */
|
||||
for (cache_rule = cache_rules;
|
||||
cache_rule != NULL;
|
||||
cache_rule = cache_rule->next)
|
||||
cache_rule != NULL; cache_rule = cache_rule->next)
|
||||
{
|
||||
if (filter_is_subset (instruction->field_names,
|
||||
cache_rule->original_fields)
|
||||
&& strcmp (cache_rule->name, cur_field->val_string) == 0)
|
||||
&& strcmp (cache_rule->name,
|
||||
cur_field->val_string) == 0)
|
||||
{
|
||||
value_type = cache_rule->entry_type;
|
||||
value_line = cache_rule->line;
|
||||
|
@ -463,19 +454,15 @@ print_icache_body (lf *file,
|
|||
}
|
||||
}
|
||||
/* Define an entry for the field within the
|
||||
instruction */
|
||||
print_icache_extraction (file,
|
||||
instruction->format_name,
|
||||
value_type,
|
||||
cur_field->val_string, /* name */
|
||||
NULL, /* type */
|
||||
NULL, /* expression */
|
||||
cur_field->val_string, /* insn field */
|
||||
instruction */
|
||||
print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string, /* name */
|
||||
NULL, /* type */
|
||||
NULL, /* expression */
|
||||
cur_field->val_string, /* insn field */
|
||||
value_line,
|
||||
cur_field,
|
||||
expanded_bits,
|
||||
what_to_declare,
|
||||
what_to_do);
|
||||
what_to_declare, what_to_do);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,29 +472,20 @@ print_icache_body (lf *file,
|
|||
{
|
||||
cache_entry *cache_rule;
|
||||
for (cache_rule = cache_rules;
|
||||
cache_rule != NULL;
|
||||
cache_rule = cache_rule->next)
|
||||
cache_rule != NULL; cache_rule = cache_rule->next)
|
||||
{
|
||||
if (filter_is_subset (instruction->field_names,
|
||||
cache_rule->original_fields)
|
||||
&& !filter_is_member (instruction->field_names,
|
||||
cache_rule->name))
|
||||
&& !filter_is_member (instruction->field_names, cache_rule->name))
|
||||
{
|
||||
char *single_field = filter_next (cache_rule->original_fields, "");
|
||||
if (filter_next (cache_rule->original_fields, single_field) != NULL)
|
||||
char *single_field =
|
||||
filter_next (cache_rule->original_fields, "");
|
||||
if (filter_next (cache_rule->original_fields, single_field) !=
|
||||
NULL)
|
||||
single_field = NULL;
|
||||
print_icache_extraction (file,
|
||||
instruction->format_name,
|
||||
cache_rule->entry_type,
|
||||
cache_rule->name,
|
||||
cache_rule->type,
|
||||
cache_rule->expression,
|
||||
single_field,
|
||||
cache_rule->line,
|
||||
NULL, /* cur_field */
|
||||
print_icache_extraction (file, instruction->format_name, cache_rule->entry_type, cache_rule->name, cache_rule->type, cache_rule->expression, single_field, cache_rule->line, NULL, /* cur_field */
|
||||
expanded_bits,
|
||||
what_to_declare,
|
||||
what_to_do);
|
||||
what_to_declare, what_to_do);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +496,8 @@ print_icache_body (lf *file,
|
|||
|
||||
|
||||
typedef struct _form_fields form_fields;
|
||||
struct _form_fields {
|
||||
struct _form_fields
|
||||
{
|
||||
char *name;
|
||||
filter *fields;
|
||||
form_fields *next;
|
||||
|
@ -529,134 +508,131 @@ insn_table_cache_fields (insn_table *isa)
|
|||
{
|
||||
form_fields *forms = NULL;
|
||||
insn_entry *insn;
|
||||
for (insn = isa->insns;
|
||||
insn != NULL;
|
||||
insn = insn->next) {
|
||||
form_fields **form = &forms;
|
||||
while (1)
|
||||
{
|
||||
if (*form == NULL)
|
||||
{
|
||||
/* new format name, add it */
|
||||
form_fields *new_form = ZALLOC (form_fields);
|
||||
new_form->name = insn->format_name;
|
||||
filter_add (&new_form->fields, insn->field_names);
|
||||
*form = new_form;
|
||||
break;
|
||||
}
|
||||
else if (strcmp ((*form)->name, insn->format_name) == 0)
|
||||
{
|
||||
/* already present, add field names to the existing list */
|
||||
filter_add (&(*form)->fields, insn->field_names);
|
||||
break;
|
||||
}
|
||||
form = &(*form)->next;
|
||||
}
|
||||
}
|
||||
for (insn = isa->insns; insn != NULL; insn = insn->next)
|
||||
{
|
||||
form_fields **form = &forms;
|
||||
while (1)
|
||||
{
|
||||
if (*form == NULL)
|
||||
{
|
||||
/* new format name, add it */
|
||||
form_fields *new_form = ZALLOC (form_fields);
|
||||
new_form->name = insn->format_name;
|
||||
filter_add (&new_form->fields, insn->field_names);
|
||||
*form = new_form;
|
||||
break;
|
||||
}
|
||||
else if (strcmp ((*form)->name, insn->format_name) == 0)
|
||||
{
|
||||
/* already present, add field names to the existing list */
|
||||
filter_add (&(*form)->fields, insn->field_names);
|
||||
break;
|
||||
}
|
||||
form = &(*form)->next;
|
||||
}
|
||||
}
|
||||
return forms;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void
|
||||
print_icache_struct (lf *file,
|
||||
insn_table *isa,
|
||||
cache_entry *cache_rules)
|
||||
print_icache_struct (lf *file, insn_table *isa, cache_entry *cache_rules)
|
||||
{
|
||||
/* Create a list of all the different instruction formats with their
|
||||
corresponding field names. */
|
||||
form_fields *formats = insn_table_cache_fields (isa);
|
||||
|
||||
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
|
||||
options.module.global.prefix.u,
|
||||
(options.gen.icache ? options.gen.icache_size : 0));
|
||||
lf_printf (file, "\n");
|
||||
|
||||
|
||||
/* create an instruction cache if being used */
|
||||
if (options.gen.icache) {
|
||||
lf_printf (file, "typedef struct _%sidecode_cache {\n",
|
||||
options.module.global.prefix.l);
|
||||
lf_indent (file, +2);
|
||||
if (options.gen.icache)
|
||||
{
|
||||
form_fields *format;
|
||||
lf_printf (file, "unsigned_word address;\n");
|
||||
lf_printf (file, "void *semantic;\n");
|
||||
lf_printf (file, "union {\n");
|
||||
lf_printf (file, "typedef struct _%sidecode_cache {\n",
|
||||
options.module.global.prefix.l);
|
||||
lf_indent (file, +2);
|
||||
for (format = formats;
|
||||
format != NULL;
|
||||
format = format->next)
|
||||
{
|
||||
lf_printf (file, "struct {\n");
|
||||
lf_indent (file, +2);
|
||||
{
|
||||
form_fields *format;
|
||||
lf_printf (file, "unsigned_word address;\n");
|
||||
lf_printf (file, "void *semantic;\n");
|
||||
lf_printf (file, "union {\n");
|
||||
lf_indent (file, +2);
|
||||
for (format = formats; format != NULL; format = format->next)
|
||||
{
|
||||
cache_entry *cache_rule;
|
||||
char *field;
|
||||
/* space for any instruction words */
|
||||
if (options.gen.insn_in_icache)
|
||||
lf_printf (file, "instruction_word insn[%d];\n", isa->max_nr_words);
|
||||
/* define an entry for any applicable cache rules */
|
||||
for (cache_rule = cache_rules;
|
||||
cache_rule != NULL;
|
||||
cache_rule = cache_rule->next)
|
||||
{
|
||||
/* nb - sort of correct - should really check against
|
||||
individual instructions */
|
||||
if (filter_is_subset (format->fields, cache_rule->original_fields))
|
||||
{
|
||||
char *memb;
|
||||
lf_printf (file, "%s %s;",
|
||||
(cache_rule->type == NULL
|
||||
? "unsigned"
|
||||
: cache_rule->type),
|
||||
cache_rule->name);
|
||||
lf_printf (file, " /*");
|
||||
for (memb = filter_next (cache_rule->original_fields, "");
|
||||
memb != NULL;
|
||||
memb = filter_next (cache_rule->original_fields, memb))
|
||||
{
|
||||
lf_printf (file, " %s", memb);
|
||||
}
|
||||
lf_printf (file, " */\n");
|
||||
}
|
||||
}
|
||||
/* define an entry for any fields not covered by a cache rule */
|
||||
for (field = filter_next (format->fields, "");
|
||||
field != NULL;
|
||||
field = filter_next (format->fields, field))
|
||||
{
|
||||
cache_entry *cache_rule;
|
||||
int found_rule = 0;
|
||||
for (cache_rule = cache_rules;
|
||||
cache_rule != NULL;
|
||||
cache_rule = cache_rule->next)
|
||||
{
|
||||
if (strcmp (cache_rule->name, field) == 0)
|
||||
{
|
||||
found_rule = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_rule)
|
||||
lf_printf (file, "unsigned %s; /* default */\n", field);
|
||||
}
|
||||
lf_printf (file, "struct {\n");
|
||||
lf_indent (file, +2);
|
||||
{
|
||||
cache_entry *cache_rule;
|
||||
char *field;
|
||||
/* space for any instruction words */
|
||||
if (options.gen.insn_in_icache)
|
||||
lf_printf (file, "instruction_word insn[%d];\n",
|
||||
isa->max_nr_words);
|
||||
/* define an entry for any applicable cache rules */
|
||||
for (cache_rule = cache_rules;
|
||||
cache_rule != NULL; cache_rule = cache_rule->next)
|
||||
{
|
||||
/* nb - sort of correct - should really check against
|
||||
individual instructions */
|
||||
if (filter_is_subset
|
||||
(format->fields, cache_rule->original_fields))
|
||||
{
|
||||
char *memb;
|
||||
lf_printf (file, "%s %s;",
|
||||
(cache_rule->type == NULL
|
||||
? "unsigned"
|
||||
: cache_rule->type), cache_rule->name);
|
||||
lf_printf (file, " /*");
|
||||
for (memb =
|
||||
filter_next (cache_rule->original_fields, "");
|
||||
memb != NULL;
|
||||
memb =
|
||||
filter_next (cache_rule->original_fields, memb))
|
||||
{
|
||||
lf_printf (file, " %s", memb);
|
||||
}
|
||||
lf_printf (file, " */\n");
|
||||
}
|
||||
}
|
||||
/* define an entry for any fields not covered by a cache rule */
|
||||
for (field = filter_next (format->fields, "");
|
||||
field != NULL; field = filter_next (format->fields, field))
|
||||
{
|
||||
cache_entry *cache_rule;
|
||||
int found_rule = 0;
|
||||
for (cache_rule = cache_rules;
|
||||
cache_rule != NULL; cache_rule = cache_rule->next)
|
||||
{
|
||||
if (strcmp (cache_rule->name, field) == 0)
|
||||
{
|
||||
found_rule = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_rule)
|
||||
lf_printf (file, "unsigned %s; /* default */\n", field);
|
||||
}
|
||||
}
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "} %s;\n", format->name);
|
||||
}
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "} %s;\n", format->name);
|
||||
}
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "} crack;\n");
|
||||
}
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "} crack;\n");
|
||||
lf_printf (file, "} %sidecode_cache;\n",
|
||||
options.module.global.prefix.l);
|
||||
}
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "} %sidecode_cache;\n", options.module.global.prefix.l);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* alernativly, since no cache, emit a dummy definition for
|
||||
idecode_cache so that code refering to the type can still compile */
|
||||
lf_printf(file, "typedef void %sidecode_cache;\n",
|
||||
options.module.global.prefix.l);
|
||||
idecode_cache so that code refering to the type can still compile */
|
||||
lf_printf (file, "typedef void %sidecode_cache;\n",
|
||||
options.module.global.prefix.l);
|
||||
}
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
@ -665,43 +641,40 @@ print_icache_struct (lf *file,
|
|||
|
||||
static void
|
||||
print_icache_function (lf *file,
|
||||
insn_entry *instruction,
|
||||
insn_entry * instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
cache_entry *cache_rules,
|
||||
int nr_prefetched_words)
|
||||
cache_entry *cache_rules, int nr_prefetched_words)
|
||||
{
|
||||
int indent;
|
||||
|
||||
/* generate code to enter decoded instruction into the icache */
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "\n");
|
||||
lf_print__function_type_function (file, print_icache_function_type,
|
||||
"EXTERN_ICACHE", "\n");
|
||||
indent = print_function_name (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
expanded_bits,
|
||||
function_name_prefix_icache);
|
||||
expanded_bits, function_name_prefix_icache);
|
||||
indent += lf_printf (file, " ");
|
||||
lf_indent (file, +indent);
|
||||
lf_printf (file, "(");
|
||||
print_icache_function_formal (file, nr_prefetched_words);
|
||||
lf_printf (file, ")\n");
|
||||
lf_indent (file, -indent);
|
||||
|
||||
|
||||
/* function header */
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
|
||||
|
||||
print_my_defines (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
expanded_bits);
|
||||
print_itrace (file, instruction, 1/*putting-value-in-cache*/);
|
||||
|
||||
instruction->format_name, expanded_bits);
|
||||
print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
|
||||
|
||||
print_idecode_validate (file, instruction, opcodes);
|
||||
|
||||
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
|
@ -716,30 +689,25 @@ print_icache_function (lf *file,
|
|||
: declare_variables),
|
||||
(options.gen.semantic_icache
|
||||
? both_values_and_icache
|
||||
: put_values_in_icache),
|
||||
nr_prefetched_words);
|
||||
|
||||
: put_values_in_icache), nr_prefetched_words);
|
||||
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "cache_entry->address = cia;\n");
|
||||
lf_printf (file, "cache_entry->semantic = ");
|
||||
print_function_name (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
expanded_bits,
|
||||
function_name_prefix_semantics);
|
||||
NULL, expanded_bits, function_name_prefix_semantics);
|
||||
lf_printf (file, ";\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
if (options.gen.semantic_icache) {
|
||||
lf_printf (file, "/* semantic routine */\n");
|
||||
print_semantic_body (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
opcodes);
|
||||
lf_printf (file, "return nia;\n");
|
||||
}
|
||||
|
||||
if (options.gen.semantic_icache)
|
||||
{
|
||||
lf_printf (file, "/* semantic routine */\n");
|
||||
print_semantic_body (file, instruction, expanded_bits, opcodes);
|
||||
lf_printf (file, "return nia;\n");
|
||||
}
|
||||
|
||||
if (!options.gen.semantic_icache)
|
||||
{
|
||||
lf_printf (file, "/* return the function proper */\n");
|
||||
|
@ -748,11 +716,10 @@ print_icache_function (lf *file,
|
|||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
expanded_bits,
|
||||
function_name_prefix_semantics);
|
||||
expanded_bits, function_name_prefix_semantics);
|
||||
lf_printf (file, ";\n");
|
||||
}
|
||||
|
||||
|
||||
if (options.gen.direct_access)
|
||||
{
|
||||
print_icache_body (file,
|
||||
|
@ -762,10 +729,9 @@ print_icache_function (lf *file,
|
|||
undef_variables,
|
||||
(options.gen.semantic_icache
|
||||
? both_values_and_icache
|
||||
: put_values_in_icache),
|
||||
nr_prefetched_words);
|
||||
: put_values_in_icache), nr_prefetched_words);
|
||||
}
|
||||
|
||||
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
lf_indent (file, -2);
|
||||
|
@ -775,25 +741,22 @@ print_icache_function (lf *file,
|
|||
|
||||
void
|
||||
print_icache_definition (lf *file,
|
||||
insn_entry *insn,
|
||||
insn_entry * insn,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
cache_entry *cache_rules,
|
||||
int nr_prefetched_words)
|
||||
cache_entry *cache_rules, int nr_prefetched_words)
|
||||
{
|
||||
print_icache_function (file,
|
||||
insn,
|
||||
expanded_bits,
|
||||
opcodes,
|
||||
cache_rules,
|
||||
nr_prefetched_words);
|
||||
opcodes, cache_rules, nr_prefetched_words);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
print_icache_internal_function_declaration (lf *file,
|
||||
function_entry *function,
|
||||
function_entry * function,
|
||||
void *data)
|
||||
{
|
||||
ASSERT (options.gen.icache);
|
||||
|
@ -804,10 +767,7 @@ print_icache_internal_function_declaration (lf *file,
|
|||
"INLINE_ICACHE", "\n");
|
||||
print_function_name (file,
|
||||
function->name,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
function_name_prefix_icache);
|
||||
NULL, NULL, NULL, function_name_prefix_icache);
|
||||
lf_printf (file, "\n(");
|
||||
print_icache_function_formal (file, 0);
|
||||
lf_printf (file, ");\n");
|
||||
|
@ -817,7 +777,7 @@ print_icache_internal_function_declaration (lf *file,
|
|||
|
||||
void
|
||||
print_icache_internal_function_definition (lf *file,
|
||||
function_entry *function,
|
||||
function_entry * function,
|
||||
void *data)
|
||||
{
|
||||
ASSERT (options.gen.icache);
|
||||
|
@ -828,10 +788,7 @@ print_icache_internal_function_definition (lf *file,
|
|||
"INLINE_ICACHE", "\n");
|
||||
print_function_name (file,
|
||||
function->name,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
function_name_prefix_icache);
|
||||
NULL, NULL, NULL, function_name_prefix_icache);
|
||||
lf_printf (file, "\n(");
|
||||
print_icache_function_formal (file, 0);
|
||||
lf_printf (file, ")\n");
|
||||
|
@ -842,7 +799,8 @@ print_icache_internal_function_definition (lf *file,
|
|||
{
|
||||
lf_print__line_ref (file, function->code->line);
|
||||
table_print_code (file, function->code);
|
||||
lf_printf (file, "error (\"Internal function must longjump\\n\");\n");
|
||||
lf_printf (file,
|
||||
"error (\"Internal function must longjump\\n\");\n");
|
||||
lf_printf (file, "return 0;\n");
|
||||
}
|
||||
else
|
||||
|
@ -851,12 +809,10 @@ print_icache_internal_function_definition (lf *file,
|
|||
print_function_name (file,
|
||||
function->name,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
function_name_prefix_semantics);
|
||||
NULL, NULL, function_name_prefix_semantics);
|
||||
lf_printf (file, ";\n");
|
||||
}
|
||||
|
||||
|
||||
lf_print__internal_ref (file);
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
|
|
|
@ -25,45 +25,45 @@
|
|||
/* Output code to manipulate the instruction cache: either create it
|
||||
or reference it */
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
declare_variables,
|
||||
define_variables,
|
||||
undef_variables,
|
||||
} icache_decl_type;
|
||||
}
|
||||
icache_decl_type;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
do_not_use_icache = 0,
|
||||
get_values_from_icache = 0x1,
|
||||
put_values_in_icache = 0x2,
|
||||
both_values_and_icache = 0x3,
|
||||
} icache_body_type;
|
||||
}
|
||||
icache_body_type;
|
||||
|
||||
extern void print_icache_body
|
||||
(lf *file,
|
||||
insn_entry *instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
cache_entry *cache_rules,
|
||||
icache_decl_type what_to_declare,
|
||||
icache_body_type what_to_do,
|
||||
int nr_prefetched_words);
|
||||
(lf *file,
|
||||
insn_entry * instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
cache_entry *cache_rules,
|
||||
icache_decl_type what_to_declare,
|
||||
icache_body_type what_to_do, int nr_prefetched_words);
|
||||
|
||||
|
||||
/* Output an instruction cache decode function */
|
||||
|
||||
extern void print_icache_declaration
|
||||
(lf *file,
|
||||
insn_entry *insn,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
int nr_prefetched_words);
|
||||
|
||||
(lf *file,
|
||||
insn_entry * insn,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes, int nr_prefetched_words);
|
||||
|
||||
extern void print_icache_definition
|
||||
(lf *file,
|
||||
insn_entry *insn,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
cache_entry *cache_rules,
|
||||
int nr_prefetched_words);
|
||||
(lf *file,
|
||||
insn_entry * insn,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes, cache_entry *cache_rules, int nr_prefetched_words);
|
||||
|
||||
|
||||
/* Output an instruction cache support function */
|
||||
|
@ -75,9 +75,7 @@ extern function_entry_handler print_icache_internal_function_definition;
|
|||
/* Output the instruction cache table data structure */
|
||||
|
||||
extern void print_icache_struct
|
||||
(lf *file,
|
||||
insn_table *instructions,
|
||||
cache_entry *cache_rules);
|
||||
(lf *file, insn_table *instructions, cache_entry *cache_rules);
|
||||
|
||||
|
||||
/* Output a single instructions decoder */
|
||||
|
|
|
@ -40,18 +40,17 @@
|
|||
|
||||
|
||||
static void
|
||||
lf_print_opcodes (lf *file,
|
||||
gen_entry *table)
|
||||
lf_print_opcodes (lf *file, gen_entry *table)
|
||||
{
|
||||
if (table != NULL)
|
||||
if (table !=NULL)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
ASSERT (table->opcode != NULL);
|
||||
lf_printf (file, "_%d_%d",
|
||||
table->opcode->first,
|
||||
table->opcode->last);
|
||||
if (table->parent == NULL) break;
|
||||
table->opcode->first, table->opcode->last);
|
||||
if (table->parent == NULL)
|
||||
break;
|
||||
lf_printf (file, "__%d", table->opcode_nr);
|
||||
table = table->parent;
|
||||
}
|
||||
|
@ -68,12 +67,12 @@ print_idecode_ifetch (lf *file,
|
|||
{
|
||||
int word_nr;
|
||||
for (word_nr = previous_nr_prefetched_words;
|
||||
word_nr < current_nr_prefetched_words;
|
||||
word_nr ++)
|
||||
word_nr < current_nr_prefetched_words; word_nr++)
|
||||
{
|
||||
lf_printf (file, "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
|
||||
lf_printf (file,
|
||||
"instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
|
||||
word_nr, options.insn_bit_size, word_nr);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,8 +82,7 @@ print_idecode_ifetch (lf *file,
|
|||
|
||||
|
||||
static void
|
||||
lf_print_table_name (lf *file,
|
||||
gen_entry *table)
|
||||
lf_print_table_name (lf *file, gen_entry *table)
|
||||
{
|
||||
lf_printf (file, "idecode_table");
|
||||
lf_print_opcodes (file, table);
|
||||
|
@ -93,9 +91,7 @@ lf_print_table_name (lf *file,
|
|||
|
||||
|
||||
static void
|
||||
print_idecode_table (lf *file,
|
||||
gen_entry *entry,
|
||||
const char *result)
|
||||
print_idecode_table (lf *file, gen_entry *entry, const char *result)
|
||||
{
|
||||
lf_printf (file, "/* prime the search */\n");
|
||||
lf_printf (file, "idecode_table_entry *table = ");
|
||||
|
@ -106,7 +102,7 @@ print_idecode_table (lf *file,
|
|||
i2target (options.hi_bit_nr, entry->opcode->first),
|
||||
i2target (options.hi_bit_nr, entry->opcode->last));
|
||||
lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n");
|
||||
|
||||
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "/* iterate until a leaf */\n");
|
||||
lf_printf (file, "while (1) {\n");
|
||||
|
@ -129,7 +125,7 @@ print_idecode_table (lf *file,
|
|||
lf_printf (file, " table_entry = table + opcode;\n");
|
||||
lf_printf (file, " }\n");
|
||||
lf_printf (file, "}\n");
|
||||
|
||||
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "/* call the leaf code */\n");
|
||||
if (options.gen.code == generate_jumps)
|
||||
|
@ -141,14 +137,16 @@ print_idecode_table (lf *file,
|
|||
lf_printf (file, "%s ", result);
|
||||
if (options.gen.icache)
|
||||
{
|
||||
lf_printf (file, "(((idecode_icache*)table_entry->function_or_table)\n");
|
||||
lf_printf (file,
|
||||
"(((idecode_icache*)table_entry->function_or_table)\n");
|
||||
lf_printf (file, " (");
|
||||
print_icache_function_actual (file, 1);
|
||||
lf_printf (file, "));\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf (file, "((idecode_semantic*)table_entry->function_or_table)\n");
|
||||
lf_printf (file,
|
||||
"((idecode_semantic*)table_entry->function_or_table)\n");
|
||||
lf_printf (file, " (");
|
||||
print_semantic_function_actual (file, 1);
|
||||
lf_printf (file, ");\n");
|
||||
|
@ -158,10 +156,7 @@ print_idecode_table (lf *file,
|
|||
|
||||
|
||||
static void
|
||||
print_idecode_table_start (lf *file,
|
||||
gen_entry *table,
|
||||
int depth,
|
||||
void *data)
|
||||
print_idecode_table_start (lf *file, gen_entry *table, int depth, void *data)
|
||||
{
|
||||
ASSERT (depth == 0);
|
||||
/* start of the table */
|
||||
|
@ -175,10 +170,7 @@ print_idecode_table_start (lf *file,
|
|||
}
|
||||
|
||||
static void
|
||||
print_idecode_table_leaf (lf *file,
|
||||
gen_entry *entry,
|
||||
int depth,
|
||||
void *data)
|
||||
print_idecode_table_leaf (lf *file, gen_entry *entry, int depth, void *data)
|
||||
{
|
||||
gen_entry *master_entry;
|
||||
ASSERT (entry->parent != NULL);
|
||||
|
@ -238,9 +230,9 @@ print_idecode_table_leaf (lf *file,
|
|||
else
|
||||
{
|
||||
/* table `calling' another table */
|
||||
lf_printf (file, "%d, ", options.insn_bit_size - entry->opcode->last - 1);
|
||||
lf_printf (file, "MASK%d(%d,%d), ",
|
||||
options.insn_bit_size,
|
||||
lf_printf (file, "%d, ",
|
||||
options.insn_bit_size - entry->opcode->last - 1);
|
||||
lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size,
|
||||
i2target (options.hi_bit_nr, entry->opcode->first),
|
||||
i2target (options.hi_bit_nr, entry->opcode->last));
|
||||
lf_printf (file, "0, ");
|
||||
|
@ -251,23 +243,20 @@ print_idecode_table_leaf (lf *file,
|
|||
}
|
||||
|
||||
static void
|
||||
print_idecode_table_end (lf *file,
|
||||
gen_entry *table,
|
||||
int depth,
|
||||
void *data)
|
||||
print_idecode_table_end (lf *file, gen_entry *table, int depth, void *data)
|
||||
{
|
||||
ASSERT (depth == 0);
|
||||
if (table->opcode_rule->gen == array_gen) {
|
||||
lf_printf (file, "};\n");
|
||||
}
|
||||
if (table->opcode_rule->gen == array_gen)
|
||||
{
|
||||
lf_printf (file, "};\n");
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
static void
|
||||
print_goto_switch_name (lf *file,
|
||||
gen_entry *entry)
|
||||
print_goto_switch_name (lf *file, gen_entry *entry)
|
||||
{
|
||||
lf_printf (file, "case_");
|
||||
if (entry->opcode == NULL)
|
||||
|
@ -283,21 +272,19 @@ print_goto_switch_name (lf *file,
|
|||
}
|
||||
else
|
||||
{
|
||||
lf_print_table_name(file, entry);
|
||||
lf_print_table_name (file, entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_goto_switch_table_leaf (lf *file,
|
||||
gen_entry *entry,
|
||||
int depth,
|
||||
void *data)
|
||||
gen_entry *entry, int depth, void *data)
|
||||
{
|
||||
ASSERT (entry->parent != NULL);
|
||||
ASSERT (depth == 0);
|
||||
ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen);
|
||||
ASSERT (entry->parent->opcode);
|
||||
|
||||
|
||||
lf_printf (file, "/* %d */ &&", entry->opcode_nr);
|
||||
if (entry->combined_parent != NULL)
|
||||
print_goto_switch_name (file, entry->combined_parent);
|
||||
|
@ -307,8 +294,7 @@ print_goto_switch_table_leaf (lf *file,
|
|||
}
|
||||
|
||||
static void
|
||||
print_goto_switch_break (lf *file,
|
||||
gen_entry *entry)
|
||||
print_goto_switch_break (lf *file, gen_entry *entry)
|
||||
{
|
||||
lf_printf (file, "goto break_");
|
||||
lf_print_table_name (file, entry->parent);
|
||||
|
@ -317,41 +303,31 @@ print_goto_switch_break (lf *file,
|
|||
|
||||
|
||||
static void
|
||||
print_goto_switch_table (lf *file,
|
||||
gen_entry *table)
|
||||
print_goto_switch_table (lf *file, gen_entry *table)
|
||||
{
|
||||
lf_printf (file, "const static void *");
|
||||
lf_print_table_name (file, table);
|
||||
lf_printf (file, "[] = {\n");
|
||||
lf_indent (file, +2);
|
||||
gen_entry_traverse_tree (file, table,
|
||||
0,
|
||||
NULL/*start*/,
|
||||
print_goto_switch_table_leaf,
|
||||
NULL/*end*/,
|
||||
NULL/*data*/);
|
||||
gen_entry_traverse_tree (file, table, 0, NULL /*start */ ,
|
||||
print_goto_switch_table_leaf, NULL /*end */ ,
|
||||
NULL /*data */ );
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "};\n");
|
||||
}
|
||||
|
||||
|
||||
void print_idecode_switch
|
||||
(lf *file,
|
||||
gen_entry *table,
|
||||
const char *result);
|
||||
void print_idecode_switch (lf *file, gen_entry *table, const char *result);
|
||||
|
||||
static void
|
||||
print_idecode_switch_start (lf *file,
|
||||
gen_entry *table,
|
||||
int depth,
|
||||
void *data)
|
||||
print_idecode_switch_start (lf *file, gen_entry *table, int depth, void *data)
|
||||
{
|
||||
/* const char *result = data; */
|
||||
ASSERT (depth == 0);
|
||||
ASSERT (table->opcode_rule->gen == switch_gen
|
||||
|| table->opcode_rule->gen == goto_switch_gen
|
||||
|| table->opcode_rule->gen == padded_switch_gen);
|
||||
|
||||
|
||||
if (table->opcode->is_boolean
|
||||
|| table->opcode_rule->gen == switch_gen
|
||||
|| table->opcode_rule->gen == padded_switch_gen)
|
||||
|
@ -393,16 +369,13 @@ print_idecode_switch_start (lf *file,
|
|||
}
|
||||
else
|
||||
{
|
||||
ASSERT("bad switch" == NULL);
|
||||
ASSERT ("bad switch" == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_idecode_switch_leaf (lf *file,
|
||||
gen_entry *entry,
|
||||
int depth,
|
||||
void *data)
|
||||
print_idecode_switch_leaf (lf *file, gen_entry *entry, int depth, void *data)
|
||||
{
|
||||
const char *result = data;
|
||||
ASSERT (entry->parent != NULL);
|
||||
|
@ -411,19 +384,17 @@ print_idecode_switch_leaf (lf *file,
|
|||
|| entry->parent->opcode_rule->gen == goto_switch_gen
|
||||
|| entry->parent->opcode_rule->gen == padded_switch_gen);
|
||||
ASSERT (entry->parent->opcode);
|
||||
|
||||
|
||||
/* skip over any instructions combined into another entry */
|
||||
if (entry->combined_parent != NULL)
|
||||
return;
|
||||
|
||||
if (entry->parent->opcode->is_boolean
|
||||
&& entry->opcode_nr == 0)
|
||||
if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0)
|
||||
{
|
||||
/* case: boolean false target */
|
||||
lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);
|
||||
}
|
||||
else if (entry->parent->opcode->is_boolean
|
||||
&& entry->opcode_nr != 0)
|
||||
else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0)
|
||||
{
|
||||
/* case: boolean true case */
|
||||
lf_printf (file, "default:\n");
|
||||
|
@ -475,7 +446,9 @@ print_idecode_switch_leaf (lf *file,
|
|||
if (options.gen.code == generate_calls)
|
||||
{
|
||||
lf_printf (file, " (");
|
||||
print_semantic_function_actual (file, entry->insns->semantic->nr_prefetched_words);
|
||||
print_semantic_function_actual (file,
|
||||
entry->insns->semantic->
|
||||
nr_prefetched_words);
|
||||
lf_printf (file, ")");
|
||||
}
|
||||
lf_printf (file, ";\n");
|
||||
|
@ -512,7 +485,7 @@ print_idecode_switch_leaf (lf *file,
|
|||
}
|
||||
else if (entry->parent->opcode_rule->gen == goto_switch_gen)
|
||||
{
|
||||
print_goto_switch_break(file, entry);
|
||||
print_goto_switch_break (file, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -525,8 +498,7 @@ print_idecode_switch_leaf (lf *file,
|
|||
|
||||
|
||||
static void
|
||||
print_idecode_switch_illegal (lf *file,
|
||||
const char *result)
|
||||
print_idecode_switch_illegal (lf *file, const char *result)
|
||||
{
|
||||
lf_indent (file, +2);
|
||||
print_idecode_invalid (file, result, invalid_illegal);
|
||||
|
@ -535,10 +507,7 @@ print_idecode_switch_illegal (lf *file,
|
|||
}
|
||||
|
||||
static void
|
||||
print_idecode_switch_end (lf *file,
|
||||
gen_entry *table,
|
||||
int depth,
|
||||
void *data)
|
||||
print_idecode_switch_end (lf *file, gen_entry *table, int depth, void *data)
|
||||
{
|
||||
const char *result = data;
|
||||
ASSERT (depth == 0);
|
||||
|
@ -546,7 +515,7 @@ print_idecode_switch_end (lf *file,
|
|||
|| table->opcode_rule->gen == goto_switch_gen
|
||||
|| table->opcode_rule->gen == padded_switch_gen);
|
||||
ASSERT (table->opcode);
|
||||
|
||||
|
||||
if (table->opcode->is_boolean)
|
||||
{
|
||||
lf_printf (file, "}\n");
|
||||
|
@ -559,7 +528,8 @@ print_idecode_switch_end (lf *file,
|
|||
lf_indent (file, +2);
|
||||
if (table->nr_entries == table->opcode->nr_opcodes)
|
||||
{
|
||||
print_sim_engine_abort (file, "Internal error - bad switch generated");
|
||||
print_sim_engine_abort (file,
|
||||
"Internal error - bad switch generated");
|
||||
lf_printf (file, "%sNULL_CIA;\n", result);
|
||||
lf_printf (file, "break;\n");
|
||||
}
|
||||
|
@ -578,7 +548,7 @@ print_idecode_switch_end (lf *file,
|
|||
lf_printf (file, ":\n");
|
||||
print_idecode_invalid (file, result, invalid_illegal);
|
||||
lf_printf (file, "break_");
|
||||
lf_print_table_name(file, table);
|
||||
lf_print_table_name (file, table);
|
||||
lf_printf (file, ":;\n");
|
||||
if (table->parent != NULL
|
||||
&& (table->parent->opcode_rule->gen == switch_gen
|
||||
|
@ -597,16 +567,13 @@ print_idecode_switch_end (lf *file,
|
|||
|
||||
|
||||
void
|
||||
print_idecode_switch (lf *file,
|
||||
gen_entry *table,
|
||||
const char *result)
|
||||
print_idecode_switch (lf *file, gen_entry *table, const char *result)
|
||||
{
|
||||
gen_entry_traverse_tree (file, table,
|
||||
0,
|
||||
print_idecode_switch_start,
|
||||
print_idecode_switch_leaf,
|
||||
print_idecode_switch_end,
|
||||
(void*)result);
|
||||
print_idecode_switch_end, (void *) result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -657,47 +624,35 @@ print_idecode_switch_function_header (lf *file,
|
|||
|
||||
|
||||
static void
|
||||
idecode_declare_if_switch (lf *file,
|
||||
gen_entry *table,
|
||||
int depth,
|
||||
void *data)
|
||||
idecode_declare_if_switch (lf *file, gen_entry *table, int depth, void *data)
|
||||
{
|
||||
if ((table->opcode_rule->gen == switch_gen
|
||||
|| table->opcode_rule->gen == goto_switch_gen
|
||||
|| table->opcode_rule->gen == padded_switch_gen)
|
||||
&& table->parent != NULL /* don't declare the top one yet */
|
||||
if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't declare the top one yet */
|
||||
&& table->parent->opcode_rule->gen == array_gen)
|
||||
{
|
||||
print_idecode_switch_function_header (file,
|
||||
table,
|
||||
0/*isnt function definition*/,
|
||||
0 /*isnt function definition */ ,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
idecode_expand_if_switch (lf *file,
|
||||
gen_entry *table,
|
||||
int depth,
|
||||
void *data)
|
||||
idecode_expand_if_switch (lf *file, gen_entry *table, int depth, void *data)
|
||||
{
|
||||
if ((table->opcode_rule->gen == switch_gen
|
||||
|| table->opcode_rule->gen == goto_switch_gen
|
||||
|| table->opcode_rule->gen == padded_switch_gen)
|
||||
&& table->parent != NULL /* don't expand the top one yet */
|
||||
if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't expand the top one yet */
|
||||
&& table->parent->opcode_rule->gen == array_gen)
|
||||
{
|
||||
print_idecode_switch_function_header(file,
|
||||
table,
|
||||
1/*is function definition*/,
|
||||
0);
|
||||
print_idecode_switch_function_header (file,
|
||||
table,
|
||||
1 /*is function definition */ ,
|
||||
0);
|
||||
if (options.gen.code == generate_calls)
|
||||
{
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
}
|
||||
print_idecode_switch(file, table, "return");
|
||||
print_idecode_switch (file, table, "return");
|
||||
if (options.gen.code == generate_calls)
|
||||
{
|
||||
lf_indent (file, -2);
|
||||
|
@ -711,45 +666,32 @@ idecode_expand_if_switch (lf *file,
|
|||
|
||||
|
||||
void
|
||||
print_idecode_lookups (lf *file,
|
||||
gen_entry *table,
|
||||
cache_entry *cache_rules)
|
||||
print_idecode_lookups (lf *file, gen_entry *table, cache_entry *cache_rules)
|
||||
{
|
||||
int depth;
|
||||
|
||||
|
||||
/* output switch function declarations where needed by tables */
|
||||
gen_entry_traverse_tree (file, table,
|
||||
1,
|
||||
idecode_declare_if_switch, /* START */
|
||||
NULL, NULL,
|
||||
NULL);
|
||||
|
||||
gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch, /* START */
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* output tables where needed */
|
||||
for (depth = gen_entry_depth (table);
|
||||
depth > 0;
|
||||
depth--)
|
||||
for (depth = gen_entry_depth (table); depth > 0; depth--)
|
||||
{
|
||||
gen_entry_traverse_tree (file, table,
|
||||
1-depth,
|
||||
1 - depth,
|
||||
print_idecode_table_start,
|
||||
print_idecode_table_leaf,
|
||||
print_idecode_table_end,
|
||||
NULL);
|
||||
print_idecode_table_end, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* output switch functions where needed */
|
||||
gen_entry_traverse_tree (file, table,
|
||||
1,
|
||||
idecode_expand_if_switch, /* START */
|
||||
NULL, NULL,
|
||||
NULL);
|
||||
gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch, /* START */
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_idecode_body (lf *file,
|
||||
gen_entry *table,
|
||||
const char *result)
|
||||
print_idecode_body (lf *file, gen_entry *table, const char *result)
|
||||
{
|
||||
if (table->opcode_rule->gen == switch_gen
|
||||
|| table->opcode_rule->gen == goto_switch_gen
|
||||
|
@ -768,15 +710,14 @@ print_idecode_body (lf *file,
|
|||
|
||||
#if 0
|
||||
static void
|
||||
print_jump (lf *file,
|
||||
int is_tail)
|
||||
print_jump (lf *file, int is_tail)
|
||||
{
|
||||
if (is_tail)
|
||||
{
|
||||
lf_putstr (file, "if (keep_running != NULL && !*keep_running)\n");
|
||||
lf_putstr (file, " cpu_halt(cpu, nia, was_continuing, 0/*na*/);\n");
|
||||
}
|
||||
|
||||
|
||||
if (!options.generate_smp)
|
||||
{
|
||||
lf_putstr (file, "if (WITH_EVENTS) {\n");
|
||||
|
@ -787,7 +728,7 @@ print_jump (lf *file,
|
|||
lf_putstr (file, " }\n");
|
||||
lf_putstr (file, "}\n");
|
||||
}
|
||||
|
||||
|
||||
if (options.generate_smp)
|
||||
{
|
||||
if (is_tail)
|
||||
|
@ -809,7 +750,7 @@ print_jump (lf *file,
|
|||
lf_putstr (file, "cpu = cpus[current_cpu];\n");
|
||||
lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
|
||||
}
|
||||
|
||||
|
||||
if (options.gen.icache)
|
||||
{
|
||||
lf_putstr (file, "cache_entry = cpu_icache_entry(cpu, nia);\n");
|
||||
|
@ -827,7 +768,7 @@ print_jump (lf *file,
|
|||
{
|
||||
lf_printf (file, "goto idecode;\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -836,16 +777,15 @@ print_jump (lf *file,
|
|||
#if 0
|
||||
static void
|
||||
print_jump_insn (lf *file,
|
||||
insn_entry *instruction,
|
||||
insn_bits *expanded_bits,
|
||||
opcode_field *opcodes,
|
||||
cache_entry *cache_rules)
|
||||
insn_entry * instruction,
|
||||
insn_bits * expanded_bits,
|
||||
opcode_field *opcodes, cache_entry *cache_rules)
|
||||
{
|
||||
|
||||
|
||||
/* what we are for the moment */
|
||||
lf_printf (file, "\n");
|
||||
print_my_defines (file, expanded_bits, instruction->name);
|
||||
|
||||
|
||||
/* output the icache entry */
|
||||
if (options.gen.icache)
|
||||
{
|
||||
|
@ -853,46 +793,36 @@ print_jump_insn (lf *file,
|
|||
lf_indent (file, -1);
|
||||
print_function_name (file,
|
||||
instruction->name,
|
||||
expanded_bits,
|
||||
function_name_prefix_icache);
|
||||
expanded_bits, function_name_prefix_icache);
|
||||
lf_printf (file, ":\n");
|
||||
lf_indent (file, +1);
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
lf_putstr (file, "const unsigned_word cia = nia;\n");
|
||||
print_itrace (file, instruction, 1/*putting-value-in-cache*/);
|
||||
print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
|
||||
print_idecode_validate (file, instruction, opcodes);
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
print_icache_body (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
cache_rules,
|
||||
0, /*use_defines*/
|
||||
print_icache_body (file, instruction, expanded_bits, cache_rules, 0, /*use_defines */
|
||||
put_values_in_icache);
|
||||
lf_printf (file, "cache_entry->address = nia;\n");
|
||||
lf_printf (file, "cache_entry->semantic = &&");
|
||||
print_function_name (file,
|
||||
instruction->name,
|
||||
expanded_bits,
|
||||
function_name_prefix_semantics);
|
||||
expanded_bits, function_name_prefix_semantics);
|
||||
lf_printf (file, ";\n");
|
||||
if (options.gen.semantic_icache)
|
||||
{
|
||||
print_semantic_body (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
opcodes);
|
||||
print_jump (file, 1/*is-tail*/);
|
||||
print_semantic_body (file, instruction, expanded_bits, opcodes);
|
||||
print_jump (file, 1 /*is-tail */ );
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf (file, "/* goto ");
|
||||
print_function_name (file,
|
||||
instruction->name,
|
||||
expanded_bits,
|
||||
function_name_prefix_semantics);
|
||||
expanded_bits, function_name_prefix_semantics);
|
||||
lf_printf (file, "; */\n");
|
||||
}
|
||||
lf_indent (file, -2);
|
||||
|
@ -900,14 +830,13 @@ print_jump_insn (lf *file,
|
|||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
}
|
||||
|
||||
|
||||
/* print the semantics */
|
||||
lf_printf (file, "\n");
|
||||
lf_indent (file, -1);
|
||||
print_function_name (file,
|
||||
instruction->name,
|
||||
expanded_bits,
|
||||
function_name_prefix_semantics);
|
||||
expanded_bits, function_name_prefix_semantics);
|
||||
lf_printf (file, ":\n");
|
||||
lf_indent (file, +1);
|
||||
lf_printf (file, "{\n");
|
||||
|
@ -921,12 +850,8 @@ print_jump_insn (lf *file,
|
|||
? define_variables
|
||||
: declare_variables),
|
||||
(options.gen.icache
|
||||
? get_values_from_icache
|
||||
: do_not_use_icache));
|
||||
print_semantic_body (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
opcodes);
|
||||
? get_values_from_icache : do_not_use_icache));
|
||||
print_semantic_body (file, instruction, expanded_bits, opcodes);
|
||||
if (options.gen.direct_access)
|
||||
print_icache_body (file,
|
||||
instruction,
|
||||
|
@ -934,9 +859,8 @@ print_jump_insn (lf *file,
|
|||
cache_rules,
|
||||
undef_variables,
|
||||
(options.gen.icache
|
||||
? get_values_from_icache
|
||||
: do_not_use_icache));
|
||||
print_jump (file, 1/*is tail*/);
|
||||
? get_values_from_icache : do_not_use_icache));
|
||||
print_jump (file, 1 /*is tail */ );
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
}
|
||||
|
@ -947,17 +871,14 @@ print_jump_insn (lf *file,
|
|||
static void
|
||||
print_jump_definition (lf *file,
|
||||
gen_entry *entry,
|
||||
insn_entry *insn,
|
||||
int depth,
|
||||
void *data)
|
||||
insn_entry * insn, int depth, void *data)
|
||||
{
|
||||
cache_entry *cache_rules = (cache_entry*)data;
|
||||
cache_entry *cache_rules = (cache_entry *) data;
|
||||
if (options.generate_expanded_instructions)
|
||||
{
|
||||
ASSERT (entry->nr_insns == 1
|
||||
&& entry->opcode == NULL
|
||||
&& entry->parent != NULL
|
||||
&& entry->parent->opcode != NULL);
|
||||
&& entry->parent != NULL && entry->parent->opcode != NULL);
|
||||
ASSERT (entry->nr_insns == 1
|
||||
&& entry->opcode == NULL
|
||||
&& entry->parent != NULL
|
||||
|
@ -965,17 +886,12 @@ print_jump_definition (lf *file,
|
|||
&& entry->parent->opcode_rule != NULL);
|
||||
print_jump_insn (file,
|
||||
entry->insns->words[0]->insn,
|
||||
entry->expanded_bits,
|
||||
entry->opcode,
|
||||
cache_rules);
|
||||
entry->expanded_bits, entry->opcode, cache_rules);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_jump_insn (file,
|
||||
instruction->words[0]->insn,
|
||||
NULL,
|
||||
NULL,
|
||||
cache_rules);
|
||||
instruction->words[0]->insn, NULL, NULL, cache_rules);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -984,8 +900,7 @@ print_jump_definition (lf *file,
|
|||
static void
|
||||
print_jump_internal_function (lf *file,
|
||||
gen_entry *table,
|
||||
function_entry *function,
|
||||
void *data)
|
||||
function_entry * function, void *data)
|
||||
{
|
||||
if (function->is_internal)
|
||||
{
|
||||
|
@ -1016,9 +931,8 @@ print_jump_internal_function (lf *file,
|
|||
|
||||
#if 0
|
||||
static void
|
||||
print_jump_until_stop_body(lf *file,
|
||||
insn_table *table,
|
||||
cache_table *cache_rules)
|
||||
print_jump_until_stop_body (lf *file,
|
||||
insn_table *table, cache_table * cache_rules)
|
||||
{
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
|
@ -1027,25 +941,28 @@ print_jump_until_stop_body(lf *file,
|
|||
lf_putstr (file, "sim_cpu *cpu = NULL;\n");
|
||||
lf_putstr (file, "unsigned_word nia = -1;\n");
|
||||
lf_putstr (file, "instruction_word instruction = 0;\n");
|
||||
if ((code & generate_with_icache)) {
|
||||
lf_putstr (file, "idecode_cache *cache_entry = NULL;\n");
|
||||
}
|
||||
if (generate_smp) {
|
||||
lf_putstr (file, "int current_cpu = -1;\n");
|
||||
}
|
||||
if ((code & generate_with_icache))
|
||||
{
|
||||
lf_putstr (file, "idecode_cache *cache_entry = NULL;\n");
|
||||
}
|
||||
if (generate_smp)
|
||||
{
|
||||
lf_putstr (file, "int current_cpu = -1;\n");
|
||||
}
|
||||
|
||||
/* all the switches and tables - they know about jumping */
|
||||
print_idecode_lookups(file, table, cache_rules);
|
||||
|
||||
print_idecode_lookups (file, table, cache_rules);
|
||||
|
||||
/* start the simulation up */
|
||||
if ((code & generate_with_icache)) {
|
||||
lf_putstr (file, "\n");
|
||||
lf_putstr (file, "{\n");
|
||||
lf_putstr (file, " int cpu_nr;\n");
|
||||
lf_putstr (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
|
||||
lf_putstr (file, " cpu_flush_icache(cpus[cpu_nr]);\n");
|
||||
lf_putstr (file, "}\n");
|
||||
}
|
||||
if ((code & generate_with_icache))
|
||||
{
|
||||
lf_putstr (file, "\n");
|
||||
lf_putstr (file, "{\n");
|
||||
lf_putstr (file, " int cpu_nr;\n");
|
||||
lf_putstr (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
|
||||
lf_putstr (file, " cpu_flush_icache(cpus[cpu_nr]);\n");
|
||||
lf_putstr (file, "}\n");
|
||||
}
|
||||
|
||||
lf_putstr (file, "\n");
|
||||
lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
|
||||
|
@ -1058,52 +975,51 @@ print_jump_until_stop_body(lf *file,
|
|||
lf_putstr (file, "setjmp(restart);\n");
|
||||
|
||||
lf_putstr (file, "\n");
|
||||
if (!generate_smp) {
|
||||
lf_putstr (file, "cpu = cpus[0];\n");
|
||||
lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
|
||||
}
|
||||
else {
|
||||
lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
|
||||
}
|
||||
if (!generate_smp)
|
||||
{
|
||||
lf_putstr (file, "cpu = cpus[0];\n");
|
||||
lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
|
||||
}
|
||||
|
||||
if (!(code & generate_with_icache)) {
|
||||
lf_printf (file, "\n");
|
||||
lf_indent (file, -1);
|
||||
lf_printf (file, "idecode:\n");
|
||||
lf_indent (file, +1);
|
||||
}
|
||||
if (!(code & generate_with_icache))
|
||||
{
|
||||
lf_printf (file, "\n");
|
||||
lf_indent (file, -1);
|
||||
lf_printf (file, "idecode:\n");
|
||||
lf_indent (file, +1);
|
||||
}
|
||||
|
||||
print_jump(file, 0/*is_tail*/);
|
||||
print_jump (file, 0 /*is_tail */ );
|
||||
|
||||
if ((code & generate_with_icache)) {
|
||||
lf_indent (file, -1);
|
||||
lf_printf (file, "cache_miss:\n");
|
||||
lf_indent (file, +1);
|
||||
}
|
||||
if ((code & generate_with_icache))
|
||||
{
|
||||
lf_indent (file, -1);
|
||||
lf_printf (file, "cache_miss:\n");
|
||||
lf_indent (file, +1);
|
||||
}
|
||||
|
||||
lf_putstr (file, "instruction\n");
|
||||
lf_putstr (file, " = vm_instruction_map_read(cpu_instruction_map(cpu),\n");
|
||||
lf_putstr (file, " cpu, nia);\n");
|
||||
print_idecode_body(file, table, "/*IGORE*/");
|
||||
print_idecode_body (file, table, "/*IGORE*/");
|
||||
|
||||
/* print out a table of all the internals functions */
|
||||
insn_table_traverse_function(table,
|
||||
file, NULL,
|
||||
print_jump_internal_function);
|
||||
insn_table_traverse_function (table,
|
||||
file, NULL, print_jump_internal_function);
|
||||
|
||||
/* print out a table of all the instructions */
|
||||
/* print out a table of all the instructions */
|
||||
if (generate_expanded_instructions)
|
||||
insn_table_traverse_tree(table,
|
||||
file, cache_rules,
|
||||
1,
|
||||
NULL, /* start */
|
||||
print_jump_definition, /* leaf */
|
||||
NULL, /* end */
|
||||
NULL); /* padding */
|
||||
insn_table_traverse_tree (table, file, cache_rules, 1, NULL, /* start */
|
||||
print_jump_definition, /* leaf */
|
||||
NULL, /* end */
|
||||
NULL); /* padding */
|
||||
else
|
||||
insn_table_traverse_insn(table,
|
||||
file, cache_rules,
|
||||
print_jump_definition);
|
||||
insn_table_traverse_insn (table,
|
||||
file, cache_rules, print_jump_definition);
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
}
|
||||
|
@ -1120,8 +1036,7 @@ print_jump_until_stop_body(lf *file,
|
|||
|
||||
void
|
||||
print_idecode_validate (lf *file,
|
||||
insn_entry *instruction,
|
||||
insn_opcodes *opcode_paths)
|
||||
insn_entry * instruction, insn_opcodes *opcode_paths)
|
||||
{
|
||||
/* Validate: unchecked instruction fields
|
||||
|
||||
|
@ -1154,27 +1069,24 @@ print_idecode_validate (lf *file,
|
|||
/* Make space for the next bit */
|
||||
check_mask <<= 1;
|
||||
check_val <<= 1;
|
||||
|
||||
|
||||
/* Only need to validate constant (and reserved)
|
||||
bits. Skip any others */
|
||||
bits. Skip any others */
|
||||
if (field->type != insn_field_int
|
||||
&& field->type != insn_field_reserved)
|
||||
continue;
|
||||
|
||||
/* Look through the list of opcode paths that lead to this
|
||||
instruction. See if any have failed to check the
|
||||
relevant bit */
|
||||
instruction. See if any have failed to check the
|
||||
relevant bit */
|
||||
if (opcode_paths != NULL)
|
||||
{
|
||||
insn_opcodes *entry;
|
||||
for (entry = opcode_paths;
|
||||
entry != NULL;
|
||||
entry = entry->next)
|
||||
for (entry = opcode_paths; entry != NULL; entry = entry->next)
|
||||
{
|
||||
opcode_field *opcode;
|
||||
for (opcode = entry->opcode;
|
||||
opcode != NULL;
|
||||
opcode = opcode->parent)
|
||||
opcode != NULL; opcode = opcode->parent)
|
||||
{
|
||||
if (opcode->word_nr == word_nr
|
||||
&& opcode->first <= bit_nr
|
||||
|
@ -1188,14 +1100,14 @@ print_idecode_validate (lf *file,
|
|||
}
|
||||
if (entry == NULL)
|
||||
/* all the opcode paths decoded on BIT_NR, no need
|
||||
to check it */
|
||||
to check it */
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
check_mask |= 1;
|
||||
check_val |= bit->value;
|
||||
}
|
||||
|
||||
|
||||
/* if any bits not checked by opcode tables, output code to check them */
|
||||
if (check_mask)
|
||||
{
|
||||
|
@ -1205,23 +1117,23 @@ print_idecode_validate (lf *file,
|
|||
lf_printf (file, " {\n");
|
||||
lf_indent (file, +4);
|
||||
}
|
||||
nr_checks ++;
|
||||
nr_checks++;
|
||||
if (options.insn_bit_size > 32)
|
||||
{
|
||||
lf_printf (file, "if ((instruction_%d\n", word_nr);
|
||||
lf_printf (file, "if ((instruction_%d\n", word_nr);
|
||||
lf_printf (file, " & UNSIGNED64 (0x%08lx%08lx))\n",
|
||||
(unsigned long)(check_mask >> 32),
|
||||
(unsigned long)(check_mask));
|
||||
(unsigned long) (check_mask >> 32),
|
||||
(unsigned long) (check_mask));
|
||||
lf_printf (file, " != UNSIGNED64 (0x%08lx%08lx))\n",
|
||||
(unsigned long)(check_val >> 32),
|
||||
(unsigned long)(check_val));
|
||||
(unsigned long) (check_val >> 32),
|
||||
(unsigned long) (check_val));
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf (file, "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
|
||||
word_nr,
|
||||
(unsigned long)(check_mask),
|
||||
(unsigned long)(check_val));
|
||||
lf_printf (file,
|
||||
"if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
|
||||
word_nr, (unsigned long) (check_mask),
|
||||
(unsigned long) (check_val));
|
||||
}
|
||||
lf_indent (file, +2);
|
||||
print_idecode_invalid (file, "return", invalid_illegal);
|
||||
|
@ -1233,12 +1145,12 @@ print_idecode_validate (lf *file,
|
|||
lf_indent (file, -4);
|
||||
lf_printf (file, " }\n");
|
||||
}
|
||||
lf_indent_suppress(file);
|
||||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#endif\n");
|
||||
}
|
||||
|
||||
/* Validate: Floating Point hardware
|
||||
|
||||
|
||||
If the simulator is being built with out floating point hardware
|
||||
(different to it being disabled in the MSR) then floating point
|
||||
instructions are invalid */
|
||||
|
@ -1249,7 +1161,8 @@ print_idecode_validate (lf *file,
|
|||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n");
|
||||
lf_printf (file, "/* Validate: FP hardware exists */\n");
|
||||
lf_printf (file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
|
||||
lf_printf (file,
|
||||
"if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
|
||||
lf_indent (file, +2);
|
||||
print_idecode_invalid (file, "return", invalid_illegal);
|
||||
lf_indent (file, -2);
|
||||
|
@ -1277,14 +1190,14 @@ print_idecode_validate (lf *file,
|
|||
lf_printf (file, "/* Validate: FP available according to cpu */\n");
|
||||
lf_printf (file, "if (!IS_FP_AVAILABLE) {\n");
|
||||
lf_indent (file, +2);
|
||||
print_idecode_invalid (file, "return", invalid_fp_unavailable);
|
||||
print_idecode_invalid (file, "return", invalid_fp_unavailable);
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#endif\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Validate: Validate Instruction in correct slot
|
||||
|
||||
Some architectures place restrictions on the slot that an
|
||||
|
@ -1297,7 +1210,8 @@ print_idecode_validate (lf *file,
|
|||
lf_printf (file, "\n");
|
||||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#if defined(IS_WRONG_SLOT)\n");
|
||||
lf_printf (file, "/* Validate: Instruction issued in correct slot */\n");
|
||||
lf_printf (file,
|
||||
"/* Validate: Instruction issued in correct slot */\n");
|
||||
lf_printf (file, "if (IS_WRONG_SLOT) {\n");
|
||||
lf_indent (file, +2);
|
||||
print_idecode_invalid (file, "return", invalid_wrong_slot);
|
||||
|
@ -1307,7 +1221,7 @@ print_idecode_validate (lf *file,
|
|||
lf_printf (file, "#endif\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1326,13 +1240,11 @@ print_idecode_issue_function_header (lf *file,
|
|||
{
|
||||
case is_function_declaration:
|
||||
lf_print__function_type_function (file, print_semantic_function_type,
|
||||
"INLINE_IDECODE",
|
||||
" ");
|
||||
"INLINE_IDECODE", " ");
|
||||
break;
|
||||
case is_function_definition:
|
||||
lf_print__function_type_function (file, print_semantic_function_type,
|
||||
"INLINE_IDECODE",
|
||||
"\n");
|
||||
"INLINE_IDECODE", "\n");
|
||||
break;
|
||||
case is_function_variable:
|
||||
print_semantic_function_type (file);
|
||||
|
@ -1343,8 +1255,7 @@ print_idecode_issue_function_header (lf *file,
|
|||
"issue",
|
||||
NULL,
|
||||
processor,
|
||||
NULL,
|
||||
function_name_prefix_idecode);
|
||||
NULL, function_name_prefix_idecode);
|
||||
switch (decl_type)
|
||||
{
|
||||
case is_function_definition:
|
||||
|
|
|
@ -23,23 +23,16 @@
|
|||
|
||||
|
||||
void print_idecode_issue_function_header
|
||||
(lf *file,
|
||||
const char *processor,
|
||||
function_decl_type decl_type,
|
||||
int nr_prefetched_words);
|
||||
(lf *file,
|
||||
const char *processor,
|
||||
function_decl_type decl_type, int nr_prefetched_words);
|
||||
|
||||
void print_idecode_globals
|
||||
(lf *file);
|
||||
void print_idecode_globals (lf *file);
|
||||
|
||||
void print_idecode_lookups
|
||||
(lf *file,
|
||||
gen_entry *table,
|
||||
cache_entry *cache_rules);
|
||||
(lf *file, gen_entry *table, cache_entry *cache_rules);
|
||||
|
||||
void print_idecode_body
|
||||
(lf *file,
|
||||
gen_entry *table,
|
||||
const char *result);
|
||||
void print_idecode_body (lf *file, gen_entry *table, const char *result);
|
||||
|
||||
|
||||
|
||||
|
@ -49,6 +42,4 @@ void print_idecode_body
|
|||
hardware isn't disabled */
|
||||
|
||||
extern void print_idecode_validate
|
||||
(lf *file,
|
||||
insn_entry *instruction,
|
||||
insn_opcodes *opcode_paths);
|
||||
(lf *file, insn_entry * instruction, insn_opcodes *opcode_paths);
|
||||
|
|
|
@ -42,18 +42,18 @@
|
|||
|
||||
|
||||
|
||||
typedef struct _itable_info {
|
||||
typedef struct _itable_info
|
||||
{
|
||||
int sizeof_form;
|
||||
int sizeof_name;
|
||||
int sizeof_file;
|
||||
} itable_info;
|
||||
}
|
||||
itable_info;
|
||||
|
||||
|
||||
static void
|
||||
itable_h_insn (lf *file,
|
||||
insn_table *entry,
|
||||
insn_entry *instruction,
|
||||
void *data)
|
||||
insn_table *entry, insn_entry * instruction, void *data)
|
||||
{
|
||||
int len;
|
||||
itable_info *info = data;
|
||||
|
@ -62,9 +62,7 @@ itable_h_insn (lf *file,
|
|||
print_function_name (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
NULL,
|
||||
function_name_prefix_itable);
|
||||
NULL, NULL, function_name_prefix_itable);
|
||||
lf_printf (file, ",\n");
|
||||
/* update summary info */
|
||||
len = strlen (instruction->format_name);
|
||||
|
@ -82,16 +80,13 @@ itable_h_insn (lf *file,
|
|||
/* print the list of all the different options */
|
||||
|
||||
static void
|
||||
itable_print_enum (lf *file,
|
||||
filter *set,
|
||||
char *name)
|
||||
itable_print_enum (lf *file, filter *set, char *name)
|
||||
{
|
||||
char *elem;
|
||||
lf_printf (file, "typedef enum {\n");
|
||||
lf_indent (file, +2);
|
||||
for (elem = filter_next (set, "");
|
||||
elem != NULL;
|
||||
elem = filter_next (set, elem))
|
||||
elem != NULL; elem = filter_next (set, elem))
|
||||
{
|
||||
lf_printf (file, "%sitable_%s_%s,\n",
|
||||
options.module.itable.prefix.l, name, elem);
|
||||
|
@ -102,8 +97,9 @@ itable_print_enum (lf *file,
|
|||
name, elem, options.module.itable.prefix.l, name, elem);
|
||||
}
|
||||
}
|
||||
lf_printf (file, "nr_%sitable_%ss,\n", options.module.itable.prefix.l, name);
|
||||
|
||||
lf_printf (file, "nr_%sitable_%ss,\n", options.module.itable.prefix.l,
|
||||
name);
|
||||
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "} %sitable_%ss;\n", options.module.itable.prefix.l, name);
|
||||
if (strlen (options.module.itable.prefix.l) > 0)
|
||||
|
@ -120,9 +116,7 @@ itable_print_enum (lf *file,
|
|||
/* print an array of the option names as strings */
|
||||
|
||||
static void
|
||||
itable_print_names (lf *file,
|
||||
filter *set,
|
||||
char *name)
|
||||
itable_print_names (lf *file, filter *set, char *name)
|
||||
{
|
||||
char *elem;
|
||||
lf_printf (file, "const char *%sitable_%s_names[nr_%sitable_%ss + 1] = {\n",
|
||||
|
@ -130,8 +124,7 @@ itable_print_names (lf *file,
|
|||
options.module.itable.prefix.l, name);
|
||||
lf_indent (file, +2);
|
||||
for (elem = filter_next (set, "");
|
||||
elem != NULL;
|
||||
elem = filter_next (set, elem))
|
||||
elem != NULL; elem = filter_next (set, elem))
|
||||
{
|
||||
lf_printf (file, "\"%s\",\n", elem);
|
||||
}
|
||||
|
@ -140,16 +133,16 @@ itable_print_names (lf *file,
|
|||
lf_printf (file, "};\n");
|
||||
}
|
||||
|
||||
extern void
|
||||
gen_itable_h (lf *file,
|
||||
insn_table *isa)
|
||||
extern void
|
||||
gen_itable_h (lf *file, insn_table *isa)
|
||||
{
|
||||
itable_info *info = ZALLOC (itable_info);
|
||||
|
||||
/* output an enumerated type for each instruction */
|
||||
lf_printf (file, "typedef enum {\n");
|
||||
insn_table_traverse_insn (file, isa, itable_h_insn, info);
|
||||
lf_printf (file, " nr_%sitable_entries,\n", options.module.itable.prefix.l);
|
||||
lf_printf (file, " nr_%sitable_entries,\n",
|
||||
options.module.itable.prefix.l);
|
||||
lf_printf (file, "} %sitable_index;\n", options.module.itable.prefix.l);
|
||||
lf_printf (file, "\n");
|
||||
|
||||
|
@ -158,7 +151,7 @@ gen_itable_h (lf *file,
|
|||
lf_printf (file, "extern const char *%sitable_flag_names[];\n",
|
||||
options.module.itable.prefix.l);
|
||||
lf_printf (file, "\n");
|
||||
|
||||
|
||||
/* output an enumeration of all the possible options */
|
||||
itable_print_enum (file, isa->options, "option");
|
||||
lf_printf (file, "extern const char *%sitable_option_names[];\n",
|
||||
|
@ -220,9 +213,7 @@ gen_itable_h (lf *file,
|
|||
/****************************************************************/
|
||||
|
||||
static void
|
||||
itable_print_set (lf *file,
|
||||
filter *set,
|
||||
filter *members)
|
||||
itable_print_set (lf *file, filter *set, filter *members)
|
||||
{
|
||||
char *elem;
|
||||
lf_printf (file, "\"");
|
||||
|
@ -240,10 +231,9 @@ itable_print_set (lf *file,
|
|||
}
|
||||
lf_printf (file, "\",\n");
|
||||
|
||||
lf_printf(file, "{");
|
||||
lf_printf (file, "{");
|
||||
for (elem = filter_next (set, "");
|
||||
elem != NULL;
|
||||
elem = filter_next (set, elem))
|
||||
elem != NULL; elem = filter_next (set, elem))
|
||||
{
|
||||
if (filter_is_member (members, elem))
|
||||
{
|
||||
|
@ -253,27 +243,23 @@ itable_print_set (lf *file,
|
|||
{
|
||||
lf_printf (file, " 0,");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/* always print a dummy element, to avoid empty initializers. */
|
||||
lf_printf(file, " 99 },\n");
|
||||
lf_printf (file, " 99 },\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
itable_c_insn (lf *file,
|
||||
insn_table *isa,
|
||||
insn_entry *instruction,
|
||||
void *data)
|
||||
insn_table *isa, insn_entry * instruction, void *data)
|
||||
{
|
||||
lf_printf (file, "{ ");
|
||||
lf_indent (file, +2);
|
||||
print_function_name (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
NULL,
|
||||
function_name_prefix_itable);
|
||||
NULL, NULL, function_name_prefix_itable);
|
||||
lf_printf (file, ",\n");
|
||||
lf_printf (file, "\"");
|
||||
print_insn_words (file, instruction);
|
||||
|
@ -284,22 +270,22 @@ itable_c_insn (lf *file,
|
|||
itable_print_set (file, isa->options, instruction->options);
|
||||
itable_print_set (file, isa->model->processors, instruction->processors);
|
||||
|
||||
lf_printf(file, "\"%s\",\n", instruction->name);
|
||||
lf_printf(file, "\"%s\",\n",
|
||||
filter_filename (instruction->line->file_name));
|
||||
lf_printf(file, "%d,\n", instruction->line->line_nr);
|
||||
lf_printf(file, "},\n");
|
||||
lf_printf (file, "\"%s\",\n", instruction->name);
|
||||
lf_printf (file, "\"%s\",\n",
|
||||
filter_filename (instruction->line->file_name));
|
||||
lf_printf (file, "%d,\n", instruction->line->line_nr);
|
||||
lf_printf (file, "},\n");
|
||||
lf_indent (file, -2);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
gen_itable_c (lf *file,
|
||||
insn_table *isa)
|
||||
extern void
|
||||
gen_itable_c (lf *file, insn_table *isa)
|
||||
{
|
||||
/* leader */
|
||||
lf_printf(file, "#include \"%sitable.h\"\n", options.module.itable.prefix.l);
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "#include \"%sitable.h\"\n",
|
||||
options.module.itable.prefix.l);
|
||||
lf_printf (file, "\n");
|
||||
|
||||
/* FIXME - output model data??? */
|
||||
/* FIXME - output assembler data??? */
|
||||
|
@ -312,9 +298,8 @@ gen_itable_c (lf *file,
|
|||
/* output the table that contains the actual instruction info */
|
||||
lf_printf (file, "%sitable_info %sitable[nr_%sitable_entries] = {\n",
|
||||
options.module.itable.prefix.l,
|
||||
options.module.itable.prefix.l,
|
||||
options.module.itable.prefix.l);
|
||||
options.module.itable.prefix.l, options.module.itable.prefix.l);
|
||||
insn_table_traverse_insn (file, isa, itable_c_insn, NULL);
|
||||
|
||||
lf_printf(file, "};\n");
|
||||
lf_printf (file, "};\n");
|
||||
}
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
|
||||
/* Output a table of all the instructions */
|
||||
|
||||
extern void gen_itable_h
|
||||
(lf *file,
|
||||
insn_table *table);
|
||||
extern void gen_itable_h (lf *file, insn_table *table);
|
||||
|
||||
extern void gen_itable_c
|
||||
(lf *file,
|
||||
insn_table *table);
|
||||
extern void gen_itable_c (lf *file, insn_table *table);
|
||||
|
|
|
@ -40,38 +40,37 @@
|
|||
|
||||
#if 0
|
||||
static void
|
||||
model_c_or_h_data(insn_table *table,
|
||||
lf *file,
|
||||
table_entry *data)
|
||||
model_c_or_h_data (insn_table *table, lf *file, table_entry *data)
|
||||
{
|
||||
if (data->annex) {
|
||||
table_entry_print_cpp_line_nr(file, data->annex_line);
|
||||
lf_print__c_code(file, data->annex);
|
||||
lf_print__internal_reference(file);
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
if (data->annex)
|
||||
{
|
||||
table_entry_print_cpp_line_nr (file, data->annex_line);
|
||||
lf_print__c_code (file, data->annex);
|
||||
lf_print__internal_reference (file);
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
model_c_or_h_function(insn_table *entry,
|
||||
lf *file,
|
||||
table_entry *function,
|
||||
char *prefix)
|
||||
model_c_or_h_function (insn_table *entry,
|
||||
lf *file, table_entry *function, char *prefix)
|
||||
{
|
||||
if (function->fields[function_type] == NULL
|
||||
|| function->fields[function_type][0] == '\0') {
|
||||
error("Model function type not specified for %s", function->fields[function_name]);
|
||||
}
|
||||
lf_printf(file, "\n");
|
||||
lf_print_function_type(file, function->fields[function_type], prefix, " ");
|
||||
lf_printf(file, "%s\n(%s);\n",
|
||||
function->fields[function_name],
|
||||
function->fields[function_param]);
|
||||
lf_printf(file, "\n");
|
||||
|| function->fields[function_type][0] == '\0')
|
||||
{
|
||||
error ("Model function type not specified for %s",
|
||||
function->fields[function_name]);
|
||||
}
|
||||
lf_printf (file, "\n");
|
||||
lf_print_function_type (file, function->fields[function_type], prefix, " ");
|
||||
lf_printf (file, "%s\n(%s);\n",
|
||||
function->fields[function_name],
|
||||
function->fields[function_param]);
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
gen_model_h(insn_table *table, lf *file)
|
||||
void
|
||||
gen_model_h (insn_table *table, lf *file)
|
||||
{
|
||||
insn *insn_ptr;
|
||||
model *model_ptr;
|
||||
|
@ -83,161 +82,171 @@ gen_model_h(insn_table *table, lf *file)
|
|||
int model_mon_info_p = 0;
|
||||
int model_mon_info_free_p = 0;
|
||||
|
||||
for(macro = model_macros; macro; macro = macro->next) {
|
||||
model_c_or_h_data(table, file, macro->file_entry);
|
||||
}
|
||||
for (macro = model_macros; macro; macro = macro->next)
|
||||
{
|
||||
model_c_or_h_data (table, file, macro->file_entry);
|
||||
}
|
||||
|
||||
lf_printf(file, "typedef enum _model_enum {\n");
|
||||
lf_printf(file, " MODEL_NONE,\n");
|
||||
for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
|
||||
lf_printf(file, " MODEL_%s,\n", model_ptr->name);
|
||||
}
|
||||
lf_printf(file, " nr_models\n");
|
||||
lf_printf(file, "} model_enum;\n");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "typedef enum _model_enum {\n");
|
||||
lf_printf (file, " MODEL_NONE,\n");
|
||||
for (model_ptr = models; model_ptr; model_ptr = model_ptr->next)
|
||||
{
|
||||
lf_printf (file, " MODEL_%s,\n", model_ptr->name);
|
||||
}
|
||||
lf_printf (file, " nr_models\n");
|
||||
lf_printf (file, "} model_enum;\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
lf_printf(file, "#define DEFAULT_MODEL MODEL_%s\n", (models) ? models->name : "NONE");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "#define DEFAULT_MODEL MODEL_%s\n",
|
||||
(models) ? models->name : "NONE");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
lf_printf(file, "typedef struct _model_data model_data;\n");
|
||||
lf_printf(file, "typedef struct _model_time model_time;\n");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "typedef struct _model_data model_data;\n");
|
||||
lf_printf (file, "typedef struct _model_time model_time;\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
lf_printf(file, "extern model_enum current_model;\n");
|
||||
lf_printf(file, "extern const char *model_name[ (int)nr_models ];\n");
|
||||
lf_printf(file, "extern const char *const *const model_func_unit_name[ (int)nr_models ];\n");
|
||||
lf_printf(file, "extern const model_time *const model_time_mapping[ (int)nr_models ];\n");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "extern model_enum current_model;\n");
|
||||
lf_printf (file, "extern const char *model_name[ (int)nr_models ];\n");
|
||||
lf_printf (file,
|
||||
"extern const char *const *const model_func_unit_name[ (int)nr_models ];\n");
|
||||
lf_printf (file,
|
||||
"extern const model_time *const model_time_mapping[ (int)nr_models ];\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||
model_c_or_h_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
|
||||
name = insn_ptr->file_entry->fields[function_name];
|
||||
if (strcmp (name, "model_create") == 0)
|
||||
model_create_p = 1;
|
||||
else if (strcmp (name, "model_init") == 0)
|
||||
model_init_p = 1;
|
||||
else if (strcmp (name, "model_halt") == 0)
|
||||
model_halt_p = 1;
|
||||
else if (strcmp (name, "model_mon_info") == 0)
|
||||
model_mon_info_p = 1;
|
||||
else if (strcmp (name, "model_mon_info_free") == 0)
|
||||
model_mon_info_free_p = 1;
|
||||
}
|
||||
for (insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next)
|
||||
{
|
||||
model_c_or_h_function (table, file, insn_ptr->file_entry,
|
||||
"INLINE_MODEL");
|
||||
name = insn_ptr->file_entry->fields[function_name];
|
||||
if (strcmp (name, "model_create") == 0)
|
||||
model_create_p = 1;
|
||||
else if (strcmp (name, "model_init") == 0)
|
||||
model_init_p = 1;
|
||||
else if (strcmp (name, "model_halt") == 0)
|
||||
model_halt_p = 1;
|
||||
else if (strcmp (name, "model_mon_info") == 0)
|
||||
model_mon_info_p = 1;
|
||||
else if (strcmp (name, "model_mon_info_free") == 0)
|
||||
model_mon_info_free_p = 1;
|
||||
}
|
||||
|
||||
if (!model_create_p) {
|
||||
lf_print_function_type(file, "model_data *", "INLINE_MODEL", " ");
|
||||
lf_printf(file, "model_create\n");
|
||||
lf_printf(file, "(sim_cpu *cpu);\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
if (!model_create_p)
|
||||
{
|
||||
lf_print_function_type (file, "model_data *", "INLINE_MODEL", " ");
|
||||
lf_printf (file, "model_create\n");
|
||||
lf_printf (file, "(sim_cpu *cpu);\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
if (!model_init_p) {
|
||||
lf_print_function_type(file, "void", "INLINE_MODEL", " ");
|
||||
lf_printf(file, "model_init\n");
|
||||
lf_printf(file, "(model_data *model_ptr);\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
if (!model_init_p)
|
||||
{
|
||||
lf_print_function_type (file, "void", "INLINE_MODEL", " ");
|
||||
lf_printf (file, "model_init\n");
|
||||
lf_printf (file, "(model_data *model_ptr);\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
if (!model_halt_p) {
|
||||
lf_print_function_type(file, "void", "INLINE_MODEL", " ");
|
||||
lf_printf(file, "model_halt\n");
|
||||
lf_printf(file, "(model_data *model_ptr);\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
if (!model_halt_p)
|
||||
{
|
||||
lf_print_function_type (file, "void", "INLINE_MODEL", " ");
|
||||
lf_printf (file, "model_halt\n");
|
||||
lf_printf (file, "(model_data *model_ptr);\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
if (!model_mon_info_p) {
|
||||
lf_print_function_type(file, "model_print *", "INLINE_MODEL", " ");
|
||||
lf_printf(file, "model_mon_info\n");
|
||||
lf_printf(file, "(model_data *model_ptr);\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
if (!model_mon_info_p)
|
||||
{
|
||||
lf_print_function_type (file, "model_print *", "INLINE_MODEL", " ");
|
||||
lf_printf (file, "model_mon_info\n");
|
||||
lf_printf (file, "(model_data *model_ptr);\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
if (!model_mon_info_free_p) {
|
||||
lf_print_function_type(file, "void", "INLINE_MODEL", " ");
|
||||
lf_printf(file, "model_mon_info_free\n");
|
||||
lf_printf(file, "(model_data *model_ptr,\n");
|
||||
lf_printf(file, " model_print *info_ptr);\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
if (!model_mon_info_free_p)
|
||||
{
|
||||
lf_print_function_type (file, "void", "INLINE_MODEL", " ");
|
||||
lf_printf (file, "model_mon_info_free\n");
|
||||
lf_printf (file, "(model_data *model_ptr,\n");
|
||||
lf_printf (file, " model_print *info_ptr);\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
lf_print_function_type(file, "void", "INLINE_MODEL", " ");
|
||||
lf_printf(file, "model_set\n");
|
||||
lf_printf(file, "(const char *name);\n");
|
||||
lf_print_function_type (file, "void", "INLINE_MODEL", " ");
|
||||
lf_printf (file, "model_set\n");
|
||||
lf_printf (file, "(const char *name);\n");
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
typedef struct _model_c_passed_data model_c_passed_data;
|
||||
struct _model_c_passed_data {
|
||||
struct _model_c_passed_data
|
||||
{
|
||||
lf *file;
|
||||
model *model_ptr;
|
||||
};
|
||||
|
||||
static void
|
||||
model_c_insn(insn_table *entry,
|
||||
lf *phony_file,
|
||||
void *data,
|
||||
insn *instruction,
|
||||
int depth)
|
||||
model_c_insn (insn_table *entry,
|
||||
lf *phony_file, void *data, insn * instruction, int depth)
|
||||
{
|
||||
model_c_passed_data *data_ptr = (model_c_passed_data *)data;
|
||||
model_c_passed_data *data_ptr = (model_c_passed_data *) data;
|
||||
lf *file = data_ptr->file;
|
||||
char *current_name = data_ptr->model_ptr->printable_name;
|
||||
table_model_entry *model_ptr = instruction->file_entry->model_first;
|
||||
|
||||
while (model_ptr) {
|
||||
if (model_ptr->fields[insn_model_name] == current_name) {
|
||||
lf_printf(file, " { %-*s }, /* %s */\n",
|
||||
max_model_fields_len,
|
||||
model_ptr->fields[insn_model_fields],
|
||||
instruction->file_entry->fields[insn_name]);
|
||||
return;
|
||||
while (model_ptr)
|
||||
{
|
||||
if (model_ptr->fields[insn_model_name] == current_name)
|
||||
{
|
||||
lf_printf (file, " { %-*s }, /* %s */\n",
|
||||
max_model_fields_len,
|
||||
model_ptr->fields[insn_model_fields],
|
||||
instruction->file_entry->fields[insn_name]);
|
||||
return;
|
||||
}
|
||||
|
||||
model_ptr = model_ptr->next;
|
||||
}
|
||||
|
||||
model_ptr = model_ptr->next;
|
||||
}
|
||||
|
||||
lf_printf(file, " { %-*s }, /* %s */\n",
|
||||
max_model_fields_len,
|
||||
data_ptr->model_ptr->insn_default,
|
||||
instruction->file_entry->fields[insn_name]);
|
||||
lf_printf (file, " { %-*s }, /* %s */\n",
|
||||
max_model_fields_len,
|
||||
data_ptr->model_ptr->insn_default,
|
||||
instruction->file_entry->fields[insn_name]);
|
||||
}
|
||||
|
||||
static void
|
||||
model_c_function(insn_table *table,
|
||||
lf *file,
|
||||
table_entry *function,
|
||||
const char *prefix)
|
||||
model_c_function (insn_table *table,
|
||||
lf *file, table_entry *function, const char *prefix)
|
||||
{
|
||||
if (function->fields[function_type] == NULL
|
||||
|| function->fields[function_type][0] == '\0')
|
||||
{
|
||||
error("Model function return type not specified for %s",
|
||||
function->fields[function_name]);
|
||||
error ("Model function return type not specified for %s",
|
||||
function->fields[function_name]);
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf(file, "\n");
|
||||
lf_print_function_type(file, function->fields[function_type], prefix, "\n");
|
||||
lf_printf(file, "%s(%s)\n",
|
||||
function->fields[function_name],
|
||||
function->fields[function_param]);
|
||||
lf_printf (file, "\n");
|
||||
lf_print_function_type (file, function->fields[function_type], prefix,
|
||||
"\n");
|
||||
lf_printf (file, "%s(%s)\n", function->fields[function_name],
|
||||
function->fields[function_param]);
|
||||
}
|
||||
lf_printf(file, "{\n");
|
||||
lf_printf (file, "{\n");
|
||||
if (function->annex)
|
||||
{
|
||||
lf_indent(file, +2);
|
||||
table_entry_print_cpp_line_nr(file, function->annex_line);
|
||||
lf_print__c_code(file, function->annex);
|
||||
lf_indent(file, -2);
|
||||
lf_indent (file, +2);
|
||||
table_entry_print_cpp_line_nr (file, function->annex_line);
|
||||
lf_print__c_code (file, function->annex);
|
||||
lf_indent (file, -2);
|
||||
}
|
||||
lf_printf(file, "}\n");
|
||||
lf_print__internal_reference(file);
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "}\n");
|
||||
lf_print__internal_reference (file);
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
gen_model_c(insn_table *table, lf *file)
|
||||
void
|
||||
gen_model_c (insn_table *table, lf *file)
|
||||
{
|
||||
insn *insn_ptr;
|
||||
model *model_ptr;
|
||||
|
@ -248,155 +257,179 @@ gen_model_c(insn_table *table, lf *file)
|
|||
int model_mon_info_p = 0;
|
||||
int model_mon_info_free_p = 0;
|
||||
|
||||
lf_printf(file, "\n");
|
||||
lf_printf(file, "#include \"cpu.h\"\n");
|
||||
lf_printf(file, "#include \"mon.h\"\n");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf(file, "#ifdef HAVE_STDLIB_H\n");
|
||||
lf_printf(file, "#include <stdlib.h>\n");
|
||||
lf_printf(file, "#endif\n");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "#include \"cpu.h\"\n");
|
||||
lf_printf (file, "#include \"mon.h\"\n");
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "#ifdef HAVE_STDLIB_H\n");
|
||||
lf_printf (file, "#include <stdlib.h>\n");
|
||||
lf_printf (file, "#endif\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
for(insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||
model_c_or_h_data(table, file, insn_ptr->file_entry);
|
||||
}
|
||||
|
||||
for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||
model_c_or_h_function(table, file, insn_ptr->file_entry, "/*h*/STATIC");
|
||||
}
|
||||
|
||||
for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||
model_c_or_h_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
|
||||
}
|
||||
|
||||
for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||
model_c_function(table, file, insn_ptr->file_entry, "/*c*/STATIC");
|
||||
}
|
||||
|
||||
for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||
model_c_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
|
||||
}
|
||||
|
||||
for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||
model_c_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
|
||||
name = insn_ptr->file_entry->fields[function_name];
|
||||
if (strcmp (name, "model_create") == 0)
|
||||
model_create_p = 1;
|
||||
else if (strcmp (name, "model_init") == 0)
|
||||
model_init_p = 1;
|
||||
else if (strcmp (name, "model_halt") == 0)
|
||||
model_halt_p = 1;
|
||||
else if (strcmp (name, "model_mon_info") == 0)
|
||||
model_mon_info_p = 1;
|
||||
else if (strcmp (name, "model_mon_info_free") == 0)
|
||||
model_mon_info_free_p = 1;
|
||||
}
|
||||
|
||||
if (!model_create_p) {
|
||||
lf_print_function_type(file, "model_data *", "INLINE_MODEL", "\n");
|
||||
lf_printf(file, "model_create(sim_cpu *cpu)\n");
|
||||
lf_printf(file, "{\n");
|
||||
lf_printf(file, " return (model_data *)0;\n");
|
||||
lf_printf(file, "}\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
|
||||
if (!model_init_p) {
|
||||
lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
|
||||
lf_printf(file, "model_init(model_data *model_ptr)\n");
|
||||
lf_printf(file, "{\n");
|
||||
lf_printf(file, "}\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
|
||||
if (!model_halt_p) {
|
||||
lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
|
||||
lf_printf(file, "model_halt(model_data *model_ptr)\n");
|
||||
lf_printf(file, "{\n");
|
||||
lf_printf(file, "}\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
|
||||
if (!model_mon_info_p) {
|
||||
lf_print_function_type(file, "model_print *", "INLINE_MODEL", "\n");
|
||||
lf_printf(file, "model_mon_info(model_data *model_ptr)\n");
|
||||
lf_printf(file, "{\n");
|
||||
lf_printf(file, " return (model_print *)0;\n");
|
||||
lf_printf(file, "}\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
|
||||
if (!model_mon_info_free_p) {
|
||||
lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
|
||||
lf_printf(file, "model_mon_info_free(model_data *model_ptr,\n");
|
||||
lf_printf(file, " model_print *info_ptr)\n");
|
||||
lf_printf(file, "{\n");
|
||||
lf_printf(file, "}\n");
|
||||
lf_printf(file, "\n");
|
||||
}
|
||||
|
||||
lf_printf(file, "/* Insn functional unit info */\n");
|
||||
for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
|
||||
model_c_passed_data data;
|
||||
|
||||
lf_printf(file, "static const model_time model_time_%s[] = {\n", model_ptr->name);
|
||||
data.file = file;
|
||||
data.model_ptr = model_ptr;
|
||||
insn_table_traverse_insn(table,
|
||||
NULL, (void *)&data,
|
||||
model_c_insn);
|
||||
|
||||
lf_printf(file, "};\n");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf(file, "\f\n");
|
||||
}
|
||||
|
||||
lf_printf(file, "#ifndef _INLINE_C_\n");
|
||||
lf_printf(file, "const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
|
||||
lf_printf(file, " (const model_time *const)0,\n");
|
||||
for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
|
||||
lf_printf(file, " model_time_%s,\n", model_ptr->name);
|
||||
}
|
||||
lf_printf(file, "};\n");
|
||||
lf_printf(file, "#endif\n");
|
||||
lf_printf(file, "\n");
|
||||
|
||||
lf_printf(file, "\f\n");
|
||||
lf_printf(file, "/* map model enumeration into printable string */\n");
|
||||
lf_printf(file, "#ifndef _INLINE_C_\n");
|
||||
lf_printf(file, "const char *model_name[ (int)nr_models ] = {\n");
|
||||
lf_printf(file, " \"NONE\",\n");
|
||||
for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
|
||||
lf_printf(file, " \"%s\",\n", model_ptr->printable_name);
|
||||
}
|
||||
lf_printf(file, "};\n");
|
||||
lf_printf(file, "#endif\n");
|
||||
lf_printf(file, "\n");
|
||||
|
||||
lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
|
||||
lf_printf(file, "model_set(const char *name)\n");
|
||||
lf_printf(file, "{\n");
|
||||
if (models) {
|
||||
lf_printf(file, " model_enum model;\n");
|
||||
lf_printf(file, " for(model = MODEL_%s; model < nr_models; model++) {\n", models->name);
|
||||
lf_printf(file, " if(strcmp(name, model_name[model]) == 0) {\n");
|
||||
lf_printf(file, " current_model = model;\n");
|
||||
lf_printf(file, " return;\n");
|
||||
lf_printf(file, " }\n");
|
||||
lf_printf(file, " }\n");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf(file, " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
|
||||
lf_printf(file, " name,\n");
|
||||
lf_printf(file, " \"");
|
||||
for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
|
||||
lf_printf(file, "\\n\\t%s", model_ptr->printable_name);
|
||||
for (insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next)
|
||||
{
|
||||
model_c_or_h_data (table, file, insn_ptr->file_entry);
|
||||
}
|
||||
lf_printf(file, "\");\n");
|
||||
} else {
|
||||
lf_printf(file, " error(\"No models are currently known about\");\n");
|
||||
}
|
||||
|
||||
lf_printf(file, "}\n");
|
||||
for (insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next)
|
||||
{
|
||||
model_c_or_h_function (table, file, insn_ptr->file_entry,
|
||||
"/*h*/STATIC");
|
||||
}
|
||||
|
||||
for (insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next)
|
||||
{
|
||||
model_c_or_h_function (table, file, insn_ptr->file_entry,
|
||||
"STATIC_INLINE_MODEL");
|
||||
}
|
||||
|
||||
for (insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next)
|
||||
{
|
||||
model_c_function (table, file, insn_ptr->file_entry, "/*c*/STATIC");
|
||||
}
|
||||
|
||||
for (insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next)
|
||||
{
|
||||
model_c_function (table, file, insn_ptr->file_entry,
|
||||
"STATIC_INLINE_MODEL");
|
||||
}
|
||||
|
||||
for (insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next)
|
||||
{
|
||||
model_c_function (table, file, insn_ptr->file_entry, "INLINE_MODEL");
|
||||
name = insn_ptr->file_entry->fields[function_name];
|
||||
if (strcmp (name, "model_create") == 0)
|
||||
model_create_p = 1;
|
||||
else if (strcmp (name, "model_init") == 0)
|
||||
model_init_p = 1;
|
||||
else if (strcmp (name, "model_halt") == 0)
|
||||
model_halt_p = 1;
|
||||
else if (strcmp (name, "model_mon_info") == 0)
|
||||
model_mon_info_p = 1;
|
||||
else if (strcmp (name, "model_mon_info_free") == 0)
|
||||
model_mon_info_free_p = 1;
|
||||
}
|
||||
|
||||
if (!model_create_p)
|
||||
{
|
||||
lf_print_function_type (file, "model_data *", "INLINE_MODEL", "\n");
|
||||
lf_printf (file, "model_create(sim_cpu *cpu)\n");
|
||||
lf_printf (file, "{\n");
|
||||
lf_printf (file, " return (model_data *)0;\n");
|
||||
lf_printf (file, "}\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
if (!model_init_p)
|
||||
{
|
||||
lf_print_function_type (file, "void", "INLINE_MODEL", "\n");
|
||||
lf_printf (file, "model_init(model_data *model_ptr)\n");
|
||||
lf_printf (file, "{\n");
|
||||
lf_printf (file, "}\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
if (!model_halt_p)
|
||||
{
|
||||
lf_print_function_type (file, "void", "INLINE_MODEL", "\n");
|
||||
lf_printf (file, "model_halt(model_data *model_ptr)\n");
|
||||
lf_printf (file, "{\n");
|
||||
lf_printf (file, "}\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
if (!model_mon_info_p)
|
||||
{
|
||||
lf_print_function_type (file, "model_print *", "INLINE_MODEL", "\n");
|
||||
lf_printf (file, "model_mon_info(model_data *model_ptr)\n");
|
||||
lf_printf (file, "{\n");
|
||||
lf_printf (file, " return (model_print *)0;\n");
|
||||
lf_printf (file, "}\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
if (!model_mon_info_free_p)
|
||||
{
|
||||
lf_print_function_type (file, "void", "INLINE_MODEL", "\n");
|
||||
lf_printf (file, "model_mon_info_free(model_data *model_ptr,\n");
|
||||
lf_printf (file, " model_print *info_ptr)\n");
|
||||
lf_printf (file, "{\n");
|
||||
lf_printf (file, "}\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
lf_printf (file, "/* Insn functional unit info */\n");
|
||||
for (model_ptr = models; model_ptr; model_ptr = model_ptr->next)
|
||||
{
|
||||
model_c_passed_data data;
|
||||
|
||||
lf_printf (file, "static const model_time model_time_%s[] = {\n",
|
||||
model_ptr->name);
|
||||
data.file = file;
|
||||
data.model_ptr = model_ptr;
|
||||
insn_table_traverse_insn (table, NULL, (void *) &data, model_c_insn);
|
||||
|
||||
lf_printf (file, "};\n");
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "\f\n");
|
||||
}
|
||||
|
||||
lf_printf (file, "#ifndef _INLINE_C_\n");
|
||||
lf_printf (file,
|
||||
"const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
|
||||
lf_printf (file, " (const model_time *const)0,\n");
|
||||
for (model_ptr = models; model_ptr; model_ptr = model_ptr->next)
|
||||
{
|
||||
lf_printf (file, " model_time_%s,\n", model_ptr->name);
|
||||
}
|
||||
lf_printf (file, "};\n");
|
||||
lf_printf (file, "#endif\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
lf_printf (file, "\f\n");
|
||||
lf_printf (file, "/* map model enumeration into printable string */\n");
|
||||
lf_printf (file, "#ifndef _INLINE_C_\n");
|
||||
lf_printf (file, "const char *model_name[ (int)nr_models ] = {\n");
|
||||
lf_printf (file, " \"NONE\",\n");
|
||||
for (model_ptr = models; model_ptr; model_ptr = model_ptr->next)
|
||||
{
|
||||
lf_printf (file, " \"%s\",\n", model_ptr->printable_name);
|
||||
}
|
||||
lf_printf (file, "};\n");
|
||||
lf_printf (file, "#endif\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
lf_print_function_type (file, "void", "INLINE_MODEL", "\n");
|
||||
lf_printf (file, "model_set(const char *name)\n");
|
||||
lf_printf (file, "{\n");
|
||||
if (models)
|
||||
{
|
||||
lf_printf (file, " model_enum model;\n");
|
||||
lf_printf (file,
|
||||
" for(model = MODEL_%s; model < nr_models; model++) {\n",
|
||||
models->name);
|
||||
lf_printf (file, " if(strcmp(name, model_name[model]) == 0) {\n");
|
||||
lf_printf (file, " current_model = model;\n");
|
||||
lf_printf (file, " return;\n");
|
||||
lf_printf (file, " }\n");
|
||||
lf_printf (file, " }\n");
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file,
|
||||
" error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
|
||||
lf_printf (file, " name,\n");
|
||||
lf_printf (file, " \"");
|
||||
for (model_ptr = models; model_ptr; model_ptr = model_ptr->next)
|
||||
{
|
||||
lf_printf (file, "\\n\\t%s", model_ptr->printable_name);
|
||||
}
|
||||
lf_printf (file, "\");\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf (file, " error(\"No models are currently known about\");\n");
|
||||
}
|
||||
|
||||
lf_printf (file, "}\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -404,16 +437,14 @@ gen_model_c(insn_table *table, lf *file)
|
|||
|
||||
|
||||
void
|
||||
gen_model_h (lf *file,
|
||||
insn_table *table)
|
||||
gen_model_h (lf *file, insn_table *table)
|
||||
{
|
||||
lf_print__this_file_is_empty (file, "suffering bit rot");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gen_model_c (lf *file,
|
||||
insn_table *table)
|
||||
gen_model_c (lf *file, insn_table *table)
|
||||
{
|
||||
lf_print__this_file_is_empty (file, "suffering bit rot");
|
||||
}
|
||||
|
|
|
@ -23,10 +23,6 @@
|
|||
|
||||
|
||||
|
||||
extern void gen_model_h
|
||||
(lf *file,
|
||||
insn_table *isa);
|
||||
extern void gen_model_h (lf *file, insn_table *isa);
|
||||
|
||||
extern void gen_model_c
|
||||
(lf *file,
|
||||
insn_table *isa);
|
||||
extern void gen_model_c (lf *file, insn_table *isa);
|
||||
|
|
|
@ -48,7 +48,7 @@ print_semantic_function_header (lf *file,
|
|||
int nr_prefetched_words)
|
||||
{
|
||||
int indent;
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "\n");
|
||||
lf_print__function_type_function (file, print_semantic_function_type,
|
||||
"EXTERN_SEMANTICS",
|
||||
(is_function_definition ? "\n" : " "));
|
||||
|
@ -85,52 +85,58 @@ print_semantic_function_header (lf *file,
|
|||
|
||||
void
|
||||
print_semantic_declaration (lf *file,
|
||||
insn_entry *insn,
|
||||
insn_entry * insn,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
int nr_prefetched_words)
|
||||
insn_opcodes *opcodes, int nr_prefetched_words)
|
||||
{
|
||||
print_semantic_function_header (file,
|
||||
insn->name,
|
||||
insn->format_name,
|
||||
expanded_bits,
|
||||
0/* is not function definition*/,
|
||||
0 /* is not function definition */ ,
|
||||
nr_prefetched_words);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* generate the semantics.c file */
|
||||
|
||||
|
||||
void
|
||||
print_idecode_invalid (lf *file,
|
||||
const char *result,
|
||||
invalid_type type)
|
||||
print_idecode_invalid (lf *file, const char *result, invalid_type type)
|
||||
{
|
||||
const char *name;
|
||||
switch (type)
|
||||
{
|
||||
default: name = "unknown"; break;
|
||||
case invalid_illegal: name = "illegal"; break;
|
||||
case invalid_fp_unavailable: name = "fp_unavailable"; break;
|
||||
case invalid_wrong_slot: name = "wrong_slot"; break;
|
||||
default:
|
||||
name = "unknown";
|
||||
break;
|
||||
case invalid_illegal:
|
||||
name = "illegal";
|
||||
break;
|
||||
case invalid_fp_unavailable:
|
||||
name = "fp_unavailable";
|
||||
break;
|
||||
case invalid_wrong_slot:
|
||||
name = "wrong_slot";
|
||||
break;
|
||||
}
|
||||
if (options.gen.code == generate_jumps)
|
||||
{
|
||||
lf_printf (file, "goto %s_%s;\n",
|
||||
(options.gen.icache ? "icache" : "semantic"),
|
||||
name);
|
||||
(options.gen.icache ? "icache" : "semantic"), name);
|
||||
}
|
||||
else if (options.gen.icache)
|
||||
{
|
||||
lf_printf (file, "%s %sicache_%s (", result, options.module.global.prefix.l, name);
|
||||
lf_printf (file, "%s %sicache_%s (", result,
|
||||
options.module.global.prefix.l, name);
|
||||
print_icache_function_actual (file, 0);
|
||||
lf_printf (file, ");\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf (file, "%s %ssemantic_%s (", result, options.module.global.prefix.l, name);
|
||||
lf_printf (file, "%s %ssemantic_%s (", result,
|
||||
options.module.global.prefix.l, name);
|
||||
print_semantic_function_actual (file, 0);
|
||||
lf_printf (file, ");\n");
|
||||
}
|
||||
|
@ -139,18 +145,17 @@ print_idecode_invalid (lf *file,
|
|||
|
||||
void
|
||||
print_semantic_body (lf *file,
|
||||
insn_entry *instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes)
|
||||
insn_entry * instruction,
|
||||
opcode_bits *expanded_bits, insn_opcodes *opcodes)
|
||||
{
|
||||
/* validate the instruction, if a cache this has already been done */
|
||||
if (!options.gen.icache)
|
||||
{
|
||||
print_idecode_validate (file, instruction, opcodes);
|
||||
}
|
||||
|
||||
print_itrace (file, instruction, 0/*put_value_in_cache*/);
|
||||
|
||||
|
||||
print_itrace (file, instruction, 0 /*put_value_in_cache */ );
|
||||
|
||||
/* generate the instruction profile call - this is delayed until
|
||||
after the instruction has been verified. The count macro
|
||||
generated is prefixed by ITABLE_PREFIX */
|
||||
|
@ -177,22 +182,20 @@ print_semantic_body (lf *file,
|
|||
print_function_name (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
NULL,
|
||||
NULL,
|
||||
function_name_prefix_itable);
|
||||
NULL, NULL, function_name_prefix_itable);
|
||||
lf_printf (file, ", cpu, cia);\n");
|
||||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#endif\n");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
|
||||
/* determine the new instruction address */
|
||||
{
|
||||
lf_printf(file, "/* keep the next instruction address handy */\n");
|
||||
lf_printf (file, "/* keep the next instruction address handy */\n");
|
||||
if (options.gen.nia == nia_is_invalid)
|
||||
{
|
||||
lf_printf(file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n",
|
||||
options.module.global.prefix.u);
|
||||
lf_printf (file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n",
|
||||
options.module.global.prefix.u);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -218,7 +221,7 @@ print_semantic_body (lf *file,
|
|||
lf_printf (file, "nia = cia + %d * (%d + 1); %s\n",
|
||||
options.insn_bit_size / 8, nr_immeds,
|
||||
"/* skip immeds as well */");
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -228,7 +231,7 @@ print_semantic_body (lf *file,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* if conditional, generate code to verify that the instruction
|
||||
should be issued */
|
||||
if (filter_is_member (instruction->options, "c")
|
||||
|
@ -241,7 +244,7 @@ print_semantic_body (lf *file,
|
|||
lf_indent (file, +4);
|
||||
/* FIXME - need to log a conditional failure */
|
||||
}
|
||||
|
||||
|
||||
/* Architecture expects a REG to be zero. Instead of having to
|
||||
check every read to see if it is refering to that REG just zap it
|
||||
at the start of every instruction */
|
||||
|
@ -251,7 +254,7 @@ print_semantic_body (lf *file,
|
|||
lf_printf (file, "/* Architecture expects REG to be zero */\n");
|
||||
lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr);
|
||||
}
|
||||
|
||||
|
||||
/* generate the code (or at least something */
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "/* semantics: */\n");
|
||||
|
@ -287,32 +290,30 @@ print_semantic_body (lf *file,
|
|||
lf_indent (file, -indent);
|
||||
lf_print__internal_ref (file);
|
||||
}
|
||||
|
||||
|
||||
/* Close off the conditional execution */
|
||||
if (filter_is_member (instruction->options, "c")
|
||||
|| options.gen.conditional_issue)
|
||||
{
|
||||
lf_indent (file, -4);
|
||||
lf_printf (file, " }\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_c_semantic (lf *file,
|
||||
insn_entry *instruction,
|
||||
insn_entry * instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
cache_entry *cache_rules,
|
||||
int nr_prefetched_words)
|
||||
cache_entry *cache_rules, int nr_prefetched_words)
|
||||
{
|
||||
|
||||
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
|
||||
|
||||
print_my_defines (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
expanded_bits);
|
||||
instruction->format_name, expanded_bits);
|
||||
lf_printf (file, "\n");
|
||||
print_icache_body (file,
|
||||
instruction,
|
||||
|
@ -323,16 +324,13 @@ print_c_semantic (lf *file,
|
|||
: declare_variables),
|
||||
(options.gen.icache
|
||||
? get_values_from_icache
|
||||
: do_not_use_icache),
|
||||
nr_prefetched_words);
|
||||
|
||||
lf_printf (file, "%sinstruction_address nia;\n", options.module.global.prefix.l);
|
||||
print_semantic_body (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
opcodes);
|
||||
: do_not_use_icache), nr_prefetched_words);
|
||||
|
||||
lf_printf (file, "%sinstruction_address nia;\n",
|
||||
options.module.global.prefix.l);
|
||||
print_semantic_body (file, instruction, expanded_bits, opcodes);
|
||||
lf_printf (file, "return nia;\n");
|
||||
|
||||
|
||||
/* generate something to clean up any #defines created for the cache */
|
||||
if (options.gen.direct_access)
|
||||
{
|
||||
|
@ -343,51 +341,41 @@ print_c_semantic (lf *file,
|
|||
undef_variables,
|
||||
(options.gen.icache
|
||||
? get_values_from_icache
|
||||
: do_not_use_icache),
|
||||
nr_prefetched_words);
|
||||
: do_not_use_icache), nr_prefetched_words);
|
||||
}
|
||||
|
||||
|
||||
lf_indent (file, -2);
|
||||
lf_printf (file, "}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_c_semantic_function (lf *file,
|
||||
insn_entry *instruction,
|
||||
insn_entry * instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
cache_entry *cache_rules,
|
||||
int nr_prefetched_words)
|
||||
cache_entry *cache_rules, int nr_prefetched_words)
|
||||
{
|
||||
/* build the semantic routine to execute the instruction */
|
||||
print_semantic_function_header (file,
|
||||
instruction->name,
|
||||
instruction->format_name,
|
||||
expanded_bits,
|
||||
1/*is-function-definition*/,
|
||||
1 /*is-function-definition */ ,
|
||||
nr_prefetched_words);
|
||||
print_c_semantic (file,
|
||||
instruction,
|
||||
expanded_bits,
|
||||
opcodes,
|
||||
cache_rules,
|
||||
nr_prefetched_words);
|
||||
expanded_bits, opcodes, cache_rules, nr_prefetched_words);
|
||||
}
|
||||
|
||||
void
|
||||
print_semantic_definition (lf *file,
|
||||
insn_entry *insn,
|
||||
insn_entry * insn,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes,
|
||||
cache_entry *cache_rules,
|
||||
int nr_prefetched_words)
|
||||
cache_entry *cache_rules, int nr_prefetched_words)
|
||||
{
|
||||
print_c_semantic_function (file,
|
||||
insn,
|
||||
expanded_bits,
|
||||
opcodes,
|
||||
cache_rules,
|
||||
nr_prefetched_words);
|
||||
opcodes, cache_rules, nr_prefetched_words);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -73,35 +73,29 @@
|
|||
|
||||
|
||||
extern void print_semantic_declaration
|
||||
(lf *file,
|
||||
insn_entry *insn,
|
||||
opcode_bits *bits,
|
||||
insn_opcodes *opcodes,
|
||||
int nr_prefetched_words);
|
||||
(lf *file,
|
||||
insn_entry * insn,
|
||||
opcode_bits *bits, insn_opcodes *opcodes, int nr_prefetched_words);
|
||||
|
||||
extern void print_semantic_definition
|
||||
(lf *file,
|
||||
insn_entry *insn,
|
||||
opcode_bits *bits,
|
||||
insn_opcodes *opcodes,
|
||||
cache_entry *cache_rules,
|
||||
int nr_prefetched_words);
|
||||
(lf *file,
|
||||
insn_entry * insn,
|
||||
opcode_bits *bits,
|
||||
insn_opcodes *opcodes, cache_entry *cache_rules, int nr_prefetched_words);
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
invalid_illegal,
|
||||
invalid_fp_unavailable,
|
||||
invalid_wrong_slot,
|
||||
} invalid_type;
|
||||
}
|
||||
invalid_type;
|
||||
|
||||
extern void print_idecode_invalid
|
||||
(lf *file,
|
||||
const char *result,
|
||||
invalid_type type);
|
||||
(lf *file, const char *result, invalid_type type);
|
||||
|
||||
extern void print_semantic_body
|
||||
(lf *file,
|
||||
insn_entry *instruction,
|
||||
opcode_bits *expanded_bits,
|
||||
insn_opcodes *opcodes);
|
||||
|
||||
(lf *file,
|
||||
insn_entry * instruction,
|
||||
opcode_bits *expanded_bits, insn_opcodes *opcodes);
|
||||
|
|
|
@ -39,19 +39,16 @@
|
|||
|
||||
static void
|
||||
print_support_function_name (lf *file,
|
||||
function_entry *function,
|
||||
function_entry * function,
|
||||
int is_function_definition)
|
||||
{
|
||||
if (function->is_internal)
|
||||
{
|
||||
lf_print__function_type_function (file, print_semantic_function_type,
|
||||
"INLINE_SUPPORT",
|
||||
(is_function_definition ? "\n" : " "));
|
||||
print_function_name (file,
|
||||
function->name,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(is_function_definition ? "\n" :
|
||||
" "));
|
||||
print_function_name (file, function->name, NULL, NULL, NULL,
|
||||
function_name_prefix_semantics);
|
||||
lf_printf (file, "\n(");
|
||||
lf_indent (file, +1);
|
||||
|
@ -71,16 +68,14 @@ print_support_function_name (lf *file,
|
|||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#define %s %s%s\n",
|
||||
function->name,
|
||||
options.module.support.prefix.l,
|
||||
function->name);
|
||||
options.module.support.prefix.l, function->name);
|
||||
}
|
||||
lf_print__function_type (file,
|
||||
function->type,
|
||||
"INLINE_SUPPORT",
|
||||
(is_function_definition ? "\n" : " "));
|
||||
lf_printf (file, "%s%s\n(",
|
||||
options.module.support.prefix.l,
|
||||
function->name);
|
||||
options.module.support.prefix.l, function->name);
|
||||
if (options.gen.smp)
|
||||
lf_printf (file,
|
||||
"sim_cpu *cpu, %sinstruction_address cia, int MY_INDEX",
|
||||
|
@ -89,8 +84,7 @@ print_support_function_name (lf *file,
|
|||
lf_printf (file,
|
||||
"SIM_DESC sd, %sinstruction_address cia, int MY_INDEX",
|
||||
options.module.support.prefix.l);
|
||||
if (function->param != NULL
|
||||
&& strlen (function->param) > 0)
|
||||
if (function->param != NULL && strlen (function->param) > 0)
|
||||
lf_printf (file, ", %s", function->param);
|
||||
lf_printf (file, ")%s", (is_function_definition ? "\n" : ";\n"));
|
||||
}
|
||||
|
@ -98,58 +92,54 @@ print_support_function_name (lf *file,
|
|||
|
||||
|
||||
static void
|
||||
support_h_function (lf *file,
|
||||
function_entry *function,
|
||||
void *data)
|
||||
support_h_function (lf *file, function_entry * function, void *data)
|
||||
{
|
||||
ASSERT (function->type != NULL);
|
||||
print_support_function_name (file,
|
||||
function,
|
||||
0/*!is_definition*/);
|
||||
lf_printf(file, "\n");
|
||||
print_support_function_name (file, function, 0 /*!is_definition */ );
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
gen_support_h (lf *file,
|
||||
insn_table *table)
|
||||
gen_support_h (lf *file, insn_table *table)
|
||||
{
|
||||
/* output the definition of `SD_'*/
|
||||
if (options.gen.smp)
|
||||
/* output the definition of `SD_' */
|
||||
if (options.gen.smp)
|
||||
{
|
||||
lf_printf(file, "#define SD CPU_STATE (cpu)\n");
|
||||
lf_printf(file, "#define CPU cpu\n");
|
||||
lf_printf(file, "#define CPU_ cpu\n");
|
||||
lf_printf (file, "#define SD CPU_STATE (cpu)\n");
|
||||
lf_printf (file, "#define CPU cpu\n");
|
||||
lf_printf (file, "#define CPU_ cpu\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf(file, "#define SD sd\n");
|
||||
lf_printf(file, "#define CPU (STATE_CPU (sd, 0))\n");
|
||||
lf_printf(file, "#define CPU_ sd\n");
|
||||
lf_printf (file, "#define SD sd\n");
|
||||
lf_printf (file, "#define CPU (STATE_CPU (sd, 0))\n");
|
||||
lf_printf (file, "#define CPU_ sd\n");
|
||||
}
|
||||
|
||||
lf_printf(file, "#define CIA_ cia\n");
|
||||
lf_printf (file, "#define CIA_ cia\n");
|
||||
if (options.gen.delayed_branch)
|
||||
{
|
||||
lf_printf(file, "#define CIA cia.ip\n");
|
||||
lf_printf(file, "/* #define NIA nia.dp -- do not define, ambigious */\n");
|
||||
lf_printf (file, "#define CIA cia.ip\n");
|
||||
lf_printf (file,
|
||||
"/* #define NIA nia.dp -- do not define, ambigious */\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
lf_printf(file, "#define CIA cia\n");
|
||||
lf_printf(file, "#define NIA nia\n");
|
||||
lf_printf (file, "#define CIA cia\n");
|
||||
lf_printf (file, "#define NIA nia\n");
|
||||
}
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
lf_printf(file, "#define SD_ CPU_, CIA_, MY_INDEX\n");
|
||||
lf_printf(file, "#define _SD SD_ /* deprecated */\n");
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "#define SD_ CPU_, CIA_, MY_INDEX\n");
|
||||
lf_printf (file, "#define _SD SD_ /* deprecated */\n");
|
||||
lf_printf (file, "\n");
|
||||
|
||||
/* Map <PREFIX>_xxxx onto the shorter xxxx for the following names:
|
||||
|
||||
instruction_word
|
||||
idecode_issue
|
||||
semantic_illegal
|
||||
instruction_word
|
||||
idecode_issue
|
||||
semantic_illegal
|
||||
|
||||
Map defined here as name space problems are created when the name is
|
||||
defined in idecode.h */
|
||||
|
@ -158,55 +148,47 @@ gen_support_h (lf *file,
|
|||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#define %s %s%s\n",
|
||||
"instruction_word",
|
||||
options.module.idecode.prefix.l,
|
||||
"instruction_word");
|
||||
options.module.idecode.prefix.l, "instruction_word");
|
||||
lf_printf (file, "\n");
|
||||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#define %s %s%s\n",
|
||||
"idecode_issue",
|
||||
options.module.idecode.prefix.l,
|
||||
"idecode_issue");
|
||||
options.module.idecode.prefix.l, "idecode_issue");
|
||||
lf_printf (file, "\n");
|
||||
lf_indent_suppress (file);
|
||||
lf_printf (file, "#define %s %s%s\n",
|
||||
"semantic_illegal",
|
||||
options.module.idecode.prefix.l,
|
||||
"semantic_illegal");
|
||||
options.module.idecode.prefix.l, "semantic_illegal");
|
||||
lf_printf (file, "\n");
|
||||
}
|
||||
|
||||
/* output a declaration for all functions */
|
||||
function_entry_traverse (file, table->functions,
|
||||
support_h_function,
|
||||
NULL);
|
||||
lf_printf(file, "\n");
|
||||
lf_printf(file, "#if defined(SUPPORT_INLINE)\n");
|
||||
lf_printf(file, "# if ((SUPPORT_INLINE & INCLUDE_MODULE)\\\n");
|
||||
lf_printf(file, " && (SUPPORT_INLINE & INCLUDED_BY_MODULE))\n");
|
||||
lf_printf(file, "# include \"%ssupport.c\"\n", options.module.support.prefix.l);
|
||||
lf_printf(file, "# endif\n");
|
||||
lf_printf(file, "#endif\n");
|
||||
function_entry_traverse (file, table->functions, support_h_function, NULL);
|
||||
lf_printf (file, "\n");
|
||||
lf_printf (file, "#if defined(SUPPORT_INLINE)\n");
|
||||
lf_printf (file, "# if ((SUPPORT_INLINE & INCLUDE_MODULE)\\\n");
|
||||
lf_printf (file, " && (SUPPORT_INLINE & INCLUDED_BY_MODULE))\n");
|
||||
lf_printf (file, "# include \"%ssupport.c\"\n",
|
||||
options.module.support.prefix.l);
|
||||
lf_printf (file, "# endif\n");
|
||||
lf_printf (file, "#endif\n");
|
||||
}
|
||||
|
||||
static void
|
||||
support_c_function (lf *file,
|
||||
function_entry *function,
|
||||
void *data)
|
||||
support_c_function (lf *file, function_entry * function, void *data)
|
||||
{
|
||||
ASSERT (function->type != NULL);
|
||||
print_support_function_name (file,
|
||||
function,
|
||||
1/*!is_definition*/);
|
||||
print_support_function_name (file, function, 1 /*!is_definition */ );
|
||||
lf_printf (file, "{\n");
|
||||
lf_indent (file, +2);
|
||||
if (function->code == NULL)
|
||||
error (function->line,
|
||||
"Function without body (or null statement)");
|
||||
error (function->line, "Function without body (or null statement)");
|
||||
lf_print__line_ref (file, function->code->line);
|
||||
table_print_code (file, function->code);
|
||||
if (function->is_internal)
|
||||
{
|
||||
lf_printf (file, "sim_engine_abort (SD, CPU, cia, \"Internal function must longjump\\n\");\n");
|
||||
lf_printf (file,
|
||||
"sim_engine_abort (SD, CPU, cia, \"Internal function must longjump\\n\");\n");
|
||||
lf_printf (file, "return cia;\n");
|
||||
}
|
||||
lf_indent (file, -2);
|
||||
|
@ -217,17 +199,17 @@ support_c_function (lf *file,
|
|||
|
||||
|
||||
void
|
||||
gen_support_c (lf *file,
|
||||
insn_table *table)
|
||||
gen_support_c (lf *file, insn_table *table)
|
||||
{
|
||||
lf_printf(file, "#include \"sim-main.h\"\n");
|
||||
lf_printf(file, "#include \"%sidecode.h\"\n", options.module.idecode.prefix.l);
|
||||
lf_printf(file, "#include \"%sitable.h\"\n", options.module.itable.prefix.l);
|
||||
lf_printf(file, "#include \"%ssupport.h\"\n", options.module.support.prefix.l);
|
||||
lf_printf(file, "\n");
|
||||
lf_printf (file, "#include \"sim-main.h\"\n");
|
||||
lf_printf (file, "#include \"%sidecode.h\"\n",
|
||||
options.module.idecode.prefix.l);
|
||||
lf_printf (file, "#include \"%sitable.h\"\n",
|
||||
options.module.itable.prefix.l);
|
||||
lf_printf (file, "#include \"%ssupport.h\"\n",
|
||||
options.module.support.prefix.l);
|
||||
lf_printf (file, "\n");
|
||||
|
||||
/* output a definition (c-code) for all functions */
|
||||
function_entry_traverse (file, table->functions,
|
||||
support_c_function,
|
||||
NULL);
|
||||
function_entry_traverse (file, table->functions, support_c_function, NULL);
|
||||
}
|
||||
|
|
|
@ -22,11 +22,6 @@
|
|||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
extern void gen_support_h
|
||||
(lf *file,
|
||||
insn_table *table);
|
||||
|
||||
extern void gen_support_c
|
||||
(lf *file,
|
||||
insn_table *table);
|
||||
extern void gen_support_h (lf *file, insn_table *table);
|
||||
|
||||
extern void gen_support_c (lf *file, insn_table *table);
|
||||
|
|
729
sim/igen/gen.c
729
sim/igen/gen.c
File diff suppressed because it is too large
Load Diff
118
sim/igen/gen.h
118
sim/igen/gen.h
|
@ -23,7 +23,8 @@
|
|||
|
||||
|
||||
typedef struct _opcode_field opcode_field;
|
||||
struct _opcode_field {
|
||||
struct _opcode_field
|
||||
{
|
||||
int word_nr;
|
||||
int first;
|
||||
int last;
|
||||
|
@ -34,7 +35,8 @@ struct _opcode_field {
|
|||
};
|
||||
|
||||
typedef struct _opcode_bits opcode_bits;
|
||||
struct _opcode_bits {
|
||||
struct _opcode_bits
|
||||
{
|
||||
int value;
|
||||
int first;
|
||||
int last;
|
||||
|
@ -44,13 +46,15 @@ struct _opcode_bits {
|
|||
};
|
||||
|
||||
typedef struct _insn_opcodes insn_opcodes;
|
||||
struct _insn_opcodes {
|
||||
struct _insn_opcodes
|
||||
{
|
||||
opcode_field *opcode;
|
||||
insn_opcodes *next;
|
||||
};
|
||||
|
||||
typedef struct _insn_list insn_list;
|
||||
struct _insn_list {
|
||||
struct _insn_list
|
||||
{
|
||||
/* the instruction */
|
||||
insn_entry *insn;
|
||||
/* list of non constant bits that have been made constant */
|
||||
|
@ -70,14 +74,15 @@ struct _insn_list {
|
|||
typedef struct _gen_list gen_list;
|
||||
|
||||
typedef struct _gen_entry gen_entry;
|
||||
struct _gen_entry {
|
||||
struct _gen_entry
|
||||
{
|
||||
|
||||
/* as an entry in a table */
|
||||
int word_nr;
|
||||
int opcode_nr;
|
||||
gen_entry *sibling;
|
||||
opcode_bits *expanded_bits;
|
||||
gen_entry *parent; /* parent has the opcode* data */
|
||||
gen_entry *parent; /* parent has the opcode* data */
|
||||
|
||||
/* as a table containing entries */
|
||||
decode_table *opcode_rule;
|
||||
|
@ -99,7 +104,8 @@ struct _gen_entry {
|
|||
};
|
||||
|
||||
|
||||
struct _gen_list {
|
||||
struct _gen_list
|
||||
{
|
||||
model_entry *model;
|
||||
insn_table *isa;
|
||||
gen_entry *table;
|
||||
|
@ -108,7 +114,8 @@ struct _gen_list {
|
|||
|
||||
|
||||
typedef struct _gen_table gen_table;
|
||||
struct _gen_table {
|
||||
struct _gen_table
|
||||
{
|
||||
/* list of all the instructions */
|
||||
insn_table *isa;
|
||||
/* list of all the semantic functions */
|
||||
|
@ -121,38 +128,28 @@ struct _gen_table {
|
|||
};
|
||||
|
||||
|
||||
extern gen_table *make_gen_tables
|
||||
(insn_table *isa,
|
||||
decode_table *rules);
|
||||
extern gen_table *make_gen_tables (insn_table *isa, decode_table *rules);
|
||||
|
||||
|
||||
extern void gen_tables_expand_insns
|
||||
(gen_table *gen);
|
||||
extern void gen_tables_expand_insns (gen_table *gen);
|
||||
|
||||
extern void gen_tables_expand_semantics
|
||||
(gen_table *gen);
|
||||
extern void gen_tables_expand_semantics (gen_table *gen);
|
||||
|
||||
extern int gen_entry_depth
|
||||
(gen_entry *table);
|
||||
extern int gen_entry_depth (gen_entry *table);
|
||||
|
||||
|
||||
|
||||
/* Traverse the created data structure */
|
||||
|
||||
typedef void gen_entry_handler
|
||||
(lf *file,
|
||||
gen_entry *entry,
|
||||
int depth,
|
||||
void *data);
|
||||
(lf *file, gen_entry *entry, int depth, void *data);
|
||||
|
||||
extern void gen_entry_traverse_tree
|
||||
(lf *file,
|
||||
gen_entry *table,
|
||||
int depth,
|
||||
gen_entry_handler *start,
|
||||
gen_entry_handler *leaf,
|
||||
gen_entry_handler *end,
|
||||
void *data);
|
||||
(lf *file,
|
||||
gen_entry *table,
|
||||
int depth,
|
||||
gen_entry_handler * start,
|
||||
gen_entry_handler * leaf, gen_entry_handler * end, void *data);
|
||||
|
||||
|
||||
|
||||
|
@ -161,70 +158,57 @@ extern void gen_entry_traverse_tree
|
|||
|
||||
/* Cache functions: */
|
||||
|
||||
extern int print_icache_function_formal
|
||||
(lf *file, int nr_prefetched_words);
|
||||
extern int print_icache_function_formal (lf *file, int nr_prefetched_words);
|
||||
|
||||
extern int print_icache_function_actual
|
||||
(lf *file, int nr_prefetched_words);
|
||||
extern int print_icache_function_actual (lf *file, int nr_prefetched_words);
|
||||
|
||||
extern int print_icache_function_type
|
||||
(lf *file);
|
||||
extern int print_icache_function_type (lf *file);
|
||||
|
||||
extern int print_semantic_function_formal
|
||||
(lf *file, int nr_prefetched_words);
|
||||
extern int print_semantic_function_formal (lf *file, int nr_prefetched_words);
|
||||
|
||||
extern int print_semantic_function_actual
|
||||
(lf *file, int nr_prefetched_words);
|
||||
extern int print_semantic_function_actual (lf *file, int nr_prefetched_words);
|
||||
|
||||
extern int print_semantic_function_type
|
||||
(lf *file);
|
||||
extern int print_semantic_function_type (lf *file);
|
||||
|
||||
extern int print_idecode_function_formal
|
||||
(lf *file, int nr_prefetched_words);
|
||||
extern int print_idecode_function_formal (lf *file, int nr_prefetched_words);
|
||||
|
||||
extern int print_idecode_function_actual
|
||||
(lf *file, int nr_prefetched_words);
|
||||
extern int print_idecode_function_actual (lf *file, int nr_prefetched_words);
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
function_name_prefix_semantics,
|
||||
function_name_prefix_idecode,
|
||||
function_name_prefix_itable,
|
||||
function_name_prefix_icache,
|
||||
function_name_prefix_engine,
|
||||
function_name_prefix_none
|
||||
} lf_function_name_prefixes;
|
||||
}
|
||||
lf_function_name_prefixes;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
is_function_declaration = 0,
|
||||
is_function_definition = 1,
|
||||
is_function_variable,
|
||||
} function_decl_type;
|
||||
}
|
||||
function_decl_type;
|
||||
|
||||
extern int print_function_name
|
||||
(lf *file,
|
||||
const char *basename,
|
||||
const char *format_name,
|
||||
const char *model_name,
|
||||
opcode_bits *expanded_bits,
|
||||
lf_function_name_prefixes prefix);
|
||||
(lf *file,
|
||||
const char *basename,
|
||||
const char *format_name,
|
||||
const char *model_name,
|
||||
opcode_bits *expanded_bits, lf_function_name_prefixes prefix);
|
||||
|
||||
extern void print_my_defines
|
||||
(lf *file,
|
||||
const char *basename,
|
||||
const char *format_name,
|
||||
opcode_bits *expanded_bits);
|
||||
(lf *file,
|
||||
const char *basename, const char *format_name, opcode_bits *expanded_bits);
|
||||
|
||||
extern void print_itrace
|
||||
(lf *file,
|
||||
insn_entry *insn,
|
||||
int idecode);
|
||||
extern void print_itrace (lf *file, insn_entry * insn, int idecode);
|
||||
|
||||
extern void print_sim_engine_abort
|
||||
(lf *file,
|
||||
const char *message);
|
||||
extern void print_sim_engine_abort (lf *file, const char *message);
|
||||
|
||||
|
||||
extern void print_include (lf *file, igen_module module);
|
||||
extern void print_include_inline (lf *file, igen_module module);
|
||||
extern void print_include_inline (lf *file, igen_module module);
|
||||
extern void print_includes (lf *file);
|
||||
|
||||
|
|
485
sim/igen/igen.c
485
sim/igen/igen.c
File diff suppressed because it is too large
Load Diff
|
@ -24,7 +24,8 @@
|
|||
|
||||
/* code-generation options: */
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
|
||||
/* Transfer control to an instructions semantic code using the the
|
||||
standard call/return mechanism */
|
||||
|
@ -37,18 +38,22 @@ typedef enum {
|
|||
|
||||
generate_jumps,
|
||||
|
||||
} igen_code;
|
||||
}
|
||||
igen_code;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
nia_is_cia_plus_one,
|
||||
nia_is_void,
|
||||
nia_is_invalid,
|
||||
} igen_nia;
|
||||
}
|
||||
igen_nia;
|
||||
|
||||
|
||||
|
||||
typedef struct _igen_gen_options igen_gen_options;
|
||||
struct _igen_gen_options {
|
||||
struct _igen_gen_options
|
||||
{
|
||||
int direct_access;
|
||||
int semantic_icache;
|
||||
int insn_in_icache;
|
||||
|
@ -87,7 +92,8 @@ struct _igen_gen_options {
|
|||
|
||||
|
||||
typedef struct _igen_trace_options igen_trace_options;
|
||||
struct _igen_trace_options {
|
||||
struct _igen_trace_options
|
||||
{
|
||||
int rule_selection;
|
||||
int rule_rejection;
|
||||
int insn_insertion;
|
||||
|
@ -96,16 +102,21 @@ struct _igen_trace_options {
|
|||
int combine;
|
||||
};
|
||||
|
||||
typedef struct _igen_name {
|
||||
typedef struct _igen_name
|
||||
{
|
||||
char *u;
|
||||
char *l;
|
||||
} igen_name;
|
||||
typedef struct _igen_module {
|
||||
}
|
||||
igen_name;
|
||||
typedef struct _igen_module
|
||||
{
|
||||
igen_name prefix;
|
||||
igen_name suffix;
|
||||
} igen_module;
|
||||
}
|
||||
igen_module;
|
||||
|
||||
typedef struct _igen_module_options {
|
||||
typedef struct _igen_module_options
|
||||
{
|
||||
igen_module global;
|
||||
igen_module engine;
|
||||
igen_module icache;
|
||||
|
@ -113,10 +124,12 @@ typedef struct _igen_module_options {
|
|||
igen_module itable;
|
||||
igen_module semantics;
|
||||
igen_module support;
|
||||
} igen_module_options;
|
||||
}
|
||||
igen_module_options;
|
||||
|
||||
typedef struct _igen_decode_options igen_decode_options ;
|
||||
struct _igen_decode_options {
|
||||
typedef struct _igen_decode_options igen_decode_options;
|
||||
struct _igen_decode_options
|
||||
{
|
||||
|
||||
/* Combine tables? Should the generator make a second pass through
|
||||
each generated table looking for any sub-entries that contain the
|
||||
|
@ -143,7 +156,8 @@ struct _igen_decode_options {
|
|||
|
||||
|
||||
typedef struct _igen_warn_options igen_warn_options;
|
||||
struct _igen_warn_options {
|
||||
struct _igen_warn_options
|
||||
{
|
||||
|
||||
/* Issue warning about discarded instructions */
|
||||
int discard;
|
||||
|
@ -159,7 +173,8 @@ struct _igen_warn_options {
|
|||
|
||||
|
||||
typedef struct _igen_options igen_options;
|
||||
struct _igen_options {
|
||||
struct _igen_options
|
||||
{
|
||||
|
||||
/* What does the instruction look like - bit ordering, size, widths or
|
||||
offesets */
|
||||
|
@ -201,7 +216,7 @@ struct _igen_options {
|
|||
|
||||
extern igen_options options;
|
||||
|
||||
/* default options - hopefully backward compatible */ \
|
||||
/* default options - hopefully backward compatible */
|
||||
#define INIT_OPTIONS() \
|
||||
do { \
|
||||
memset (&options, 0, sizeof options); \
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ca_type,
|
||||
ca_field_name,
|
||||
ca_derived_name,
|
||||
|
@ -47,10 +48,10 @@ enum {
|
|||
};
|
||||
|
||||
static const name_map cache_type_map[] = {
|
||||
{ "cache", cache_value },
|
||||
{ "compute", compute_value },
|
||||
{ "scratch", scratch_value },
|
||||
{ NULL, 0 },
|
||||
{"cache", cache_value},
|
||||
{"compute", compute_value},
|
||||
{"scratch", scratch_value},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
|
||||
|
@ -67,8 +68,7 @@ load_cache_table (char *file_name)
|
|||
new_rule->line = entry->line;
|
||||
new_rule->entry_type = name2i (entry->field[ca_type], cache_type_map);
|
||||
new_rule->name = entry->field[ca_derived_name];
|
||||
filter_parse (&new_rule->original_fields,
|
||||
entry->field[ca_field_name]);
|
||||
filter_parse (&new_rule->original_fields, entry->field[ca_field_name]);
|
||||
new_rule->type = entry->field[ca_type_def];
|
||||
/* expression is the concatenation of the remaining fields */
|
||||
if (entry->nr_fields > ca_expression)
|
||||
|
@ -101,7 +101,7 @@ load_cache_table (char *file_name)
|
|||
igen_options options;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
cache_entry *rules = NULL;
|
||||
lf *l;
|
||||
|
|
|
@ -65,5 +65,4 @@
|
|||
new name had better be the same. */
|
||||
|
||||
|
||||
extern cache_entry *load_cache_table
|
||||
(char *file_name);
|
||||
extern cache_entry *load_cache_table (char *file_name);
|
||||
|
|
|
@ -39,45 +39,44 @@
|
|||
|
||||
|
||||
static const name_map decode_type_map[] = {
|
||||
{ "normal", normal_decode_rule },
|
||||
{ "boolean", boolean_rule },
|
||||
{ NULL, normal_decode_rule },
|
||||
{"normal", normal_decode_rule},
|
||||
{"boolean", boolean_rule},
|
||||
{NULL, normal_decode_rule},
|
||||
};
|
||||
|
||||
static const name_map decode_gen_map[] = {
|
||||
{ "array", array_gen },
|
||||
{ "switch", switch_gen },
|
||||
{ "padded-switch", padded_switch_gen },
|
||||
{ "goto-switch", goto_switch_gen },
|
||||
{ NULL, -1 },
|
||||
{"array", array_gen},
|
||||
{"switch", switch_gen},
|
||||
{"padded-switch", padded_switch_gen},
|
||||
{"goto-switch", goto_switch_gen},
|
||||
{NULL, -1},
|
||||
};
|
||||
|
||||
static const name_map decode_reserved_map[] = {
|
||||
{ "zero-reserved", 1 },
|
||||
{ NULL, 0 },
|
||||
{"zero-reserved", 1},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
static const name_map decode_duplicates_map[] = {
|
||||
{ "duplicate", 1 },
|
||||
{ NULL, 0 },
|
||||
{"duplicate", 1},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
static const name_map decode_combine_map[] = {
|
||||
{ "combine", 1 },
|
||||
{ NULL, 0 },
|
||||
{"combine", 1},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
static const name_map decode_search_map[] = {
|
||||
{ "constants", decode_find_constants },
|
||||
{ "mixed", decode_find_mixed },
|
||||
{ "strings", decode_find_strings },
|
||||
{ NULL, decode_find_mixed },
|
||||
{"constants", decode_find_constants},
|
||||
{"mixed", decode_find_mixed},
|
||||
{"strings", decode_find_strings},
|
||||
{NULL, decode_find_mixed},
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
set_bits (int bit[max_insn_bit_size],
|
||||
unsigned64 value)
|
||||
set_bits (int bit[max_insn_bit_size], unsigned64 value)
|
||||
{
|
||||
int bit_nr;
|
||||
for (bit_nr = 0; bit_nr < max_insn_bit_size; bit_nr++)
|
||||
|
@ -90,7 +89,7 @@ set_bits (int bit[max_insn_bit_size],
|
|||
}
|
||||
|
||||
decode_table *
|
||||
load_decode_table(char *file_name)
|
||||
load_decode_table (char *file_name)
|
||||
{
|
||||
table *file = table_open (file_name);
|
||||
table_entry *entry;
|
||||
|
@ -107,20 +106,22 @@ load_decode_table(char *file_name)
|
|||
/* the options field */
|
||||
new_rule->type = name2i (decode_options, decode_type_map);
|
||||
if (options.decode.overriding_gen != NULL)
|
||||
new_rule->gen = name2i (options.decode.overriding_gen, decode_gen_map);
|
||||
new_rule->gen =
|
||||
name2i (options.decode.overriding_gen, decode_gen_map);
|
||||
else
|
||||
new_rule->gen = name2i (decode_options, decode_gen_map);
|
||||
if (new_rule->gen == padded_switch_gen
|
||||
&& options.decode.switch_as_goto)
|
||||
if (new_rule->gen == padded_switch_gen && options.decode.switch_as_goto)
|
||||
new_rule->gen = goto_switch_gen;
|
||||
if (options.decode.zero_reserved)
|
||||
new_rule->with_zero_reserved = 1;
|
||||
else
|
||||
new_rule->with_zero_reserved = name2i (decode_options, decode_reserved_map);
|
||||
new_rule->with_zero_reserved =
|
||||
name2i (decode_options, decode_reserved_map);
|
||||
if (options.decode.duplicate)
|
||||
new_rule->with_duplicates = 1;
|
||||
else
|
||||
new_rule->with_duplicates = name2i (decode_options, decode_duplicates_map);
|
||||
new_rule->with_duplicates =
|
||||
name2i (decode_options, decode_duplicates_map);
|
||||
if (options.decode.combine)
|
||||
new_rule->with_combine = 1;
|
||||
else
|
||||
|
@ -169,7 +170,9 @@ load_decode_table(char *file_name)
|
|||
&& strlen (entry->field[decode_force_first_field]) > 0)
|
||||
{
|
||||
new_rule->force_first = target_a2i (options.hi_bit_nr,
|
||||
entry->field[decode_force_first_field]);
|
||||
entry->
|
||||
field
|
||||
[decode_force_first_field]);
|
||||
if (new_rule->force_first < new_rule->first
|
||||
|| new_rule->force_first > new_rule->last + 1)
|
||||
error (new_rule->line, "Force first out of range\n");
|
||||
|
@ -180,7 +183,8 @@ load_decode_table(char *file_name)
|
|||
&& strlen (entry->field[decode_force_last_field]) > 0)
|
||||
{
|
||||
new_rule->force_last = target_a2i (options.hi_bit_nr,
|
||||
entry->field[decode_force_last_field]);
|
||||
entry->
|
||||
field[decode_force_last_field]);
|
||||
if (new_rule->force_last > new_rule->last
|
||||
|| new_rule->force_last < new_rule->first - 1)
|
||||
error (new_rule->line, "Force-last out of range\n");
|
||||
|
@ -217,7 +221,7 @@ load_decode_table(char *file_name)
|
|||
{
|
||||
(*last) = ZALLOC (decode_path_list);
|
||||
/* extra root/zero entry */
|
||||
(*last)->path = ZALLOC (decode_path);
|
||||
(*last)->path = ZALLOC (decode_path);
|
||||
do
|
||||
{
|
||||
decode_path *entry = ZALLOC (decode_path);
|
||||
|
@ -244,22 +248,32 @@ load_decode_table(char *file_name)
|
|||
decode_cond *cond = ZALLOC (decode_cond);
|
||||
decode_cond **last;
|
||||
if (entry->nr_fields > field_nr + decode_cond_mask_field)
|
||||
set_bits (cond->mask, a2i (entry->field[field_nr + decode_cond_mask_field]));
|
||||
set_bits (cond->mask,
|
||||
a2i (entry->
|
||||
field[field_nr + decode_cond_mask_field]));
|
||||
if (entry->nr_fields > field_nr + decode_cond_value_field)
|
||||
{
|
||||
if (entry->field[field_nr + decode_cond_value_field][0] == '!')
|
||||
{
|
||||
cond->is_equal = 0;
|
||||
set_bits (cond->value, a2i (entry->field[field_nr + decode_cond_value_field] + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
cond->is_equal = 1;
|
||||
set_bits (cond->value, a2i (entry->field[field_nr + decode_cond_value_field]));
|
||||
}
|
||||
}
|
||||
{
|
||||
if (entry->field[field_nr + decode_cond_value_field][0] ==
|
||||
'!')
|
||||
{
|
||||
cond->is_equal = 0;
|
||||
set_bits (cond->value,
|
||||
a2i (entry->
|
||||
field[field_nr + decode_cond_value_field] +
|
||||
1));
|
||||
}
|
||||
else
|
||||
{
|
||||
cond->is_equal = 1;
|
||||
set_bits (cond->value,
|
||||
a2i (entry->
|
||||
field[field_nr +
|
||||
decode_cond_value_field]));
|
||||
}
|
||||
}
|
||||
if (entry->nr_fields > field_nr + decode_cond_word_nr_field)
|
||||
cond->word_nr = a2i (entry->field[field_nr + decode_cond_word_nr_field]);
|
||||
cond->word_nr =
|
||||
a2i (entry->field[field_nr + decode_cond_word_nr_field]);
|
||||
field_nr += nr_decode_cond_fields;
|
||||
/* insert it */
|
||||
last = &new_rule->conditions;
|
||||
|
@ -274,7 +288,7 @@ load_decode_table(char *file_name)
|
|||
return table;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
decode_table_max_word_nr (decode_table *entry)
|
||||
{
|
||||
|
@ -297,10 +311,7 @@ decode_table_max_word_nr (decode_table *entry)
|
|||
|
||||
|
||||
static void
|
||||
dump_decode_cond (lf *file,
|
||||
char *prefix,
|
||||
decode_cond *cond,
|
||||
char *suffix)
|
||||
dump_decode_cond (lf *file, char *prefix, decode_cond *cond, char *suffix)
|
||||
{
|
||||
lf_printf (file, "%s(decode_cond *) 0x%lx", prefix, (long) cond);
|
||||
if (cond != NULL)
|
||||
|
@ -318,10 +329,7 @@ dump_decode_cond (lf *file,
|
|||
|
||||
|
||||
static void
|
||||
dump_decode_conds (lf *file,
|
||||
char *prefix,
|
||||
decode_cond *cond,
|
||||
char *suffix)
|
||||
dump_decode_conds (lf *file, char *prefix, decode_cond *cond, char *suffix)
|
||||
{
|
||||
lf_printf (file, "%s(decode_cond *) 0x%lx", prefix, (long) cond);
|
||||
while (cond != NULL)
|
||||
|
@ -334,23 +342,21 @@ dump_decode_conds (lf *file,
|
|||
|
||||
|
||||
void
|
||||
dump_decode_rule (lf *file,
|
||||
char *prefix,
|
||||
decode_table *rule,
|
||||
char *suffix)
|
||||
dump_decode_rule (lf *file, char *prefix, decode_table *rule, char *suffix)
|
||||
{
|
||||
lf_printf (file, "%s(decode_table *) 0x%lx", prefix, (long) rule);
|
||||
if (rule != NULL)
|
||||
{
|
||||
lf_indent (file, +1);
|
||||
dump_line_ref (file, "\n(line ", rule->line, ")");
|
||||
lf_printf (file, "\n(type %s)", i2name(rule->type, decode_type_map));
|
||||
lf_printf (file, "\n(gen %s)", i2name(rule->gen, decode_gen_map));
|
||||
lf_printf (file, "\n(type %s)", i2name (rule->type, decode_type_map));
|
||||
lf_printf (file, "\n(gen %s)", i2name (rule->gen, decode_gen_map));
|
||||
lf_printf (file, "\n(first %d)", rule->first);
|
||||
lf_printf (file, "\n(last %d)", rule->last);
|
||||
lf_printf (file, "\n(force_first %d)", rule->force_first);
|
||||
lf_printf (file, "\n(force_last %d)", rule->force_last);
|
||||
dump_filter (file, "\n(constant_field_names \"", rule->constant_field_names, "\")");
|
||||
dump_filter (file, "\n(constant_field_names \"",
|
||||
rule->constant_field_names, "\")");
|
||||
lf_printf (file, "\n(constant 0x%x)", rule->constant);
|
||||
lf_printf (file, "\n(word_nr %d)", rule->word_nr);
|
||||
lf_printf (file, "\n(with_zero_reserved %d)", rule->with_zero_reserved);
|
||||
|
@ -369,10 +375,7 @@ dump_decode_rule (lf *file,
|
|||
#ifdef MAIN
|
||||
|
||||
static void
|
||||
dump_decode_rules (lf *file,
|
||||
char *prefix,
|
||||
decode_table *rule,
|
||||
char *suffix)
|
||||
dump_decode_rules (lf *file, char *prefix, decode_table *rule, char *suffix)
|
||||
{
|
||||
lf_printf (file, "%s", prefix);
|
||||
while (rule != NULL)
|
||||
|
@ -388,7 +391,7 @@ dump_decode_rules (lf *file,
|
|||
igen_options options;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
lf *l;
|
||||
decode_table *rules;
|
||||
|
|
|
@ -133,22 +133,27 @@
|
|||
*/
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
normal_decode_rule,
|
||||
boolean_rule,
|
||||
} decode_special_type;
|
||||
}
|
||||
decode_special_type;
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
invalid_gen,
|
||||
array_gen,
|
||||
switch_gen,
|
||||
padded_switch_gen,
|
||||
goto_switch_gen,
|
||||
} decode_gen_type;
|
||||
}
|
||||
decode_gen_type;
|
||||
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
decode_cond_mask_field,
|
||||
decode_cond_value_field,
|
||||
decode_cond_word_nr_field,
|
||||
|
@ -156,20 +161,23 @@ enum {
|
|||
};
|
||||
|
||||
typedef struct _decode_path decode_path;
|
||||
struct _decode_path {
|
||||
struct _decode_path
|
||||
{
|
||||
int opcode_nr;
|
||||
decode_path *parent;
|
||||
};
|
||||
|
||||
typedef struct _decode_path_list decode_path_list;
|
||||
struct _decode_path_list {
|
||||
struct _decode_path_list
|
||||
{
|
||||
decode_path *path;
|
||||
decode_path_list *next;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _decode_cond decode_cond;
|
||||
struct _decode_cond {
|
||||
struct _decode_cond
|
||||
{
|
||||
int word_nr;
|
||||
int mask[max_insn_bit_size];
|
||||
int value[max_insn_bit_size];
|
||||
|
@ -177,13 +185,16 @@ struct _decode_cond {
|
|||
decode_cond *next;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
decode_find_mixed,
|
||||
decode_find_constants,
|
||||
decode_find_strings,
|
||||
} decode_search_type;
|
||||
}
|
||||
decode_search_type;
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
decode_options_field,
|
||||
decode_first_field,
|
||||
decode_last_field,
|
||||
|
@ -200,7 +211,8 @@ enum {
|
|||
|
||||
|
||||
typedef struct _decode_table decode_table;
|
||||
struct _decode_table {
|
||||
struct _decode_table
|
||||
{
|
||||
line_ref *line;
|
||||
decode_special_type type;
|
||||
decode_gen_type gen;
|
||||
|
@ -226,14 +238,9 @@ struct _decode_table {
|
|||
};
|
||||
|
||||
|
||||
extern decode_table *load_decode_table
|
||||
(char *file_name);
|
||||
extern decode_table *load_decode_table (char *file_name);
|
||||
|
||||
extern int decode_table_max_word_nr
|
||||
(decode_table *rule);
|
||||
extern int decode_table_max_word_nr (decode_table *rule);
|
||||
|
||||
extern void dump_decode_rule
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
decode_table *rule,
|
||||
char *suffix);
|
||||
(lf *file, char *prefix, decode_table *rule, char *suffix);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -38,7 +38,8 @@ typedef unsigned64 insn_uint;
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
record_type_field = 1,
|
||||
old_record_type_field = 2,
|
||||
record_filter_flags_field = 2,
|
||||
|
@ -60,7 +61,8 @@ enum {
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
include_filename_field = 4,
|
||||
nr_include_fields,
|
||||
};
|
||||
|
@ -99,10 +101,11 @@ enum {
|
|||
;
|
||||
|
||||
|
||||
These update the global options structure. */
|
||||
These update the global options structure. */
|
||||
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
option_name_field = 4,
|
||||
option_value_field,
|
||||
nr_option_fields,
|
||||
|
@ -129,7 +132,8 @@ enum {
|
|||
*/
|
||||
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
macro_name_field = 4,
|
||||
macro_args_field,
|
||||
macro_expr_field,
|
||||
|
@ -177,29 +181,33 @@ enum {
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
function_typedef_field = 4,
|
||||
function_name_field,
|
||||
function_param_field,
|
||||
nr_function_fields,
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
function_model_name_field = 0,
|
||||
nr_function_model_fields = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
old_function_typedef_field = 0,
|
||||
old_function_type_field = 2,
|
||||
old_function_name_field = 4,
|
||||
old_function_param_field = 5,
|
||||
nr_old_function_fields = 5, /* parameter-list is optional */
|
||||
nr_old_function_fields = 5, /* parameter-list is optional */
|
||||
};
|
||||
|
||||
|
||||
typedef struct _function_entry function_entry;
|
||||
struct _function_entry {
|
||||
struct _function_entry
|
||||
{
|
||||
line_ref *line;
|
||||
filter *flags;
|
||||
filter *models;
|
||||
|
@ -213,15 +221,11 @@ struct _function_entry {
|
|||
|
||||
|
||||
typedef void function_entry_handler
|
||||
(lf *file,
|
||||
function_entry *function,
|
||||
void *data);
|
||||
(lf *file, function_entry * function, void *data);
|
||||
|
||||
extern void function_entry_traverse
|
||||
(lf *file,
|
||||
function_entry *functions,
|
||||
function_entry_handler *handler,
|
||||
void *data);
|
||||
(lf *file,
|
||||
function_entry * functions, function_entry_handler * handler, void *data);
|
||||
|
||||
|
||||
/* cache-macro:
|
||||
|
@ -258,7 +262,8 @@ extern void function_entry_traverse
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
cache_typedef_field = 4,
|
||||
cache_name_field,
|
||||
cache_original_fields_field,
|
||||
|
@ -266,14 +271,17 @@ enum {
|
|||
nr_cache_fields,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
scratch_value,
|
||||
cache_value,
|
||||
compute_value,
|
||||
} cache_entry_type;
|
||||
}
|
||||
cache_entry_type;
|
||||
|
||||
typedef struct _cache_entry cache_entry;
|
||||
struct _cache_entry {
|
||||
struct _cache_entry
|
||||
{
|
||||
line_ref *line;
|
||||
filter *flags;
|
||||
filter *models;
|
||||
|
@ -332,7 +340,8 @@ struct _cache_entry {
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
nr_model_macro_fields = 4,
|
||||
nr_model_data_fields = 4,
|
||||
nr_model_static_fields = nr_function_fields,
|
||||
|
@ -341,7 +350,8 @@ enum {
|
|||
};
|
||||
|
||||
typedef struct _model_data model_data;
|
||||
struct _model_data {
|
||||
struct _model_data
|
||||
{
|
||||
line_ref *line;
|
||||
filter *flags;
|
||||
table_entry *entry;
|
||||
|
@ -349,7 +359,8 @@ struct _model_data {
|
|||
model_data *next;
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
model_name_field = 4,
|
||||
model_full_name_field,
|
||||
model_unit_data_field,
|
||||
|
@ -357,7 +368,8 @@ enum {
|
|||
};
|
||||
|
||||
typedef struct _model_entry model_entry;
|
||||
struct _model_entry {
|
||||
struct _model_entry
|
||||
{
|
||||
line_ref *line;
|
||||
filter *flags;
|
||||
char *name;
|
||||
|
@ -368,7 +380,8 @@ struct _model_entry {
|
|||
|
||||
|
||||
typedef struct _model_table model_table;
|
||||
struct _model_table {
|
||||
struct _model_table
|
||||
{
|
||||
filter *processors;
|
||||
int nr_models;
|
||||
model_entry *models;
|
||||
|
@ -410,16 +423,21 @@ struct _model_table {
|
|||
|
||||
*/
|
||||
|
||||
typedef enum _insn_field_cond_type {
|
||||
typedef enum _insn_field_cond_type
|
||||
{
|
||||
insn_field_cond_value,
|
||||
insn_field_cond_field,
|
||||
} insn_field_cond_type;
|
||||
typedef enum _insn_field_cond_test {
|
||||
}
|
||||
insn_field_cond_type;
|
||||
typedef enum _insn_field_cond_test
|
||||
{
|
||||
insn_field_cond_eq,
|
||||
insn_field_cond_ne,
|
||||
} insn_field_cond_test;
|
||||
}
|
||||
insn_field_cond_test;
|
||||
typedef struct _insn_field_cond insn_field_cond;
|
||||
struct _insn_field_cond {
|
||||
struct _insn_field_cond
|
||||
{
|
||||
insn_field_cond_type type;
|
||||
insn_field_cond_test test;
|
||||
insn_uint value;
|
||||
|
@ -429,16 +447,19 @@ struct _insn_field_cond {
|
|||
};
|
||||
|
||||
|
||||
typedef enum _insn_field_type {
|
||||
typedef enum _insn_field_type
|
||||
{
|
||||
insn_field_invalid,
|
||||
insn_field_int,
|
||||
insn_field_reserved,
|
||||
insn_field_wild,
|
||||
insn_field_string,
|
||||
} insn_field_type;
|
||||
}
|
||||
insn_field_type;
|
||||
|
||||
typedef struct _insn_field_entry insn_field_entry;
|
||||
struct _insn_field_entry {
|
||||
struct _insn_field_entry
|
||||
{
|
||||
int first;
|
||||
int last;
|
||||
int width;
|
||||
|
@ -453,7 +474,8 @@ struct _insn_field_entry {
|
|||
};
|
||||
|
||||
typedef struct _insn_bit_entry insn_bit_entry;
|
||||
struct _insn_bit_entry {
|
||||
struct _insn_bit_entry
|
||||
{
|
||||
int value;
|
||||
int mask;
|
||||
insn_field_entry *field;
|
||||
|
@ -462,10 +484,11 @@ struct _insn_bit_entry {
|
|||
|
||||
|
||||
|
||||
typedef struct _insn_entry insn_entry; /* forward */
|
||||
typedef struct _insn_entry insn_entry; /* forward */
|
||||
|
||||
typedef struct _insn_word_entry insn_word_entry;
|
||||
struct _insn_word_entry {
|
||||
struct _insn_word_entry
|
||||
{
|
||||
/* list of sub-fields making up the instruction. bit provides
|
||||
faster access to the field data for bit N. */
|
||||
insn_field_entry *first;
|
||||
|
@ -499,14 +522,16 @@ struct _insn_word_entry {
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
insn_model_name_field = 0,
|
||||
insn_model_unit_data_field = 1,
|
||||
nr_insn_model_fields = 1,
|
||||
};
|
||||
|
||||
typedef struct _insn_model_entry insn_model_entry;
|
||||
struct _insn_model_entry {
|
||||
struct _insn_model_entry
|
||||
{
|
||||
line_ref *line;
|
||||
insn_entry *insn;
|
||||
filter *names;
|
||||
|
@ -554,14 +579,16 @@ struct _insn_model_entry {
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
insn_mnemonic_format_field = 0,
|
||||
insn_mnemonic_condition_field = 1,
|
||||
nr_insn_mnemonic_fields = 1,
|
||||
};
|
||||
|
||||
typedef struct _insn_mnemonic_entry insn_mnemonic_entry;
|
||||
struct _insn_mnemonic_entry {
|
||||
struct _insn_mnemonic_entry
|
||||
{
|
||||
line_ref *line;
|
||||
insn_entry *insn;
|
||||
char *format;
|
||||
|
@ -586,7 +613,8 @@ struct _insn_mnemonic_entry {
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
insn_word_field = 0,
|
||||
insn_format_name_field = 1,
|
||||
insn_filter_flags_field = 2,
|
||||
|
@ -597,9 +625,10 @@ enum {
|
|||
|
||||
|
||||
/* typedef struct _insn_entry insn_entry; */
|
||||
struct _insn_entry {
|
||||
struct _insn_entry
|
||||
{
|
||||
line_ref *line;
|
||||
filter *flags; /* filtered by options.filters */
|
||||
filter *flags; /* filtered by options.filters */
|
||||
char *format_name;
|
||||
filter *options;
|
||||
char *name;
|
||||
|
@ -630,7 +659,8 @@ struct _insn_entry {
|
|||
*/
|
||||
|
||||
typedef struct _insn_table insn_table;
|
||||
struct _insn_table {
|
||||
struct _insn_table
|
||||
{
|
||||
cache_entry *caches;
|
||||
int max_nr_words;
|
||||
int nr_insns;
|
||||
|
@ -642,65 +672,37 @@ struct _insn_table {
|
|||
filter *flags;
|
||||
};
|
||||
|
||||
extern insn_table *load_insn_table
|
||||
(char *file_name,
|
||||
cache_entry *cache);
|
||||
extern insn_table *load_insn_table (char *file_name, cache_entry *cache);
|
||||
|
||||
typedef void insn_entry_handler
|
||||
(lf *file,
|
||||
insn_table *isa,
|
||||
insn_entry *insn,
|
||||
void *data);
|
||||
(lf *file, insn_table *isa, insn_entry * insn, void *data);
|
||||
|
||||
extern void insn_table_traverse_insn
|
||||
(lf *file,
|
||||
insn_table *isa,
|
||||
insn_entry_handler *handler,
|
||||
void *data);
|
||||
(lf *file, insn_table *isa, insn_entry_handler * handler, void *data);
|
||||
|
||||
|
||||
|
||||
/* Printing */
|
||||
|
||||
extern void print_insn_words
|
||||
(lf *file,
|
||||
insn_entry *insn);
|
||||
extern void print_insn_words (lf *file, insn_entry * insn);
|
||||
|
||||
|
||||
|
||||
/* Debugging */
|
||||
|
||||
void
|
||||
dump_insn_field
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
insn_field_entry *field,
|
||||
char *suffix);
|
||||
dump_insn_field
|
||||
(lf *file, char *prefix, insn_field_entry *field, char *suffix);
|
||||
|
||||
void
|
||||
dump_insn_word_entry
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
insn_word_entry *word,
|
||||
char *suffix);
|
||||
dump_insn_word_entry
|
||||
(lf *file, char *prefix, insn_word_entry *word, char *suffix);
|
||||
|
||||
void
|
||||
dump_insn_entry
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
insn_entry *insn,
|
||||
char *suffix);
|
||||
dump_insn_entry (lf *file, char *prefix, insn_entry * insn, char *suffix);
|
||||
|
||||
void
|
||||
dump_cache_entries
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
cache_entry *entry,
|
||||
char *suffix);
|
||||
dump_cache_entries
|
||||
(lf *file, char *prefix, cache_entry *entry, char *suffix);
|
||||
|
||||
void
|
||||
dump_insn_table
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
insn_table *isa,
|
||||
char *suffix);
|
||||
void dump_insn_table (lf *file, char *prefix, insn_table *isa, char *suffix);
|
||||
|
|
307
sim/igen/lf.c
307
sim/igen/lf.c
|
@ -43,9 +43,10 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
struct _lf {
|
||||
struct _lf
|
||||
{
|
||||
FILE *stream;
|
||||
int line_nr; /* nr complete lines written, curr line is line_nr+1 */
|
||||
int line_nr; /* nr complete lines written, curr line is line_nr+1 */
|
||||
int indent;
|
||||
int line_blank;
|
||||
const char *name;
|
||||
|
@ -59,70 +60,73 @@ lf *
|
|||
lf_open (char *name,
|
||||
char *real_name,
|
||||
lf_file_references references,
|
||||
lf_file_type type,
|
||||
const char *program)
|
||||
lf_file_type type, const char *program)
|
||||
{
|
||||
/* create a file object */
|
||||
lf *new_lf = ZALLOC(lf);
|
||||
lf *new_lf = ZALLOC (lf);
|
||||
ASSERT (new_lf != NULL);
|
||||
new_lf->references = references;
|
||||
new_lf->type = type;
|
||||
new_lf->name = (real_name == NULL ? name : real_name);
|
||||
new_lf->program = program;
|
||||
/* attach to stdout if pipe */
|
||||
if (!strcmp(name, "-")) {
|
||||
new_lf->stream = stdout;
|
||||
}
|
||||
else {
|
||||
/* create a new file */
|
||||
new_lf->stream = fopen(name, "w");
|
||||
if (new_lf->stream == NULL) {
|
||||
perror(name);
|
||||
exit(1);
|
||||
if (!strcmp (name, "-"))
|
||||
{
|
||||
new_lf->stream = stdout;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a new file */
|
||||
new_lf->stream = fopen (name, "w");
|
||||
if (new_lf->stream == NULL)
|
||||
{
|
||||
perror (name);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new_lf;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lf_close(lf *file)
|
||||
lf_close (lf *file)
|
||||
{
|
||||
if (file->stream != stdout) {
|
||||
if (fclose(file->stream)) {
|
||||
perror("lf_close.fclose");
|
||||
exit(1);
|
||||
if (file->stream != stdout)
|
||||
{
|
||||
if (fclose (file->stream))
|
||||
{
|
||||
perror ("lf_close.fclose");
|
||||
exit (1);
|
||||
}
|
||||
free (file);
|
||||
}
|
||||
free(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lf_putchr(lf *file,
|
||||
const char chr)
|
||||
lf_putchr (lf *file, const char chr)
|
||||
{
|
||||
int nr = 0;
|
||||
if (chr == '\n') {
|
||||
file->line_nr += 1;
|
||||
file->line_blank = 1;
|
||||
}
|
||||
else if (file->line_blank) {
|
||||
int pad;
|
||||
for (pad = file->indent; pad > 0; pad--)
|
||||
putc(' ', file->stream);
|
||||
nr += file->indent;
|
||||
file->line_blank = 0;
|
||||
}
|
||||
putc(chr, file->stream);
|
||||
if (chr == '\n')
|
||||
{
|
||||
file->line_nr += 1;
|
||||
file->line_blank = 1;
|
||||
}
|
||||
else if (file->line_blank)
|
||||
{
|
||||
int pad;
|
||||
for (pad = file->indent; pad > 0; pad--)
|
||||
putc (' ', file->stream);
|
||||
nr += file->indent;
|
||||
file->line_blank = 0;
|
||||
}
|
||||
putc (chr, file->stream);
|
||||
nr += 1;
|
||||
return nr;
|
||||
}
|
||||
|
||||
int
|
||||
lf_write (lf *file,
|
||||
const char *string,
|
||||
int strlen_string)
|
||||
lf_write (lf *file, const char *string, int strlen_string)
|
||||
{
|
||||
int nr = 0;
|
||||
int i;
|
||||
|
@ -133,63 +137,63 @@ lf_write (lf *file,
|
|||
|
||||
|
||||
void
|
||||
lf_indent_suppress(lf *file)
|
||||
lf_indent_suppress (lf *file)
|
||||
{
|
||||
file->line_blank = 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lf_putstr(lf *file,
|
||||
const char *string)
|
||||
lf_putstr (lf *file, const char *string)
|
||||
{
|
||||
int nr = 0;
|
||||
const char *chp;
|
||||
if (string != NULL) {
|
||||
for (chp = string; *chp != '\0'; chp++) {
|
||||
nr += lf_putchr(file, *chp);
|
||||
if (string != NULL)
|
||||
{
|
||||
for (chp = string; *chp != '\0'; chp++)
|
||||
{
|
||||
nr += lf_putchr (file, *chp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
static int
|
||||
do_lf_putunsigned(lf *file,
|
||||
unsigned u)
|
||||
do_lf_putunsigned (lf *file, unsigned u)
|
||||
{
|
||||
int nr = 0;
|
||||
if (u > 0) {
|
||||
nr += do_lf_putunsigned(file, u / 10);
|
||||
nr += lf_putchr(file, (u % 10) + '0');
|
||||
}
|
||||
if (u > 0)
|
||||
{
|
||||
nr += do_lf_putunsigned (file, u / 10);
|
||||
nr += lf_putchr (file, (u % 10) + '0');
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lf_putint(lf *file,
|
||||
int decimal)
|
||||
lf_putint (lf *file, int decimal)
|
||||
{
|
||||
int nr = 0;
|
||||
if (decimal == 0)
|
||||
nr += lf_putchr(file, '0');
|
||||
else if (decimal < 0) {
|
||||
nr += lf_putchr(file, '-');
|
||||
nr += do_lf_putunsigned(file, -decimal);
|
||||
}
|
||||
else if (decimal > 0) {
|
||||
nr += do_lf_putunsigned(file, decimal);
|
||||
}
|
||||
nr += lf_putchr (file, '0');
|
||||
else if (decimal < 0)
|
||||
{
|
||||
nr += lf_putchr (file, '-');
|
||||
nr += do_lf_putunsigned (file, -decimal);
|
||||
}
|
||||
else if (decimal > 0)
|
||||
{
|
||||
nr += do_lf_putunsigned (file, decimal);
|
||||
}
|
||||
else
|
||||
ASSERT(0);
|
||||
ASSERT (0);
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lf_printf (lf *file,
|
||||
const char *fmt,
|
||||
...)
|
||||
lf_printf (lf *file, const char *fmt, ...)
|
||||
{
|
||||
int nr = 0;
|
||||
char buf[1024];
|
||||
|
@ -200,28 +204,25 @@ lf_printf (lf *file,
|
|||
/* FIXME - this is really stuffed but so is vsprintf() on a sun! */
|
||||
ASSERT (strlen (buf) < sizeof (buf));
|
||||
nr += lf_putstr (file, buf);
|
||||
va_end(ap);
|
||||
va_end (ap);
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lf_print__line_ref (lf *file,
|
||||
line_ref *line)
|
||||
lf_print__line_ref (lf *file, line_ref *line)
|
||||
{
|
||||
return lf_print__external_ref (file, line->line_nr, line->file_name);
|
||||
}
|
||||
|
||||
int
|
||||
lf_print__external_ref (lf *file,
|
||||
int line_nr,
|
||||
const char *file_name)
|
||||
lf_print__external_ref (lf *file, int line_nr, const char *file_name)
|
||||
{
|
||||
int nr = 0;
|
||||
switch (file->references)
|
||||
{
|
||||
case lf_include_references:
|
||||
lf_indent_suppress(file);
|
||||
lf_indent_suppress (file);
|
||||
nr += lf_putstr (file, "#line ");
|
||||
nr += lf_putint (file, line_nr);
|
||||
nr += lf_putstr (file, " \"");
|
||||
|
@ -243,7 +244,7 @@ int
|
|||
lf_print__internal_ref (lf *file)
|
||||
{
|
||||
int nr = 0;
|
||||
nr += lf_print__external_ref (file, file->line_nr+2, file->name);
|
||||
nr += lf_print__external_ref (file, file->line_nr + 2, file->name);
|
||||
/* line_nr == last_line, want to number from next */
|
||||
return nr;
|
||||
}
|
||||
|
@ -259,10 +260,11 @@ int
|
|||
lf_print__gnu_copyleft (lf *file)
|
||||
{
|
||||
int nr = 0;
|
||||
switch (file->type) {
|
||||
case lf_is_c:
|
||||
case lf_is_h:
|
||||
nr += lf_printf(file, "\
|
||||
switch (file->type)
|
||||
{
|
||||
case lf_is_c:
|
||||
case lf_is_h:
|
||||
nr += lf_printf (file, "\
|
||||
/* This file is part of GDB.\n\
|
||||
\n\
|
||||
Copyright 2002 Free Software Foundation, Inc.\n\
|
||||
|
@ -285,110 +287,115 @@ lf_print__gnu_copyleft (lf *file)
|
|||
--\n\
|
||||
\n\
|
||||
This file was generated by the program %s */\n\
|
||||
", filter_filename(file->program));
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
", filter_filename (file->program));
|
||||
break;
|
||||
default:
|
||||
ASSERT (0);
|
||||
break;
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lf_putbin(lf *file, int decimal, int width)
|
||||
lf_putbin (lf *file, int decimal, int width)
|
||||
{
|
||||
int nr = 0;
|
||||
int bit;
|
||||
ASSERT(width > 0);
|
||||
for (bit = 1 << (width-1); bit != 0; bit >>= 1) {
|
||||
if (decimal & bit)
|
||||
nr += lf_putchr(file, '1');
|
||||
else
|
||||
nr += lf_putchr(file, '0');
|
||||
}
|
||||
ASSERT (width > 0);
|
||||
for (bit = 1 << (width - 1); bit != 0; bit >>= 1)
|
||||
{
|
||||
if (decimal & bit)
|
||||
nr += lf_putchr (file, '1');
|
||||
else
|
||||
nr += lf_putchr (file, '0');
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
int
|
||||
lf_print__this_file_is_empty(lf *file,
|
||||
const char *reason)
|
||||
lf_print__this_file_is_empty (lf *file, const char *reason)
|
||||
{
|
||||
int nr = 0;
|
||||
switch (file->type) {
|
||||
case lf_is_c:
|
||||
case lf_is_h:
|
||||
nr += lf_printf (file,
|
||||
"/* This generated file (%s) is intentionally left blank",
|
||||
file->name);
|
||||
if (reason != NULL)
|
||||
nr += lf_printf (file, " - %s", reason);
|
||||
nr += lf_printf (file, " */\n");
|
||||
break;
|
||||
default:
|
||||
ERROR ("Bad switch");
|
||||
}
|
||||
switch (file->type)
|
||||
{
|
||||
case lf_is_c:
|
||||
case lf_is_h:
|
||||
nr += lf_printf (file,
|
||||
"/* This generated file (%s) is intentionally left blank",
|
||||
file->name);
|
||||
if (reason != NULL)
|
||||
nr += lf_printf (file, " - %s", reason);
|
||||
nr += lf_printf (file, " */\n");
|
||||
break;
|
||||
default:
|
||||
ERROR ("Bad switch");
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
int
|
||||
lf_print__ucase_filename(lf *file)
|
||||
lf_print__ucase_filename (lf *file)
|
||||
{
|
||||
int nr = 0;
|
||||
const char *chp = file->name;
|
||||
while (*chp != '\0') {
|
||||
char ch = *chp;
|
||||
if (islower(ch)) {
|
||||
nr += lf_putchr(file, toupper(ch));
|
||||
while (*chp != '\0')
|
||||
{
|
||||
char ch = *chp;
|
||||
if (islower (ch))
|
||||
{
|
||||
nr += lf_putchr (file, toupper (ch));
|
||||
}
|
||||
else if (ch == '.')
|
||||
nr += lf_putchr (file, '_');
|
||||
else
|
||||
nr += lf_putchr (file, ch);
|
||||
chp++;
|
||||
}
|
||||
else if (ch == '.')
|
||||
nr += lf_putchr(file, '_');
|
||||
else
|
||||
nr += lf_putchr(file, ch);
|
||||
chp++;
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
int
|
||||
lf_print__file_start(lf *file)
|
||||
lf_print__file_start (lf *file)
|
||||
{
|
||||
int nr = 0;
|
||||
switch (file->type) {
|
||||
case lf_is_h:
|
||||
case lf_is_c:
|
||||
nr += lf_print__gnu_copyleft(file);
|
||||
nr += lf_printf(file, "\n");
|
||||
nr += lf_printf(file, "#ifndef ");
|
||||
nr += lf_print__ucase_filename(file);
|
||||
nr += lf_printf(file, "\n");
|
||||
nr += lf_printf(file, "#define ");
|
||||
nr += lf_print__ucase_filename(file);
|
||||
nr += lf_printf(file, "\n");
|
||||
nr += lf_printf(file, "\n");
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
switch (file->type)
|
||||
{
|
||||
case lf_is_h:
|
||||
case lf_is_c:
|
||||
nr += lf_print__gnu_copyleft (file);
|
||||
nr += lf_printf (file, "\n");
|
||||
nr += lf_printf (file, "#ifndef ");
|
||||
nr += lf_print__ucase_filename (file);
|
||||
nr += lf_printf (file, "\n");
|
||||
nr += lf_printf (file, "#define ");
|
||||
nr += lf_print__ucase_filename (file);
|
||||
nr += lf_printf (file, "\n");
|
||||
nr += lf_printf (file, "\n");
|
||||
break;
|
||||
default:
|
||||
ASSERT (0);
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lf_print__file_finish(lf *file)
|
||||
lf_print__file_finish (lf *file)
|
||||
{
|
||||
int nr = 0;
|
||||
switch (file->type) {
|
||||
case lf_is_h:
|
||||
case lf_is_c:
|
||||
nr += lf_printf(file, "\n");
|
||||
nr += lf_printf(file, "#endif /* _");
|
||||
nr += lf_print__ucase_filename(file);
|
||||
nr += lf_printf(file, "_*/\n");
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
switch (file->type)
|
||||
{
|
||||
case lf_is_h:
|
||||
case lf_is_c:
|
||||
nr += lf_printf (file, "\n");
|
||||
nr += lf_printf (file, "#endif /* _");
|
||||
nr += lf_print__ucase_filename (file);
|
||||
nr += lf_printf (file, "_*/\n");
|
||||
break;
|
||||
default:
|
||||
ASSERT (0);
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
@ -396,8 +403,7 @@ lf_print__file_finish(lf *file)
|
|||
int
|
||||
lf_print__function_type (lf *file,
|
||||
const char *type,
|
||||
const char *prefix,
|
||||
const char *trailing_space)
|
||||
const char *prefix, const char *trailing_space)
|
||||
{
|
||||
int nr = 0;
|
||||
nr += lf_printf (file, "%s\\\n(%s)", prefix, type);
|
||||
|
@ -408,7 +414,7 @@ lf_print__function_type (lf *file,
|
|||
|
||||
int
|
||||
lf_print__function_type_function (lf *file,
|
||||
print_function *print_type,
|
||||
print_function * print_type,
|
||||
const char *prefix,
|
||||
const char *trailing_space)
|
||||
{
|
||||
|
@ -420,4 +426,3 @@ lf_print__function_type_function (lf *file,
|
|||
nr += lf_printf (file, "%s", trailing_space);
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
|
100
sim/igen/lf.h
100
sim/igen/lf.h
|
@ -27,17 +27,21 @@
|
|||
|
||||
typedef struct _lf lf;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
lf_is_h,
|
||||
lf_is_c,
|
||||
lf_is_text,
|
||||
} lf_file_type;
|
||||
}
|
||||
lf_file_type;
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
lf_include_references,
|
||||
lf_omit_references,
|
||||
} lf_file_references;
|
||||
}
|
||||
lf_file_references;
|
||||
|
||||
|
||||
/* Open the file NAME for writing ("-" for stdout). Use REAL_NAME
|
||||
|
@ -47,44 +51,28 @@ typedef enum {
|
|||
the print messages below. */
|
||||
|
||||
extern lf *lf_open
|
||||
(char *name,
|
||||
char *real_name,
|
||||
lf_file_references file_references,
|
||||
lf_file_type type,
|
||||
const char *program);
|
||||
(char *name,
|
||||
char *real_name,
|
||||
lf_file_references file_references,
|
||||
lf_file_type type, const char *program);
|
||||
|
||||
extern void lf_close
|
||||
(lf *file);
|
||||
extern void lf_close (lf *file);
|
||||
|
||||
|
||||
/* Basic output functions */
|
||||
|
||||
extern int lf_write
|
||||
(lf *file,
|
||||
const char *string,
|
||||
int len);
|
||||
extern int lf_write (lf *file, const char *string, int len);
|
||||
|
||||
extern int lf_putchr
|
||||
(lf *file,
|
||||
const char ch);
|
||||
extern int lf_putchr (lf *file, const char ch);
|
||||
|
||||
extern int lf_putstr
|
||||
(lf *file,
|
||||
const char *string);
|
||||
extern int lf_putstr (lf *file, const char *string);
|
||||
|
||||
extern int lf_putint
|
||||
(lf *file,
|
||||
int decimal);
|
||||
extern int lf_putint (lf *file, int decimal);
|
||||
|
||||
extern int lf_putbin
|
||||
(lf *file,
|
||||
int decimal,
|
||||
int width);
|
||||
extern int lf_putbin (lf *file, int decimal, int width);
|
||||
|
||||
extern int lf_printf
|
||||
(lf *file,
|
||||
const char *fmt,
|
||||
...) __attribute__((format(printf, 2, 3)));
|
||||
(lf *file, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
|
||||
/* Indentation control.
|
||||
|
@ -92,56 +80,38 @@ extern int lf_printf
|
|||
lf_indent_suppress suppresses indentation on the next line (current
|
||||
line if that has not yet been started) */
|
||||
|
||||
extern void lf_indent_suppress
|
||||
(lf *file);
|
||||
extern void lf_indent_suppress (lf *file);
|
||||
|
||||
extern void lf_indent
|
||||
(lf *file,
|
||||
int delta);
|
||||
extern void lf_indent (lf *file, int delta);
|
||||
|
||||
|
||||
/* Print generic text: */
|
||||
|
||||
|
||||
extern int lf_print__gnu_copyleft
|
||||
(lf *file);
|
||||
extern int lf_print__gnu_copyleft (lf *file);
|
||||
|
||||
extern int lf_print__file_start
|
||||
(lf *file);
|
||||
extern int lf_print__file_start (lf *file);
|
||||
|
||||
extern int lf_print__this_file_is_empty
|
||||
(lf *file,
|
||||
const char *reason);
|
||||
extern int lf_print__this_file_is_empty (lf *file, const char *reason);
|
||||
|
||||
extern int lf_print__file_finish
|
||||
(lf *file);
|
||||
extern int lf_print__file_finish (lf *file);
|
||||
|
||||
extern int lf_print__internal_ref
|
||||
(lf *file);
|
||||
extern int lf_print__internal_ref (lf *file);
|
||||
|
||||
extern int lf_print__external_ref
|
||||
(lf *file,
|
||||
int line_nr,
|
||||
const char *file_name);
|
||||
(lf *file, int line_nr, const char *file_name);
|
||||
|
||||
extern int lf_print__line_ref
|
||||
(lf *file,
|
||||
line_ref *line);
|
||||
extern int lf_print__line_ref (lf *file, line_ref *line);
|
||||
|
||||
extern int lf_print__ucase_filename
|
||||
(lf *file);
|
||||
extern int lf_print__ucase_filename (lf *file);
|
||||
|
||||
extern int lf_print__function_type
|
||||
(lf *file,
|
||||
const char *type,
|
||||
const char *prefix,
|
||||
const char *trailing_space);
|
||||
(lf *file,
|
||||
const char *type, const char *prefix, const char *trailing_space);
|
||||
|
||||
typedef int print_function(lf *file);
|
||||
typedef int print_function (lf *file);
|
||||
|
||||
extern int lf_print__function_type_function
|
||||
(lf *file,
|
||||
print_function *print_type,
|
||||
const char *prefix,
|
||||
const char *trailing_space);
|
||||
|
||||
(lf *file,
|
||||
print_function * print_type,
|
||||
const char *prefix, const char *trailing_space);
|
||||
|
|
|
@ -46,9 +46,7 @@
|
|||
trailing '\n' */
|
||||
|
||||
void
|
||||
error (const line_ref *line,
|
||||
char *msg,
|
||||
...)
|
||||
error (const line_ref *line, char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if (line != NULL)
|
||||
|
@ -60,9 +58,7 @@ error (const line_ref *line,
|
|||
}
|
||||
|
||||
void
|
||||
warning (const line_ref *line,
|
||||
char *msg,
|
||||
...)
|
||||
warning (const line_ref *line, char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if (line != NULL)
|
||||
|
@ -73,25 +69,23 @@ warning (const line_ref *line,
|
|||
}
|
||||
|
||||
void
|
||||
notify (const line_ref *line,
|
||||
char *msg,
|
||||
...)
|
||||
notify (const line_ref *line, char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if (line != NULL)
|
||||
fprintf (stdout, "%s %d: info: ", line->file_name, line->line_nr);
|
||||
va_start(ap, msg);
|
||||
va_start (ap, msg);
|
||||
vfprintf (stdout, msg, ap);
|
||||
va_end(ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void *
|
||||
zalloc(long size)
|
||||
zalloc (long size)
|
||||
{
|
||||
void *memory = malloc(size);
|
||||
void *memory = malloc (size);
|
||||
if (memory == NULL)
|
||||
ERROR ("zalloc failed");
|
||||
memset(memory, 0, size);
|
||||
memset (memory, 0, size);
|
||||
return memory;
|
||||
}
|
||||
|
||||
|
@ -103,16 +97,14 @@ a2i (const char *a)
|
|||
int base = 10;
|
||||
unsigned long long num = 0;
|
||||
int looping;
|
||||
|
||||
|
||||
while (isspace (*a))
|
||||
a++;
|
||||
|
||||
if (strcmp (a, "true") == 0
|
||||
|| strcmp (a, "TRUE") == 0)
|
||||
|
||||
if (strcmp (a, "true") == 0 || strcmp (a, "TRUE") == 0)
|
||||
return 1;
|
||||
|
||||
if (strcmp (a, "false") == 0
|
||||
|| strcmp (a, "false") == 0)
|
||||
if (strcmp (a, "false") == 0 || strcmp (a, "false") == 0)
|
||||
return 0;
|
||||
|
||||
if (*a == '-')
|
||||
|
@ -120,7 +112,7 @@ a2i (const char *a)
|
|||
neg = 1;
|
||||
a++;
|
||||
}
|
||||
|
||||
|
||||
if (*a == '0')
|
||||
{
|
||||
if (a[1] == 'x' || a[1] == 'X')
|
||||
|
@ -136,18 +128,18 @@ a2i (const char *a)
|
|||
else
|
||||
base = 8;
|
||||
}
|
||||
|
||||
|
||||
looping = 1;
|
||||
while (looping)
|
||||
{
|
||||
int ch = *a++;
|
||||
|
||||
|
||||
switch (base)
|
||||
{
|
||||
default:
|
||||
looping = 0;
|
||||
break;
|
||||
|
||||
|
||||
case 2:
|
||||
if (ch >= '0' && ch <= '1')
|
||||
{
|
||||
|
@ -158,7 +150,7 @@ a2i (const char *a)
|
|||
looping = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 10:
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
|
@ -169,7 +161,7 @@ a2i (const char *a)
|
|||
looping = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 8:
|
||||
if (ch >= '0' && ch <= '7')
|
||||
{
|
||||
|
@ -180,7 +172,7 @@ a2i (const char *a)
|
|||
looping = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 16:
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
|
@ -201,26 +193,24 @@ a2i (const char *a)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (neg)
|
||||
num = - num;
|
||||
num = -num;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
unsigned
|
||||
target_a2i(int ms_bit_nr,
|
||||
const char *a)
|
||||
target_a2i (int ms_bit_nr, const char *a)
|
||||
{
|
||||
if (ms_bit_nr)
|
||||
return (ms_bit_nr - a2i(a));
|
||||
return (ms_bit_nr - a2i (a));
|
||||
else
|
||||
return a2i(a);
|
||||
return a2i (a);
|
||||
}
|
||||
|
||||
unsigned
|
||||
i2target(int ms_bit_nr,
|
||||
unsigned bit)
|
||||
i2target (int ms_bit_nr, unsigned bit)
|
||||
{
|
||||
if (ms_bit_nr)
|
||||
return ms_bit_nr - bit;
|
||||
|
@ -230,20 +220,19 @@ i2target(int ms_bit_nr,
|
|||
|
||||
|
||||
int
|
||||
name2i (const char *names,
|
||||
const name_map *map)
|
||||
name2i (const char *names, const name_map * map)
|
||||
{
|
||||
const name_map *curr;
|
||||
const char *name = names;
|
||||
while (*name != '\0')
|
||||
{
|
||||
/* find our name */
|
||||
char *end = strchr(name, ',');
|
||||
char *end = strchr (name, ',');
|
||||
char *next;
|
||||
unsigned len;
|
||||
if (end == NULL)
|
||||
{
|
||||
end = strchr(name, '\0');
|
||||
end = strchr (name, '\0');
|
||||
next = end;
|
||||
}
|
||||
else
|
||||
|
@ -274,8 +263,7 @@ name2i (const char *names,
|
|||
}
|
||||
|
||||
const char *
|
||||
i2name (const int i,
|
||||
const name_map *map)
|
||||
i2name (const int i, const name_map * map)
|
||||
{
|
||||
while (map->name != NULL)
|
||||
{
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
#include "config.h"
|
||||
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
default_insn_bit_size = 32,
|
||||
max_insn_bit_size = 64,
|
||||
};
|
||||
|
@ -42,7 +43,7 @@ enum {
|
|||
typedef long long signed64;
|
||||
typedef unsigned long long unsigned64;
|
||||
|
||||
#else /* _WIN32 */
|
||||
#else /* _WIN32 */
|
||||
|
||||
typedef __int64 signed64;
|
||||
typedef unsigned __int64 unsigned64;
|
||||
|
@ -77,16 +78,14 @@ typedef unsigned __int64 unsigned64;
|
|||
#include "filter_host.h"
|
||||
|
||||
typedef struct _line_ref line_ref;
|
||||
struct _line_ref {
|
||||
struct _line_ref
|
||||
{
|
||||
const char *file_name;
|
||||
int line_nr;
|
||||
};
|
||||
|
||||
/* Error appends a new line, warning and notify do not */
|
||||
typedef void error_func
|
||||
(const line_ref *line,
|
||||
char *msg,
|
||||
...);
|
||||
typedef void error_func (const line_ref *line, char *msg, ...);
|
||||
|
||||
extern error_func error;
|
||||
extern error_func warning;
|
||||
|
@ -118,19 +117,13 @@ do { \
|
|||
#define STRNDUP(STRING,LEN) (strncpy (zalloc ((LEN) + 1), (STRING), (LEN)))
|
||||
#endif
|
||||
|
||||
extern void *zalloc
|
||||
(long size);
|
||||
extern void *zalloc (long size);
|
||||
|
||||
extern unsigned target_a2i
|
||||
(int ms_bit_nr,
|
||||
const char *a);
|
||||
extern unsigned target_a2i (int ms_bit_nr, const char *a);
|
||||
|
||||
extern unsigned i2target
|
||||
(int ms_bit_nr,
|
||||
unsigned bit);
|
||||
extern unsigned i2target (int ms_bit_nr, unsigned bit);
|
||||
|
||||
extern unsigned long long a2i
|
||||
(const char *a);
|
||||
extern unsigned long long a2i (const char *a);
|
||||
|
||||
|
||||
/* Try looking for name in the map table (returning the corresponding
|
||||
|
@ -139,15 +132,13 @@ extern unsigned long long a2i
|
|||
If the the sentinal (NAME == NULL) its value if >= zero is returned
|
||||
as the default. */
|
||||
|
||||
typedef struct _name_map {
|
||||
typedef struct _name_map
|
||||
{
|
||||
const char *name;
|
||||
int i;
|
||||
} name_map;
|
||||
}
|
||||
name_map;
|
||||
|
||||
extern int name2i
|
||||
(const char *name,
|
||||
const name_map *map);
|
||||
extern int name2i (const char *name, const name_map * map);
|
||||
|
||||
extern const char *i2name
|
||||
(const int i,
|
||||
const name_map *map);
|
||||
extern const char *i2name (const int i, const name_map * map);
|
||||
|
|
131
sim/igen/table.c
131
sim/igen/table.c
|
@ -43,7 +43,8 @@
|
|||
#endif
|
||||
|
||||
typedef struct _open_table open_table;
|
||||
struct _open_table {
|
||||
struct _open_table
|
||||
{
|
||||
size_t size;
|
||||
char *buffer;
|
||||
char *pos;
|
||||
|
@ -52,13 +53,14 @@ struct _open_table {
|
|||
open_table *parent;
|
||||
table *root;
|
||||
};
|
||||
struct _table {
|
||||
struct _table
|
||||
{
|
||||
open_table *current;
|
||||
};
|
||||
|
||||
|
||||
static line_ref *
|
||||
current_line (open_table *file)
|
||||
current_line (open_table * file)
|
||||
{
|
||||
line_ref *entry = ZALLOC (line_ref);
|
||||
*entry = file->pseudo_line;
|
||||
|
@ -66,8 +68,7 @@ current_line (open_table *file)
|
|||
}
|
||||
|
||||
static table_entry *
|
||||
new_table_entry (open_table *file,
|
||||
table_entry_type type)
|
||||
new_table_entry (open_table * file, table_entry_type type)
|
||||
{
|
||||
table_entry *entry;
|
||||
entry = ZALLOC (table_entry);
|
||||
|
@ -78,19 +79,16 @@ new_table_entry (open_table *file,
|
|||
}
|
||||
|
||||
static void
|
||||
set_nr_table_entry_fields (table_entry *entry,
|
||||
int nr_fields)
|
||||
set_nr_table_entry_fields (table_entry *entry, int nr_fields)
|
||||
{
|
||||
entry->field = NZALLOC (char*, nr_fields + 1);
|
||||
entry->field = NZALLOC (char *, nr_fields + 1);
|
||||
entry->nr_fields = nr_fields;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
table_push (table *root,
|
||||
line_ref *line,
|
||||
table_include *includes,
|
||||
const char *file_name)
|
||||
line_ref *line, table_include *includes, const char *file_name)
|
||||
{
|
||||
FILE *ff;
|
||||
open_table *file;
|
||||
|
@ -115,7 +113,8 @@ table_push (table *root,
|
|||
while (1)
|
||||
{
|
||||
/* save the file name */
|
||||
char *dup_name = NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
|
||||
char *dup_name =
|
||||
NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
|
||||
if (dup_name == NULL)
|
||||
{
|
||||
perror (file_name);
|
||||
|
@ -143,7 +142,7 @@ table_push (table *root,
|
|||
exit (1);
|
||||
}
|
||||
include = include->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* determine the size */
|
||||
|
@ -152,7 +151,7 @@ table_push (table *root,
|
|||
fseek (ff, 0, SEEK_SET);
|
||||
|
||||
/* allocate this much memory */
|
||||
file->buffer = (char*) zalloc (file->size + 1);
|
||||
file->buffer = (char *) zalloc (file->size + 1);
|
||||
if (file->buffer == NULL)
|
||||
{
|
||||
perror (file_name);
|
||||
|
@ -161,15 +160,16 @@ table_push (table *root,
|
|||
file->pos = file->buffer;
|
||||
|
||||
/* read it all in */
|
||||
if (fread (file->buffer, 1, file->size, ff) < file->size) {
|
||||
perror (file_name);
|
||||
exit (1);
|
||||
}
|
||||
if (fread (file->buffer, 1, file->size, ff) < file->size)
|
||||
{
|
||||
perror (file_name);
|
||||
exit (1);
|
||||
}
|
||||
file->buffer[file->size] = '\0';
|
||||
|
||||
/* set the initial line numbering */
|
||||
file->real_line.line_nr = 1; /* specifies current line */
|
||||
file->pseudo_line.line_nr = 1; /* specifies current line */
|
||||
file->real_line.line_nr = 1; /* specifies current line */
|
||||
file->pseudo_line.line_nr = 1; /* specifies current line */
|
||||
|
||||
/* done */
|
||||
fclose (ff);
|
||||
|
@ -197,9 +197,7 @@ skip_spaces (char *chp)
|
|||
{
|
||||
while (1)
|
||||
{
|
||||
if (*chp == '\0'
|
||||
|| *chp == '\n'
|
||||
|| !isspace (*chp))
|
||||
if (*chp == '\0' || *chp == '\n' || !isspace (*chp))
|
||||
return chp;
|
||||
chp++;
|
||||
}
|
||||
|
@ -211,8 +209,7 @@ back_spaces (char *start, char *chp)
|
|||
{
|
||||
while (1)
|
||||
{
|
||||
if (chp <= start
|
||||
|| !isspace (chp[-1]))
|
||||
if (chp <= start || !isspace (chp[-1]))
|
||||
return chp;
|
||||
chp--;
|
||||
}
|
||||
|
@ -223,17 +220,14 @@ skip_digits (char *chp)
|
|||
{
|
||||
while (1)
|
||||
{
|
||||
if (*chp == '\0'
|
||||
|| *chp == '\n'
|
||||
|| !isdigit (*chp))
|
||||
if (*chp == '\0' || *chp == '\n' || !isdigit (*chp))
|
||||
return chp;
|
||||
chp++;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
skip_to_separator (char *chp,
|
||||
char *separators)
|
||||
skip_to_separator (char *chp, char *separators)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
@ -258,14 +252,14 @@ skip_to_null (char *chp)
|
|||
|
||||
|
||||
static char *
|
||||
skip_to_nl (char * chp)
|
||||
skip_to_nl (char *chp)
|
||||
{
|
||||
return skip_to_separator (chp, "\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
next_line (open_table *file)
|
||||
next_line (open_table * file)
|
||||
{
|
||||
file->pos = skip_to_nl (file->pos);
|
||||
if (*file->pos == '0')
|
||||
|
@ -282,7 +276,7 @@ table_read (table *root)
|
|||
{
|
||||
open_table *file = root->current;
|
||||
table_entry *entry = NULL;
|
||||
while(1)
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* end-of-file? */
|
||||
|
@ -301,7 +295,7 @@ table_read (table *root)
|
|||
if (*file->pos == '{')
|
||||
{
|
||||
char *chp;
|
||||
next_line (file); /* discard leading brace */
|
||||
next_line (file); /* discard leading brace */
|
||||
entry = new_table_entry (file, table_code_entry);
|
||||
chp = file->pos;
|
||||
/* determine how many lines are involved - look for <nl> "}" */
|
||||
|
@ -368,7 +362,7 @@ table_read (table *root)
|
|||
if (*chp == '\t')
|
||||
entry->field[line_nr] = chp + 1;
|
||||
else
|
||||
entry->field[line_nr] = ""; /* blank */
|
||||
entry->field[line_nr] = ""; /* blank */
|
||||
chp = skip_to_null (chp) + 1;
|
||||
}
|
||||
}
|
||||
|
@ -389,27 +383,28 @@ table_read (table *root)
|
|||
char *file_name;
|
||||
file->pos = chp;
|
||||
/* parse the number */
|
||||
line_nr = atoi(file->pos) - 1;
|
||||
line_nr = atoi (file->pos) - 1;
|
||||
/* skip to the file name */
|
||||
while (file->pos[0] != '0'
|
||||
&& file->pos[0] != '"'
|
||||
&& file->pos[0] != '\0')
|
||||
&& file->pos[0] != '"' && file->pos[0] != '\0')
|
||||
file->pos++;
|
||||
if (file->pos[0] != '"')
|
||||
error (&file->real_line, "Missing opening quote in cpp directive\n");
|
||||
error (&file->real_line,
|
||||
"Missing opening quote in cpp directive\n");
|
||||
/* parse the file name */
|
||||
file->pos++;
|
||||
file_name = file->pos;
|
||||
while (file->pos[0] != '"'
|
||||
&& file->pos[0] != '\0')
|
||||
while (file->pos[0] != '"' && file->pos[0] != '\0')
|
||||
file->pos++;
|
||||
if (file->pos[0] != '"')
|
||||
error (&file->real_line, "Missing closing quote in cpp directive\n");
|
||||
error (&file->real_line,
|
||||
"Missing closing quote in cpp directive\n");
|
||||
file->pos[0] = '\0';
|
||||
file->pos++;
|
||||
file->pos = skip_to_nl (file->pos);
|
||||
if (file->pos[0] != '\n')
|
||||
error (&file->real_line, "Missing newline in cpp directive\n");
|
||||
error (&file->real_line,
|
||||
"Missing newline in cpp directive\n");
|
||||
file->pseudo_line.file_name = file_name;
|
||||
file->pseudo_line.line_nr = line_nr;
|
||||
next_line (file);
|
||||
|
@ -498,40 +493,35 @@ table_read (table *root)
|
|||
}
|
||||
|
||||
extern void
|
||||
table_print_code (lf *file,
|
||||
table_entry *entry)
|
||||
table_print_code (lf *file, table_entry *entry)
|
||||
{
|
||||
int field_nr;
|
||||
int nr = 0;
|
||||
for (field_nr = 0;
|
||||
field_nr < entry->nr_fields;
|
||||
field_nr++)
|
||||
for (field_nr = 0; field_nr < entry->nr_fields; field_nr++)
|
||||
{
|
||||
char *chp = entry->field[field_nr];
|
||||
int in_bit_field = 0;
|
||||
if (*chp == '#')
|
||||
lf_indent_suppress(file);
|
||||
while (*chp != '\0')
|
||||
lf_indent_suppress (file);
|
||||
while (*chp != '\0')
|
||||
{
|
||||
if (chp[0] == '{'
|
||||
&& !isspace(chp[1])
|
||||
&& chp[1] != '\0')
|
||||
if (chp[0] == '{' && !isspace (chp[1]) && chp[1] != '\0')
|
||||
{
|
||||
in_bit_field = 1;
|
||||
nr += lf_putchr(file, '_');
|
||||
nr += lf_putchr (file, '_');
|
||||
}
|
||||
else if (in_bit_field && chp[0] == ':')
|
||||
{
|
||||
nr += lf_putchr(file, '_');
|
||||
nr += lf_putchr (file, '_');
|
||||
}
|
||||
else if (in_bit_field && *chp == '}')
|
||||
{
|
||||
nr += lf_putchr(file, '_');
|
||||
nr += lf_putchr (file, '_');
|
||||
in_bit_field = 0;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
nr += lf_putchr(file, *chp);
|
||||
nr += lf_putchr (file, *chp);
|
||||
}
|
||||
chp++;
|
||||
}
|
||||
|
@ -541,17 +531,14 @@ table_print_code (lf *file,
|
|||
line.line_nr += field_nr;
|
||||
error (&line, "Bit field brace miss match\n");
|
||||
}
|
||||
nr += lf_putchr(file, '\n');
|
||||
nr += lf_putchr (file, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
dump_line_ref (lf *file,
|
||||
char *prefix,
|
||||
const line_ref *line,
|
||||
char *suffix)
|
||||
dump_line_ref (lf *file, char *prefix, const line_ref *line, char *suffix)
|
||||
{
|
||||
lf_printf (file, "%s(line_ref*) 0x%lx", prefix, (long) line);
|
||||
if (line != NULL)
|
||||
|
@ -570,17 +557,17 @@ table_entry_type_to_str (table_entry_type type)
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case table_code_entry: return "code-entry";
|
||||
case table_colon_entry: return "colon-entry";
|
||||
case table_code_entry:
|
||||
return "code-entry";
|
||||
case table_colon_entry:
|
||||
return "colon-entry";
|
||||
}
|
||||
return "*invalid*";
|
||||
}
|
||||
|
||||
void
|
||||
dump_table_entry(lf *file,
|
||||
char *prefix,
|
||||
const table_entry *entry,
|
||||
char *suffix)
|
||||
dump_table_entry (lf *file,
|
||||
char *prefix, const table_entry *entry, char *suffix)
|
||||
{
|
||||
lf_printf (file, "%s(table_entry*) 0x%lx", prefix, (long) entry);
|
||||
if (entry != NULL)
|
||||
|
@ -604,7 +591,7 @@ dump_table_entry(lf *file,
|
|||
|
||||
#ifdef MAIN
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
table *t;
|
||||
table_entry *entry;
|
||||
|
@ -613,7 +600,7 @@ main(int argc, char **argv)
|
|||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Usage: table <file>\n");
|
||||
printf ("Usage: table <file>\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
@ -625,7 +612,7 @@ main(int argc, char **argv)
|
|||
{
|
||||
char line[10];
|
||||
entry = table_read (t);
|
||||
line_nr ++;
|
||||
line_nr++;
|
||||
sprintf (line, "(%d ", line_nr);
|
||||
dump_table_entry (l, line, entry, ")\n");
|
||||
}
|
||||
|
|
|
@ -64,14 +64,17 @@
|
|||
|
||||
typedef struct _table table;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
table_colon_entry,
|
||||
table_code_entry,
|
||||
} table_entry_type;
|
||||
}
|
||||
table_entry_type;
|
||||
|
||||
|
||||
typedef struct _table_entry table_entry;
|
||||
struct _table_entry {
|
||||
struct _table_entry
|
||||
{
|
||||
table *file;
|
||||
line_ref *line;
|
||||
table_entry_type type;
|
||||
|
@ -82,7 +85,8 @@ struct _table_entry {
|
|||
/* 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 {
|
||||
struct _table_include
|
||||
{
|
||||
char *dir;
|
||||
table_include *next;
|
||||
};
|
||||
|
@ -91,68 +95,47 @@ struct _table_include {
|
|||
/* Open/read a table file. Since the file is read once during open
|
||||
(and then closed immediatly) there is no close method. */
|
||||
|
||||
extern table *table_open
|
||||
(const char *file_name);
|
||||
extern table *table_open (const char *file_name);
|
||||
|
||||
extern table_entry *table_read
|
||||
(table *file);
|
||||
extern table_entry *table_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,
|
||||
line_ref *line,
|
||||
table_include *search,
|
||||
const char *file_name);
|
||||
(table *file, line_ref *line, table_include *search, const char *file_name);
|
||||
|
||||
|
||||
/* Expand the specified field_nr using the internal expansion table.
|
||||
A field is only expanded when explicitly specified. */
|
||||
|
||||
extern void table_expand_field
|
||||
(table_entry *entry,
|
||||
int field_nr);
|
||||
extern void table_expand_field (table_entry *entry, int field_nr);
|
||||
|
||||
|
||||
/* Given a code entry, write the code to FILE. Since any
|
||||
leading/trailing braces were striped as part of the read, they are
|
||||
not written. */
|
||||
|
||||
extern void table_print_code
|
||||
(lf *file,
|
||||
table_entry *entry);
|
||||
extern void table_print_code (lf *file, table_entry *entry);
|
||||
|
||||
|
||||
/* Debugging */
|
||||
|
||||
extern void dump_line_ref
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
const line_ref *line,
|
||||
char *suffix);
|
||||
(lf *file, char *prefix, const line_ref *line, char *suffix);
|
||||
|
||||
extern void dump_table_entry
|
||||
(lf *file,
|
||||
char *prefix,
|
||||
const table_entry *entry,
|
||||
char *suffix);
|
||||
(lf *file, char *prefix, const table_entry *entry, char *suffix);
|
||||
|
||||
|
||||
|
||||
/* Utilities for skipping around text */
|
||||
|
||||
extern char *skip_digits
|
||||
(char *chp);
|
||||
extern char *skip_digits (char *chp);
|
||||
|
||||
extern char *skip_spaces
|
||||
(char *chp);
|
||||
extern char *skip_spaces (char *chp);
|
||||
|
||||
extern char *skip_to_separator
|
||||
(char *chp,
|
||||
char *separators);
|
||||
extern char *skip_to_separator (char *chp, char *separators);
|
||||
|
||||
extern char *back_spaces
|
||||
(char *start,
|
||||
char *chp);
|
||||
extern char *back_spaces (char *start, char *chp);
|
||||
|
|
Loading…
Reference in New Issue