📄 gen-icache.c
字号:
NULL, NULL, what_to_declare, what_to_do); } lf_printf (file, "\n"); /* pass one - process instruction fields. If there is no cache rule, the default is to enter the field into the cache */ { insn_word_entry *word; for (word = instruction->words; word != NULL; word = word->next) { insn_field_entry *cur_field; for (cur_field = word->first; cur_field->first < options.insn_bit_size; cur_field = cur_field->next) { if (cur_field->type == insn_field_string) { cache_entry *cache_rule; cache_entry_type value_type = cache_value; line_ref *value_line = instruction->line; /* check the cache table to see if it contains a rule overriding the default cache action for an instruction field */ for (cache_rule = cache_rules; 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) { value_type = cache_rule->entry_type; value_line = cache_rule->line; if (value_type == compute_value) { options.warning (cache_rule->line, "instruction field of type `compute' changed to `cache'\n"); cache_rule->entry_type = cache_value; } break; } } /* 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 */ value_line, cur_field, expanded_bits, what_to_declare, what_to_do); } } } } /* pass two - any cache fields not processed above */ { cache_entry *cache_rule; for (cache_rule = cache_rules; 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)) { 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 */ expanded_bits, what_to_declare, what_to_do); } } } lf_print__internal_ref (file);}typedef struct _form_fields form_fields;struct _form_fields{ char *name; filter *fields; form_fields *next;};static form_fields *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; } } return forms;}extern voidprint_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");}static voidprint_icache_function (lf *file, insn_entry * instruction, opcode_bits *expanded_bits, insn_opcodes *opcodes, cache_entry *cache_rules, int nr_prefetched_words){ int indent; /* generate code to enter decoded instruction into the icache */ 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); 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 */ ); print_idecode_validate (file, instruction, opcodes); lf_printf (file, "\n"); lf_printf (file, "{\n"); lf_indent (file, +2); if (options.gen.semantic_icache) lf_printf (file, "unsigned_word nia;\n"); print_icache_body (file, instruction, expanded_bits, cache_rules, (options.gen.direct_access ? define_variables : declare_variables), (options.gen.semantic_icache ? both_values_and_icache : 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); 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, "/* return the function proper */\n"); lf_printf (file, "return "); print_function_name (file, instruction->name, instruction->format_name, NULL, expanded_bits, function_name_prefix_semantics); lf_printf (file, ";\n"); } if (options.gen.direct_access) { print_icache_body (file, instruction, expanded_bits, cache_rules, undef_variables, (options.gen.semantic_icache ? both_values_and_icache : put_values_in_icache), nr_prefetched_words); } lf_indent (file, -2); lf_printf (file, "}\n"); lf_indent (file, -2); lf_printf (file, "}\n");}voidprint_icache_definition (lf *file, insn_entry * insn, opcode_bits *expanded_bits, insn_opcodes *opcodes, cache_entry *cache_rules, int nr_prefetched_words){ print_icache_function (file, insn, expanded_bits, opcodes, cache_rules, nr_prefetched_words);}voidprint_icache_internal_function_declaration (lf *file, function_entry * function, void *data){ ASSERT (options.gen.icache); if (function->is_internal) { lf_printf (file, "\n"); lf_print__function_type_function (file, print_icache_function_type, "INLINE_ICACHE", "\n"); print_function_name (file, function->name, NULL, NULL, NULL, function_name_prefix_icache); lf_printf (file, "\n("); print_icache_function_formal (file, 0); lf_printf (file, ");\n"); }}voidprint_icache_internal_function_definition (lf *file, function_entry * function, void *data){ ASSERT (options.gen.icache); if (function->is_internal) { lf_printf (file, "\n"); lf_print__function_type_function (file, print_icache_function_type, "INLINE_ICACHE", "\n"); print_function_name (file, function->name, NULL, NULL, NULL, function_name_prefix_icache); lf_printf (file, "\n("); print_icache_function_formal (file, 0); lf_printf (file, ")\n"); lf_printf (file, "{\n"); lf_indent (file, +2); lf_printf (file, "/* semantic routine */\n"); if (options.gen.semantic_icache) { 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, "return 0;\n"); } else { lf_printf (file, "return "); print_function_name (file, function->name, NULL, NULL, NULL, function_name_prefix_semantics); lf_printf (file, ";\n"); } lf_print__internal_ref (file); lf_indent (file, -2); lf_printf (file, "}\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -