extern void print_icache_struct(insn_table *instructions, cache_table *cache_rules, lf *file) { icache_tree *tree = insn_table_cache_fields(instructions); lf_printf(file, "\n"); lf_printf(file, "#define WITH_IDECODE_CACHE_SIZE %d\n", (code & generate_with_icache) ? icache_size : 0); lf_printf(file, "\n"); /* create an instruction cache if being used */ if ((code & generate_with_icache)) { icache_tree *form; lf_printf(file, "typedef struct _idecode_cache {\n"); lf_printf(file, " unsigned_word address;\n"); lf_printf(file, " void *semantic;\n"); lf_printf(file, " union {\n"); for (form = tree->children; form != NULL; form = form->next) { icache_tree *field; lf_printf(file, " struct {\n"); if (code & generate_with_insn_in_icache) lf_printf(file, " instruction_word insn;\n"); for (field = form->children; field != NULL; field = field->next) { cache_table *cache_rule; int found_rule = 0; for (cache_rule = cache_rules; cache_rule != NULL; cache_rule = cache_rule->next) { if (strcmp(field->name, cache_rule->field_name) == 0) { found_rule = 1; if (cache_rule->derived_name != NULL) lf_printf(file, " %s %s; /* %s */\n", (cache_rule->type_def == NULL ? "unsigned" : cache_rule->type_def), cache_rule->derived_name, cache_rule->field_name); } } if (!found_rule) lf_printf(file, " unsigned %s;\n", field->name); } lf_printf(file, " } %s;\n", form->name); } lf_printf(file, " } crack;\n"); lf_printf(file, "} idecode_cache;\n"); } 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 idecode_cache;\n"); } lf_printf(file, "\n"); }
extern void 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); { 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) { 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, "} crack;\n"); } 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); } lf_printf (file, "\n"); }