diff options
Diffstat (limited to 'sim/ppc/gen.c')
-rw-r--r-- | sim/ppc/gen.c | 506 |
1 files changed, 326 insertions, 180 deletions
diff --git a/sim/ppc/gen.c b/sim/ppc/gen.c index cc46952..b9870ab 100644 --- a/sim/ppc/gen.c +++ b/sim/ppc/gen.c @@ -23,11 +23,7 @@ Instead of using/abusing macro's the semantic code should be parsed and each `cachable' expression replaced with the corresponding - value. - - If not expanding fields, invalid_insn has call to its self this is - a little fatal when semantic_invalid() is being called because an - instruction is invalid */ + value. */ #include <sys/types.h> @@ -52,7 +48,7 @@ /****************************************************************/ -void +static void error (char *msg, ...) { va_list ap; @@ -62,7 +58,7 @@ error (char *msg, ...) exit (1); } -void * +static void * zmalloc(long size) { void *memory = malloc(size); @@ -72,7 +68,7 @@ zmalloc(long size) return memory; } -void +static void dumpf (int indent, char *msg, ...) { va_list ap; @@ -121,10 +117,11 @@ typedef struct _opcode_rules { /* FIXME - this should be loaded from a file */ opcode_rules opcode_table[] = WITH_IDECODE_OPCODE_RULES; +static void dump_opcode_rule(opcode_rules *rule, int indent) { - printf("(opcode_rules*)0x%x\n", rule); + printf("(opcode_rules*)%p\n", rule); dumpf(indent, "(valid %d)\n", rule->valid); ASSERT(rule != NULL); if (rule->valid) { @@ -158,7 +155,7 @@ char insn_local[] = "unsigned_word nia = cia + 4;"; /****************************************************************/ -int +static int bin2i(char *bin, int width) { int i = 0; @@ -171,7 +168,7 @@ bin2i(char *bin, int width) } -int +static int it_is(char *flag, char *flags) { @@ -203,13 +200,16 @@ struct _lf { }; -lf * -lf_open(char *name) +static lf * +lf_open(char *name, + char *real_name) { /* create a file object */ lf *new_lf = zmalloc(sizeof(lf)); ASSERT(new_lf != NULL); - new_lf->file_name = name; + new_lf->file_name = (real_name == NULL + ? name + : real_name); /* attach to stdout if pipe */ if (!strcmp(name, "-")) { @@ -224,7 +224,7 @@ lf_open(char *name) } -void +static void lf_close(lf *file) { if (file->stream != stdout) { @@ -237,7 +237,7 @@ lf_close(lf *file) } -void +static void lf_putchr(lf *file, const char chr) { @@ -254,14 +254,14 @@ lf_putchr(lf *file, putc(chr, file->stream); } -void +static void lf_indent_suppress(lf *file) { file->line_blank = 0; } -void +static void lf_putstr(lf *file, const char *string) { @@ -273,7 +273,7 @@ lf_putstr(lf *file, } } -void +static void do_lf_putunsigned(lf *file, unsigned u) { @@ -284,7 +284,7 @@ do_lf_putunsigned(lf *file, } -void +static void lf_putint(lf *file, int decimal) { @@ -301,7 +301,7 @@ lf_putint(lf *file, ASSERT(0); } -void +static void lf_printf(lf *file, const char *fmt, ...) @@ -318,7 +318,7 @@ lf_printf(lf *file, va_end(ap); } -void +static void lf_print_file_line_nr(lf *file) { #if WITH_LINE_NUMBERS @@ -331,6 +331,7 @@ lf_print_file_line_nr(lf *file) #endif } +static void lf_indent(lf *file, int delta) { file->indent += delta; @@ -363,7 +364,7 @@ struct _file_table_entry { }; -file_table * +static file_table * file_table_open(char *file_name) { int fd; @@ -411,7 +412,7 @@ file_table_open(char *file_name) } -file_table_entry * +static file_table_entry * file_table_read(file_table *file) { int field; @@ -494,11 +495,11 @@ file_table_read(file_table *file) } -void +static void dump_file_table_entry(file_table_entry *entry, int indent) { - printf("(file_table_entry*)0x%x\n", entry); + printf("(file_table_entry*)%p\n", entry); if (entry != NULL) { int field; @@ -548,7 +549,7 @@ struct _insn_fields { unsigned value; }; -insn_field * +static insn_field * insn_field_new() { insn_field *new_field = (insn_field*)zmalloc(sizeof(insn_field)); @@ -556,7 +557,7 @@ insn_field_new() return new_field; } -insn_fields * +static insn_fields * insn_fields_new() { insn_fields *new_fields = (insn_fields*)zmalloc(sizeof(insn_fields)); @@ -565,7 +566,7 @@ insn_fields_new() } -insn_fields * +static insn_fields * parse_insn_format(file_table_entry *entry, char *format) { @@ -600,9 +601,8 @@ parse_insn_format(file_table_entry *entry, /* sanity check */ if (!isdigit(*chp)) { - fprintf(stderr, "%s:%d: missing position field at %s\n", - entry->file_name, entry->line_nr, chp); - break; + error("%s:%d: missing position field at `%s'\n", + entry->file_name, entry->line_nr, chp); } /* break out the bit position */ @@ -613,23 +613,23 @@ parse_insn_format(file_table_entry *entry, if (*chp == '.' && strlen_pos > 0) chp++; else { - fprintf(stderr, "%s:%d: missing field value at %s\n", - entry->file_name, entry->line_nr, chp); + error("%s:%d: missing field value at %s\n", + entry->file_name, entry->line_nr, chp); break; } /* break out the value */ start_val = chp; - while (*start_val == '/' && *chp == '/' - || isdigit(*start_val) && isdigit(*chp) - || isalpha(*start_val) && (isalnum(*chp) || *chp == '_')) + while ((*start_val == '/' && *chp == '/') + || (isdigit(*start_val) && isdigit(*chp)) + || (isalpha(*start_val) && (isalnum(*chp) || *chp == '_'))) chp++; strlen_val = chp - start_val; if (*chp == ',') chp++; else if (*chp != '\0' || strlen_val == 0) { - fprintf(stderr, "%s:%d: missing field terminator at %s\n", - entry->file_name, entry->line_nr, chp); + error("%s:%d: missing field terminator at %s\n", + entry->file_name, entry->line_nr, chp); break; } @@ -706,7 +706,7 @@ typedef enum { } constant_field_types; -int +static int insn_field_is_constant(insn_field *field, opcode_rules *rule) { @@ -738,12 +738,12 @@ insn_field_is_constant(insn_field *field, } -void +static void dump_insn_field(insn_field *field, int indent) { - printf("(insn_field*)0x%x\n", field); + printf("(insn_field*)0x%x\n", (unsigned)field); dumpf(indent, "(first %d)\n", field->first); @@ -767,14 +767,14 @@ dump_insn_field(insn_field *field, } -void +static void dump_insn_fields(insn_fields *fields, int indent) { insn_field *field; int i; - printf("(insn_fields*)0x%x\n", fields); + printf("(insn_fields*)%p\n", fields); dumpf(indent, "(first 0x%x)\n", fields->first); dumpf(indent, "(last 0x%x)\n", fields->last); @@ -800,7 +800,7 @@ struct _opcode_field { opcode_field *parent; }; -opcode_field * +static opcode_field * opcode_field_new() { opcode_field *new_field = (opcode_field*)zmalloc(sizeof(opcode_field)); @@ -810,10 +810,10 @@ opcode_field_new() return new_field; } -void +static void dump_opcode_field(opcode_field *field, int indent, int levels) { - printf("(opcode_field*)0x%x\n", field); + printf("(opcode_field*)%p\n", field); if (levels && field != NULL) { dumpf(indent, "(first %d)\n", field->first); dumpf(indent, "(last %d)\n", field->last); @@ -835,7 +835,7 @@ struct _insn_bits { insn_bits *last; }; -insn_bits * +static insn_bits * insn_bits_new() { insn_bits *new_bits = (insn_bits*)zmalloc(sizeof(insn_bits)); @@ -844,10 +844,10 @@ insn_bits_new() } -void +static void dump_insn_bits(insn_bits *bits, int indent, int levels) { - printf("(insn_bits*)0x%x\n", bits); + printf("(insn_bits*)%p\n", bits); if (levels && bits != NULL) { dumpf(indent, "(value %d)\n", bits->value); @@ -873,12 +873,19 @@ typedef enum { insn_nmemonic, insn_name, insn_comment, - nr_insn_table_fields = file_table_max_fields + nr_insn_table_fields = file_table_max_fields, } insn_table_fields; char *insn_field_name[] = { "format", "form", "flags", "nmemonic", "name", "comments" }; +typedef enum { + function_type = insn_format, + function_name = insn_name, + function_param = insn_comment, +} function_table_fields; + + typedef struct _insn insn; struct _insn { file_table_entry *file_entry; @@ -892,6 +899,7 @@ struct _insn_table { insn_bits *expanded_bits; int nr_insn; insn *insns; + insn *functions; opcode_rules *opcode_rule; opcode_field *opcode; int nr_entries; @@ -902,7 +910,7 @@ struct _insn_table { -insn * +static insn * insn_new() { insn *new_entry = ((insn*) zmalloc(sizeof(insn))); @@ -910,7 +918,7 @@ insn_new() return new_entry; } -insn_table * +static insn_table * insn_table_new() { insn_table *new_table = (insn_table*)zmalloc(sizeof(insn_table)); @@ -919,7 +927,25 @@ insn_table_new() } -void +static void +insn_table_insert_function(insn_table *table, + file_table_entry *file_entry) +{ + insn **ptr_to_cur_function = &table->functions; + + /* create a new function */ + insn *new_function = insn_new(); + new_function->file_entry = file_entry; + + /* append it to the end of the function list */ + while (*ptr_to_cur_function != NULL) { + ptr_to_cur_function = &(*ptr_to_cur_function)->next; + } + *ptr_to_cur_function = new_function; +} + + +static void insn_table_insert_insn(insn_table *table, file_table_entry *file_entry, insn_fields *fields) @@ -946,7 +972,7 @@ insn_table_insert_insn(insn_table *table, } -opcode_field * +static opcode_field * insn_table_find_opcode_field(insn *insns, opcode_rules *rule, int string_only) @@ -1047,7 +1073,7 @@ insn_table_find_opcode_field(insn *insns, } -void +static void insn_table_insert_expanded(insn_table *table, insn *old_insn, int new_opcode_nr, @@ -1081,7 +1107,7 @@ insn_table_insert_expanded(insn_table *table, old_insn->fields); } -void +static void insn_table_expand_opcode(insn_table *table, insn *instruction, int field_nr, @@ -1124,6 +1150,7 @@ insn_table_expand_opcode(insn_table *table, } } +static void insn_table_insert_expanding(insn_table *table, insn *entry) { @@ -1135,7 +1162,7 @@ insn_table_insert_expanding(insn_table *table, } -void +static void insn_table_expand_insns(insn_table *table) { @@ -1196,7 +1223,7 @@ insn_table_expand_insns(insn_table *table) -insn_table * +static insn_table * insn_table_load_insns(char *file_name) { file_table *file = file_table_open(file_name); @@ -1204,25 +1231,33 @@ insn_table_load_insns(char *file_name) file_table_entry *file_entry; table->opcode_rule = opcode_table; - while (file_entry = file_table_read(file)) { - insn_fields *fields; - /* skip instructions that aren't relevant to the mode */ - if (it_is("64", file_entry->fields[insn_flags]) && !WITH_64BIT_TARGET - || it_is("32", file_entry->fields[insn_flags]) && WITH_64BIT_TARGET) - continue; - /* create/insert the new instruction */ - fields = parse_insn_format(file_entry, file_entry->fields[insn_format]); - insn_table_insert_insn(table, file_entry, fields); + while ((file_entry = file_table_read(file)) != NULL) { + if (it_is("function", file_entry->fields[insn_flags])) { + insn_table_insert_function(table, file_entry); + } + else { + insn_fields *fields; + /* skip instructions that aren't relevant to the mode */ + if ((it_is("64", file_entry->fields[insn_flags]) + && WITH_TARGET_WORD_BITSIZE != 64) + || (it_is("32", file_entry->fields[insn_flags]) + && WITH_TARGET_WORD_BITSIZE != 32) + || (it_is("f", file_entry->fields[insn_flags]) + && WITH_FLOATING_POINT == SOFT_FLOATING_POINT)) + continue; + /* create/insert the new instruction */ + fields = parse_insn_format(file_entry, file_entry->fields[insn_format]); + insn_table_insert_insn(table, file_entry, fields); + } } - return table; } -void +static void dump_insn(insn *entry, int indent, int levels) { - printf("(insn*)0x%x\n", entry); + printf("(insn*)%p\n", entry); if (levels && entry != NULL) { @@ -1243,12 +1278,12 @@ dump_insn(insn *entry, int indent, int levels) } -void +static void dump_insn_table(insn_table *table, int indent, int levels) { - printf("(insn_table*)0x%x\n", table); + printf("(insn_table*)%p\n", table); if (levels && table != NULL) { insn *entry; @@ -1293,7 +1328,7 @@ dump_insn_table(insn_table *table, /****************************************************************/ -void +static void lf_print_copyleft(lf *file) { lf_putstr(file, "\ @@ -1326,7 +1361,7 @@ lf_print_copyleft(lf *file) } -void +static void lf_print_c_line_nr(lf *file, file_table_entry *entry) { #if WITH_LINE_NUMBERS @@ -1340,7 +1375,7 @@ lf_print_c_line_nr(lf *file, file_table_entry *entry) } -void +static void lf_print_c_code(lf *file, char *code) { char *chp = code; @@ -1378,7 +1413,7 @@ lf_print_c_code(lf *file, char *code) } -void +static void lf_print_binary(lf *file, int decimal, int width) { int bit; @@ -1394,7 +1429,7 @@ lf_print_binary(lf *file, int decimal, int width) } -void +static void lf_print_insn_bits(lf *file, insn_bits *bits) { if (bits == NULL) @@ -1410,7 +1445,7 @@ lf_print_insn_bits(lf *file, insn_bits *bits) } } -void +static void lf_print_opcodes(lf *file, insn_table *table) { @@ -1426,7 +1461,7 @@ lf_print_opcodes(lf *file, } } -void +static void lf_print_table_name(lf *file, insn_table *table) { @@ -1442,12 +1477,13 @@ typedef enum { function_name_prefix_none } lf_function_name_prefixes; -void +static void lf_print_function_name(lf *file, - insn *instruction, + char *basename, insn_bits *expanded_bits, lf_function_name_prefixes prefix) { + /* the prefix */ switch (prefix) { case function_name_prefix_semantics: @@ -1463,7 +1499,7 @@ lf_print_function_name(lf *file, /* the function name */ { char *pos; - for (pos = instruction->file_entry->fields[insn_name]; + for (pos = basename; *pos != '\0'; pos++) { switch (*pos) { @@ -1486,7 +1522,7 @@ lf_print_function_name(lf *file, } -void +static void lf_print_idecode_table(lf *file, insn_table *entry) { @@ -1574,7 +1610,7 @@ lf_print_idecode_table(lf *file, } -void +static void lf_print_my_prefix(lf *file, file_table_entry *file_entry) { @@ -1586,7 +1622,7 @@ lf_print_my_prefix(lf *file, } -void +static void lf_print_ptrace(lf *file) { lf_printf(file, "\n"); @@ -1607,7 +1643,7 @@ typedef void padding_handler int opcode_nr); -void +static void insn_table_traverse_tree(insn_table *table, void *data, int depth, @@ -1657,12 +1693,31 @@ insn_table_traverse_tree(insn_table *table, } +typedef void function_handler +(insn_table *table, + void *data, + file_table_entry *function); + +static void +insn_table_traverse_function(insn_table *table, + void *data, + function_handler *leaf) +{ + insn *function; + for (function = table->functions; + function != NULL; + function = function->next) { + leaf(table, data, function->file_entry); + } +} + + typedef void insn_handler (insn_table *table, void *data, insn *instruction); -void +static void insn_table_traverse_insn(insn_table *table, void *data, insn_handler *leaf) @@ -1676,7 +1731,7 @@ insn_table_traverse_insn(insn_table *table, } -void +static void update_depth(insn_table *entry, void *data, int depth) @@ -1687,7 +1742,7 @@ update_depth(insn_table *entry, } -int +static int insn_table_depth(insn_table *table) { int depth = 0; @@ -1704,7 +1759,7 @@ insn_table_depth(insn_table *table) /****************************************************************/ -void +static void dump_traverse_start(insn_table *table, void *data, int depth) @@ -1712,7 +1767,7 @@ dump_traverse_start(insn_table *table, dumpf(depth*2, "(%d\n", table->opcode_nr); } -void +static void dump_traverse_leaf(insn_table *entry, void *data, int depth) @@ -1724,7 +1779,7 @@ dump_traverse_leaf(insn_table *entry, entry->insns->file_entry->fields[insn_format]); } -void +static void dump_traverse_end(insn_table *table, void *data, int depth) @@ -1732,7 +1787,7 @@ dump_traverse_end(insn_table *table, dumpf(depth*2, ")\n"); } -void +static void dump_traverse_padding(insn_table *table, void *data, int depth, @@ -1742,7 +1797,7 @@ dump_traverse_padding(insn_table *table, } -void +static void dump_traverse(insn_table *table) { insn_table_traverse_tree(table, NULL, 1, @@ -1756,15 +1811,15 @@ dump_traverse(insn_table *table) /****************************************************************/ -void +static void semantics_h_print_function(lf *file, - insn *instruction, + char *basename, insn_bits *expanded_bits) { lf_printf(file, "\n"); lf_printf(file, "INLINE_SEMANTICS unsigned_word "); lf_print_function_name(file, - instruction, + basename, expanded_bits, function_name_prefix_semantics); lf_printf(file, "\n(%s);\n", @@ -1772,27 +1827,52 @@ semantics_h_print_function(lf *file, } -void +static void semantics_h_leaf(insn_table *entry, void *data, int depth) { lf *file = (lf*)data; ASSERT(entry->nr_insn == 1); - semantics_h_print_function(file, entry->insns, entry->expanded_bits); + semantics_h_print_function(file, + entry->insns->file_entry->fields[insn_name], + entry->expanded_bits); } -void +static void semantics_h_insn(insn_table *entry, void *data, insn *instruction) { lf *file = (lf*)data; - semantics_h_print_function(file, instruction, NULL); + semantics_h_print_function(file, + instruction->file_entry->fields[insn_name], + NULL); +} + +static void +semantics_h_function(insn_table *entry, + void *data, + file_table_entry *function) +{ + lf *file = (lf*)data; + if (function->fields[function_type] == NULL + || function->fields[function_type][0] == '\0') { + semantics_h_print_function(file, + function->fields[function_name], + NULL); + } + else { + lf_printf(file, "\n"); + lf_printf(file, "INLINE_SEMANTICS %s %s\n(%s);\n", + function->fields[function_type], + function->fields[function_name], + function->fields[function_param]); + } } -void +static void gen_semantics_h(insn_table *table, lf *file) { @@ -1807,6 +1887,12 @@ gen_semantics_h(insn_table *table, lf *file) lf_printf(file, "\n"); lf_printf(file, "\n"); + /* output a declaration for all functions */ + insn_table_traverse_function(table, + file, + semantics_h_function); + + /* output a declaration for all instructions */ if (idecode_expand_semantics) insn_table_traverse_tree(table, file, @@ -1834,7 +1920,7 @@ struct _icache_tree { icache_tree *children; }; -icache_tree * +static icache_tree * icache_tree_new() { icache_tree *new_tree = (icache_tree*)zmalloc(sizeof(icache_tree)); @@ -1842,7 +1928,7 @@ icache_tree_new() return new_tree; } -icache_tree * +static icache_tree * icache_tree_insert(icache_tree *tree, char *name) { @@ -1872,7 +1958,7 @@ icache_tree_insert(icache_tree *tree, } -icache_tree * +static icache_tree * insn_table_cache_fields(insn_table *table) { icache_tree *tree = icache_tree_new(); @@ -1896,7 +1982,7 @@ insn_table_cache_fields(insn_table *table) -void +static void gen_icache_h(icache_tree *tree, lf *file) { @@ -1976,7 +2062,7 @@ gen_icache_h(icache_tree *tree, /****************************************************************/ -void +static void lf_print_c_extraction(lf *file, insn *instruction, char *field_name, @@ -2030,7 +2116,7 @@ lf_print_c_extraction(lf *file, } -void +static void lf_print_c_extractions(lf *file, insn *instruction, insn_bits *expanded_bits, @@ -2126,7 +2212,24 @@ lf_print_c_extractions(lf *file, lf_print_file_line_nr(file); } -void + +static void +lf_print_idecode_illegal(lf *file) +{ + switch (idecode_cache) { + case 0: + lf_printf(file, "return semantic_illegal(%s);\n", insn_actual); + break; + case 1: + lf_printf(file, "return semantic_illegal;\n"); + break; + default: + lf_printf(file, "return idecode_illegal(%s);\n", cache_idecode_actual); + } +} + + +static void lf_print_c_validate(lf *file, insn *instruction, opcode_field *opcodes) @@ -2161,30 +2264,21 @@ lf_print_c_validate(lf *file, } /* if any bits not checked by opcode tables, output code to check them */ - if (!it_is("illegal", instruction->file_entry->fields[insn_flags]) - && check_mask) { + if (check_mask) { lf_printf(file, "\n"); lf_printf(file, "/* validate: %s */\n", instruction->file_entry->fields[insn_format]); - lf_printf(file, "if ((instruction & 0x%x) != 0x%x) {\n", + lf_printf(file, "if ((instruction & 0x%x) != 0x%x)\n", check_mask, check_val); - switch (idecode_cache) { - case 0: - lf_printf(file, " return semantic_illegal(%s);\n", insn_actual); - break; - case 1: - lf_printf(file, " return semantic_illegal;\n"); - break; - default: - lf_printf(file, " return idecode_illegal(%s);\n", cache_idecode_actual); - } - lf_printf(file, "}\n"); + lf_indent(file, +2); + lf_print_idecode_illegal(file); + lf_indent(file, -2); } } -void +static void lf_print_c_cracker(lf *file, insn *instruction, insn_bits *expanded_bits, @@ -2219,7 +2313,7 @@ lf_print_c_cracker(lf *file, lf_print_c_line_nr(file, instruction->file_entry); lf_printf(file, "return "); lf_print_function_name(file, - instruction, + instruction->file_entry->fields[insn_name], expanded_bits, function_name_prefix_semantics); lf_printf(file, ";\n"); @@ -2230,7 +2324,7 @@ lf_print_c_cracker(lf *file, } -void +static void lf_print_c_semantic(lf *file, insn *instruction, insn_bits *expanded_bits, @@ -2258,12 +2352,21 @@ lf_print_c_semantic(lf *file, if (idecode_cache < 2) lf_print_c_validate(file, instruction, opcodes); - /* if OEA and a floating point generate a check that fp is enabled */ + /* if floating-point generate checks that a. floating point hardware + exists and b. floating point is enabled */ if (it_is("f", instruction->file_entry->fields[insn_flags])) { lf_printf(file, "\n"); - lf_printf(file, "/* verify FP is enabled */\n"); + lf_printf(file, "/* verify: FP hardware exists */\n"); + lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n"); + lf_indent(file, +2); + lf_print_idecode_illegal(file); + lf_indent(file, -2); + lf_printf(file, "\n"); + lf_printf(file, "/* verify: FP is enabled */\n"); lf_printf(file, "if (!IS_FP_AVAILABLE(processor))\n"); - lf_printf(file, " floating_point_unavailable_interrupt(processor, cia);\n"); + lf_indent(file, +2); + lf_printf(file, "floating_point_unavailable_interrupt(processor, cia);\n"); + lf_indent(file, -2); } /* generate the code (or at least something */ @@ -2282,8 +2385,9 @@ lf_print_c_semantic(lf *file, lf_print_file_line_nr(file); } else if (it_is("f", instruction->file_entry->fields[insn_flags])) { - /* unimplemented floating point - call for assistance */ + /* unimplemented floating point instruction - call for assistance */ lf_printf(file, "\n"); + lf_printf(file, "/* unimplemented floating point instruction - call for assistance */\n"); lf_print_c_line_nr(file, instruction->file_entry); lf_putstr(file, "floating_point_assist_interrupt(processor, cia);\n"); lf_print_file_line_nr(file); @@ -2302,25 +2406,32 @@ lf_print_c_semantic(lf *file, lf_printf(file, "}\n"); } -void -lf_print_c_semantic_function(lf *file, - insn *instruction, - insn_bits *expanded_bits, - opcode_field *opcodes) +static void +lf_print_c_semantic_function_header(lf *file, + char *basename, + insn_bits *expanded_bits) { - - /* build the semantic routine to execute the instruction */ - - /* function header */ lf_printf(file, "\n"); lf_printf(file, "INLINE_SEMANTICS unsigned_word\n"); lf_print_function_name(file, - instruction, + basename, expanded_bits, function_name_prefix_semantics); lf_printf(file, "\n(%s)\n", idecode_cache > 1 ? cache_insn_formal : insn_formal); +} +static void +lf_print_c_semantic_function(lf *file, + insn *instruction, + insn_bits *expanded_bits, + opcode_field *opcodes) +{ + + /* build the semantic routine to execute the instruction */ + lf_print_c_semantic_function_header(file, + instruction->file_entry->fields[insn_name], + expanded_bits); lf_print_c_semantic(file, instruction, expanded_bits, @@ -2329,7 +2440,7 @@ lf_print_c_semantic_function(lf *file, } -void +static void semantics_c_leaf(insn_table *entry, void *data, int depth) @@ -2345,7 +2456,7 @@ semantics_c_leaf(insn_table *entry, entry->parent->opcode); } -void +static void semantics_c_insn(insn_table *table, void *data, insn *instruction) @@ -2355,9 +2466,37 @@ semantics_c_insn(insn_table *table, NULL, NULL); } +static void +semantics_c_function(insn_table *table, + void *data, + file_table_entry *function) +{ + lf *file = (lf*)data; + if (function->fields[function_type] == NULL + || function->fields[function_type][0] == '\0') { + lf_print_c_semantic_function_header(file, + function->fields[function_name], + NULL); + } + else { + lf_printf(file, "\n"); + lf_printf(file, "INLINE_SEMANTICS %s\n%s(%s)\n", + function->fields[function_type], + function->fields[function_name], + function->fields[function_param]); + } + lf_print_c_line_nr(file, function); + lf_printf(file, "{\n"); + lf_indent(file, +2); + lf_print_c_code(file, function->annex); + lf_indent(file, -2); + lf_printf(file, "}\n"); + lf_print_file_line_nr(file); +} + -void +static void gen_semantics_c(insn_table *table, lf *file) { lf_print_copyleft(file); @@ -2374,6 +2513,12 @@ gen_semantics_c(insn_table *table, lf *file) lf_printf(file, "#include \"semantics.h\"\n"); lf_printf(file, "\n"); + /* output a definition (c-code) for all functions */ + insn_table_traverse_function(table, + file, + semantics_c_function); + + /* output a definition (c-code) for all instructions */ if (idecode_expand_semantics) insn_table_traverse_tree(table, file, @@ -2394,7 +2539,7 @@ gen_semantics_c(insn_table *table, lf *file) /****************************************************************/ -void +static void gen_idecode_h(insn_table *table, lf *file) { lf_print_copyleft(file); @@ -2406,7 +2551,6 @@ gen_idecode_h(insn_table *table, lf *file) lf_printf(file, "#define INLINE_IDECODE\n"); lf_printf(file, "#endif\n"); lf_printf(file, "\n"); - lf_printf(file, "#include \"idecode_insn.h\"\n"); lf_printf(file, "#include \"idecode_expression.h\"\n"); lf_printf(file, "#include \"idecode_fields.h\"\n"); lf_printf(file, "#include \"idecode_branch.h\"\n"); @@ -2430,7 +2574,7 @@ gen_idecode_h(insn_table *table, lf *file) /****************************************************************/ -void +static void idecode_table_start(insn_table *table, void *data, int depth) @@ -2446,7 +2590,7 @@ idecode_table_start(insn_table *table, } } -void +static void idecode_table_leaf(insn_table *entry, void *data, int depth) @@ -2461,7 +2605,7 @@ idecode_table_leaf(insn_table *entry, /* table leaf entry */ lf_printf(file, " /*%d*/ { 0, 0, ", entry->opcode_nr); lf_print_function_name(file, - entry->insns, + entry->insns->file_entry->fields[insn_name], entry->expanded_bits, (idecode_cache < 2 ? function_name_prefix_semantics @@ -2491,7 +2635,7 @@ idecode_table_leaf(insn_table *entry, } } -void +static void idecode_table_end(insn_table *table, void *data, int depth) @@ -2504,7 +2648,7 @@ idecode_table_end(insn_table *table, } } -void +static void idecode_table_padding(insn_table *table, void *data, int depth, @@ -2528,7 +2672,7 @@ void lf_print_idecode_switch insn_table *table); -void +static void idecode_switch_start(insn_table *table, void *data, int depth) @@ -2542,7 +2686,7 @@ idecode_switch_start(insn_table *table, } -void +static void idecode_switch_leaf(insn_table *entry, void *data, int depth) @@ -2559,7 +2703,7 @@ idecode_switch_leaf(insn_table *entry, /* switch calling leaf */ lf_printf(file, "return "); lf_print_function_name(file, - entry->insns, + entry->insns->file_entry->fields[insn_name], entry->expanded_bits, (idecode_cache < 2 ? function_name_prefix_semantics @@ -2585,22 +2729,17 @@ idecode_switch_leaf(insn_table *entry, lf_indent(file, -2); } + +static void lf_print_idecode_switch_illegal(lf *file) { - switch (idecode_cache) { - case 0: - lf_printf(file, " return semantic_illegal(%s);\n", insn_actual); - break; - case 1: - lf_printf(file, " return semantic_illegal;\n"); - break; - default: - lf_printf(file, " return idecode_illegal(%s);\n", cache_idecode_actual); - } - lf_printf(file, " break;\n"); + lf_indent(file, +2); + lf_print_idecode_illegal(file); + lf_printf(file, "break;\n"); + lf_indent(file, -2); } -void +static void idecode_switch_end(insn_table *table, void *data, int depth) @@ -2616,7 +2755,7 @@ idecode_switch_end(insn_table *table, lf_printf(file, "}\n"); } -void +static void idecode_switch_padding(insn_table *table, void *data, int depth, @@ -2648,7 +2787,7 @@ lf_print_idecode_switch(lf *file, } -void +static void idecode_expand_if_switch(insn_table *table, void *data, int depth) @@ -2674,6 +2813,7 @@ idecode_expand_if_switch(insn_table *table, } +static void lf_print_c_cracker_function(lf *file, insn *instruction, insn_bits *expanded_bits, @@ -2683,7 +2823,7 @@ lf_print_c_cracker_function(lf *file, lf_printf(file, "\n"); lf_printf(file, "STATIC_INLINE_IDECODE idecode_semantic *\n"); lf_print_function_name(file, - instruction, + instruction->file_entry->fields[insn_name], expanded_bits, function_name_prefix_idecode); lf_printf(file, "\n(%s)\n", cache_idecode_formal); @@ -2694,7 +2834,7 @@ lf_print_c_cracker_function(lf *file, opcodes); } -void +static void idecode_crack_leaf(insn_table *entry, void *data, int depth) @@ -2710,7 +2850,7 @@ idecode_crack_leaf(insn_table *entry, entry->opcode); } -void +static void idecode_crack_insn(insn_table *entry, void *data, insn *instruction) @@ -2724,6 +2864,7 @@ idecode_crack_insn(insn_table *entry, /****************************************************************/ +static void gen_idecode_c(insn_table *table, lf *file) { int depth; @@ -2841,7 +2982,7 @@ struct _spreg_table { spreg_table_entry *sprs; }; -spreg_table_entry * +static spreg_table_entry * spreg_table_entry_new() { spreg_table_entry *new_entry = @@ -2850,7 +2991,7 @@ spreg_table_entry_new() return new_entry; } -spreg_table * +static spreg_table * spreg_table_new() { spreg_table *new_table = (spreg_table*)zmalloc(sizeof(spreg_table)); @@ -2858,7 +2999,7 @@ spreg_table_new() return new_table; } -void +static void spreg_table_insert(spreg_table *table, file_table_entry *entry) { /* create a new spr entry */ @@ -2898,7 +3039,7 @@ spreg_table_insert(spreg_table *table, file_table_entry *entry) } -spreg_table * +static spreg_table * spreg_table_load(char *file_name) { file_table *file = file_table_open(file_name); @@ -2906,7 +3047,7 @@ spreg_table_load(char *file_name) { file_table_entry *entry; - while (entry = file_table_read(file)) { + while ((entry = file_table_read(file)) != NULL) { spreg_table_insert(table, entry); } } @@ -2926,7 +3067,7 @@ char *spreg_attributes[] = { 0 }; -void +static void gen_spreg_h(spreg_table *table, lf *file) { spreg_table_entry *entry; @@ -2969,7 +3110,7 @@ gen_spreg_h(spreg_table *table, lf *file) } -void +static void gen_spreg_c(spreg_table *table, lf *file) { spreg_table_entry *entry; @@ -3060,9 +3201,10 @@ main(int argc, insn_table *instructions = NULL; spreg_table *sprs = NULL; icache_tree *cache_fields = NULL; + char *real_file_name = NULL; int ch; - while ((ch = getopt(argc, argv, "i:I:r:S:s:D:d:P:p:C:")) != -1) { + while ((ch = getopt(argc, argv, "n:i:I:r:S:s:D:d:P:p:C:")) != -1) { fprintf(stderr, "\t-%c %s\n", ch, optarg); switch(ch) { case 'I': @@ -3080,9 +3222,12 @@ main(int argc, case 'r': sprs = spreg_table_load(optarg); break; + case 'n': + real_file_name = strdup(optarg); + break; default: { - lf *file = lf_open(optarg); + lf *file = lf_open(optarg, real_file_name); switch (ch) { case 'S': gen_semantics_h(instructions, file); @@ -3108,6 +3253,7 @@ main(int argc, } lf_close(file); } + real_file_name = NULL; } } return 0; |