extern void insn_table_expand_insns(insn_table *table) { ASSERT(table->nr_insn >= 1); /* determine a valid opcode */ while (table->opcode_rule) { /* specials only for single instructions */ if ((table->nr_insn > 1 && table->opcode_rule->special_mask == 0 && table->opcode_rule->type == normal_decode_rule) || (table->nr_insn == 1 && table->opcode_rule->special_mask != 0 && ((table->insns->fields->value & table->opcode_rule->special_mask) == table->opcode_rule->special_value)) || (generate_expanded_instructions && table->opcode_rule->special_mask == 0 && table->opcode_rule->type == normal_decode_rule)) table->opcode = insn_table_find_opcode_field(table->insns, table->opcode_rule, table->nr_insn == 1/*string*/ ); if (table->opcode != NULL) break; table->opcode_rule = table->opcode_rule->next; } /* did we find anything */ if (table->opcode == NULL) { return; } ASSERT(table->opcode != NULL); /* back link what we found to its parent */ if (table->parent != NULL) { ASSERT(table->parent->opcode != NULL); table->opcode->parent = table->parent->opcode; } /* expand the raw instructions according to the opcode */ { insn *entry; for (entry = table->insns; entry != NULL; entry = entry->next) { insn_table_insert_expanding(table, entry); } } /* and do the same for the sub entries */ { insn_table *entry; for (entry = table->entries; entry != NULL; entry = entry->sibling) { insn_table_expand_insns(entry); } } }
int main(int argc, char **argv) { filter *filters = NULL; decode_table *decode_rules = NULL; insn_table *instructions = NULL; if (argc != 5) error("Usage: insn <filter> <hi-bit-nr> <decode-table> <insn-table>\n"); filters = new_filter(argv[1], filters); hi_bit_nr = a2i(argv[2]); ASSERT(hi_bit_nr < insn_bit_size); decode_rules = load_decode_table(argv[3], hi_bit_nr); instructions = load_insn_table(argv[4], decode_rules, filters); insn_table_expand_insns(instructions); dump_insn_table(instructions, 0, -1); return 0; }
int main(int argc, char **argv, char **envp) { cache_table *cache_rules = NULL; lf_file_references file_references = lf_include_references; decode_table *decode_rules = NULL; filter *filters = NULL; insn_table *instructions = NULL; table_include *includes = NULL; char *real_file_name = NULL; int is_header = 0; int ch; if (argc == 1) { printf("Usage:\n"); printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n"); printf("Config options:\n"); printf(" -F <filter-out-flag> eg -F 64 to skip 64bit instructions\n"); printf(" -E Expand (duplicate) semantic functions\n"); printf(" -I <icache-size> Generate cracking cache version\n"); printf(" -C Include semantics in cache functions\n"); printf(" -S Include insn (instruction) in icache\n"); printf(" -R Use defines to reference cache vars\n"); printf(" -L Supress line numbering in output files\n"); printf(" -B <bit-size> Set the number of bits in an instruction\n"); printf(" -H <high-bit> Set the nr of the high (msb bit)\n"); printf(" -N <nr-cpus> Specify the max number of cpus the simulation will support\n"); printf(" -J Use jumps instead of function calls\n"); printf(" -T <mechanism> Override the mechanism used to decode an instruction\n"); printf(" using <mechanism> instead of what was specified in the\n"); printf(" decode-rules input file\n"); printf("\n"); printf("Input options (ucase version also dumps loaded table):\n"); printf(" -o <decode-rules>\n"); printf(" -k <cache-rules>\n"); printf(" -i <instruction-table>\n"); printf("\n"); printf("Output options:\n"); printf(" -n <real-name> Specify the real name of for the next output file\n"); printf(" -h Generate header file\n"); printf(" -c <output-file> output icache\n"); printf(" -d <output-file> output idecode\n"); printf(" -m <output-file> output model\n"); printf(" -s <output-file> output schematic\n"); printf(" -t <output-file> output itable\n"); printf(" -f <output-file> output support functions\n"); } while ((ch = getopt(argc, argv, "F:EI:RSLJT:CB:H:N:o:k:i:n:hc:d:m:s:t:f:")) != -1) { fprintf(stderr, "\t-%c %s\n", ch, (optarg ? optarg : "")); switch(ch) { case 'C': code |= generate_with_icache; code |= generate_with_semantic_icache; break; case 'S': code |= generate_with_icache; code |= generate_with_insn_in_icache; break; case 'L': file_references = lf_omit_references; break; case 'E': generate_expanded_instructions = 1; break; case 'G': { int enable_p; char *argp; if (strncmp (optarg, "no-", strlen ("no-")) == 0) { argp = optarg + strlen ("no-"); enable_p = 0; } else if (strncmp (optarg, "!", strlen ("!")) == 0) { argp = optarg + strlen ("no-"); enable_p = 0; } else { argp = optarg; enable_p = 1; } if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0) { switch (argp[strlen ("gen-icache")]) { case '=': icache_size = atoi (argp + strlen ("gen-icache") + 1); code |= generate_with_icache; break; case '\0': code |= generate_with_icache; break; default: error (NULL, "Expecting -Ggen-icache or -Ggen-icache=<N>\n"); } } } case 'I': { table_include **dir = &includes; while ((*dir) != NULL) dir = &(*dir)->next; (*dir) = ZALLOC (table_include); (*dir)->dir = strdup (optarg); } break; case 'N': generate_smp = a2i(optarg); break; case 'R': code |= generate_with_direct_access; break; case 'B': insn_bit_size = a2i(optarg); ASSERT(insn_bit_size > 0 && insn_bit_size <= max_insn_bit_size && (hi_bit_nr == insn_bit_size-1 || hi_bit_nr == 0)); break; case 'H': hi_bit_nr = a2i(optarg); ASSERT(hi_bit_nr == insn_bit_size-1 || hi_bit_nr == 0); break; case 'F': filters = new_filter(optarg, filters); break; case 'J': code &= ~generate_calls; code |= generate_jumps; break; case 'T': force_decode_gen_type(optarg); break; case 'i': if (decode_rules == NULL) { fprintf(stderr, "Must specify decode tables\n"); exit (1); } instructions = load_insn_table(optarg, decode_rules, filters, includes, &cache_rules); fprintf(stderr, "\texpanding ...\n"); insn_table_expand_insns(instructions); break; case 'o': decode_rules = load_decode_table(optarg, hi_bit_nr); break; case 'k': cache_rules = load_cache_table(optarg, hi_bit_nr); break; case 'n': real_file_name = strdup(optarg); break; case 'h': is_header = 1; break; case 's': case 'd': case 'm': case 't': case 'f': case 'c': { lf *file = lf_open(optarg, real_file_name, file_references, (is_header ? lf_is_h : lf_is_c), argv[0]); lf_print__file_start(file); ASSERT(instructions != NULL); switch (ch) { case 's': if(is_header) gen_semantics_h(instructions, file, code); else gen_semantics_c(instructions, cache_rules, file, code); break; case 'd': if (is_header) gen_idecode_h(file, instructions, cache_rules); else gen_idecode_c(file, instructions, cache_rules); break; case 'm': if (is_header) gen_model_h(instructions, file); else gen_model_c(instructions, file); break; case 't': if (is_header) gen_itable_h(instructions, file); else gen_itable_c(instructions, file); break; case 'f': if (is_header) gen_support_h(instructions, file); else gen_support_c(instructions, file); break; case 'c': if (is_header) gen_icache_h(instructions, file, code); else gen_icache_c(instructions, cache_rules, file, code); break; } lf_print__file_finish(file); lf_close(file); is_header = 0; } real_file_name = NULL; break; default: error("unknown option\n"); } } return 0; }