📄 gen-icache.c
字号:
? declare_variables : what_to_declare), what_to_do, "default in icache"); /* any thing else ... */ } } lf_print__internal_reference(file); if ((code & generate_with_insn_in_icache)) { lf_printf(file, "\n"); print_icache_extraction(file, instruction, "insn", "instruction_word", "instruction", NULL, /* origin */ NULL, 0, /* file_name & line_nr */ NULL, NULL, what_to_declare, what_to_do, NULL); }}typedef struct _icache_tree icache_tree;struct _icache_tree { char *name; icache_tree *next; icache_tree *children;};static icache_tree *icache_tree_insert(icache_tree *tree, char *name){ icache_tree *new_tree; /* find it */ icache_tree **ptr_to_cur_tree = &tree->children; icache_tree *cur_tree = *ptr_to_cur_tree; while (cur_tree != NULL && strcmp(cur_tree->name, name) < 0) { ptr_to_cur_tree = &cur_tree->next; cur_tree = *ptr_to_cur_tree; } ASSERT(cur_tree == NULL || strcmp(cur_tree->name, name) >= 0); /* already in the tree */ if (cur_tree != NULL && strcmp(cur_tree->name, name) == 0) return cur_tree; /* missing, insert it */ ASSERT(cur_tree == NULL || strcmp(cur_tree->name, name) > 0); new_tree = ZALLOC(icache_tree); new_tree->name = name; new_tree->next = cur_tree; *ptr_to_cur_tree = new_tree; return new_tree;}static icache_tree *insn_table_cache_fields(insn_table *table){ icache_tree *tree = ZALLOC(icache_tree); insn *instruction; for (instruction = table->insns; instruction != NULL; instruction = instruction->next) { insn_field *field; icache_tree *form = icache_tree_insert(tree, instruction->file_entry->fields[insn_form]); for (field = instruction->fields->first; field != NULL; field = field->next) { if (field->is_string) icache_tree_insert(form, field->val_string); } } return tree;}extern voidprint_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");}static voidprint_icache_function(lf *file, insn *instruction, insn_bits *expanded_bits, opcode_field *opcodes, cache_table *cache_rules){ int indent; /* generate code to enter decoded instruction into the icache */ lf_printf(file, "\n"); lf_print_function_type(file, ICACHE_FUNCTION_TYPE, "EXTERN_ICACHE", "\n"); indent = print_function_name(file, instruction->file_entry->fields[insn_name], expanded_bits, function_name_prefix_icache); lf_indent(file, +indent); lf_printf(file, "(%s)\n", ICACHE_FUNCTION_FORMAL); lf_indent(file, -indent); /* function header */ lf_printf(file, "{\n"); lf_indent(file, +2); print_my_defines(file, expanded_bits, instruction->file_entry); print_itrace(file, instruction->file_entry, 1/*putting-value-in-cache*/); print_idecode_validate(file, instruction, opcodes); lf_printf(file, "\n"); lf_printf(file, "{\n"); lf_indent(file, +2); if ((code & generate_with_semantic_icache)) lf_printf(file, "unsigned_word nia;\n"); print_icache_body(file, instruction, expanded_bits, cache_rules, ((code & generate_with_direct_access) ? define_variables : declare_variables), ((code & generate_with_semantic_icache) ? both_values_and_icache : put_values_in_icache)); lf_printf(file, "\n"); lf_printf(file, "cache_entry->address = cia;\n"); lf_printf(file, "cache_entry->semantic = "); print_function_name(file, instruction->file_entry->fields[insn_name], expanded_bits, function_name_prefix_semantics); lf_printf(file, ";\n"); lf_printf(file, "\n"); if ((code & generate_with_semantic_icache)) { lf_printf(file, "/* semantic routine */\n"); print_semantic_body(file, instruction, expanded_bits, opcodes); lf_printf(file, "return nia;\n"); } if (!(code & generate_with_semantic_icache)) { lf_printf(file, "/* return the function proper */\n"); lf_printf(file, "return "); print_function_name(file, instruction->file_entry->fields[insn_name], expanded_bits, function_name_prefix_semantics); lf_printf(file, ";\n"); } if ((code & generate_with_direct_access)) print_icache_body(file, instruction, expanded_bits, cache_rules, undef_variables, ((code & generate_with_semantic_icache) ? both_values_and_icache : put_values_in_icache)); lf_indent(file, -2); lf_printf(file, "}\n"); lf_indent(file, -2); lf_printf(file, "}\n");}voidprint_icache_definition(insn_table *entry, lf *file, void *data, insn *instruction, int depth){ cache_table *cache_rules = (cache_table*)data; if (generate_expanded_instructions) { ASSERT(entry->nr_insn == 1 && entry->opcode == NULL && entry->parent != NULL && entry->parent->opcode != NULL); ASSERT(entry->nr_insn == 1 && entry->opcode == NULL && entry->parent != NULL && entry->parent->opcode != NULL && entry->parent->opcode_rule != NULL); print_icache_function(file, entry->insns, entry->expanded_bits, entry->opcode, cache_rules); } else { print_icache_function(file, instruction, NULL, NULL, cache_rules); }}voidprint_icache_internal_function_declaration(insn_table *table, lf *file, void *data, table_entry *function){ ASSERT((code & generate_with_icache) != 0); if (it_is("internal", function->fields[insn_flags])) { lf_printf(file, "\n"); lf_print_function_type(file, ICACHE_FUNCTION_TYPE, "PSIM_INLINE_ICACHE", "\n"); print_function_name(file, function->fields[insn_name], NULL, function_name_prefix_icache); lf_printf(file, "\n(%s);\n", ICACHE_FUNCTION_FORMAL); }}voidprint_icache_internal_function_definition(insn_table *table, lf *file, void *data, table_entry *function){ ASSERT((code & generate_with_icache) != 0); if (it_is("internal", function->fields[insn_flags])) { lf_printf(file, "\n"); lf_print_function_type(file, ICACHE_FUNCTION_TYPE, "PSIM_INLINE_ICACHE", "\n"); print_function_name(file, function->fields[insn_name], NULL, function_name_prefix_icache); lf_printf(file, "\n(%s)\n", ICACHE_FUNCTION_FORMAL); lf_printf(file, "{\n"); lf_indent(file, +2); lf_printf(file, "/* semantic routine */\n"); table_entry_print_cpp_line_nr(file, function); if ((code & generate_with_semantic_icache)) { lf_print__c_code(file, function->annex); 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->fields[insn_name], NULL, function_name_prefix_semantics); lf_printf(file, ";\n"); } lf_print__internal_reference(file); lf_indent(file, -2); lf_printf(file, "}\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -