void print_icache_body(lf *file, insn *instruction, insn_bits *expanded_bits, cache_table *cache_rules, icache_decl_type what_to_declare, icache_body_type what_to_do) { insn_field *cur_field; /* extract instruction fields */ lf_printf(file, "/* extraction: %s ", instruction->file_entry->fields[insn_format]); switch (what_to_declare) { case define_variables: lf_printf(file, "#define"); break; case declare_variables: lf_printf(file, "declare"); break; case undef_variables: lf_printf(file, "#undef"); break; } lf_printf(file, " "); switch (what_to_do) { case get_values_from_icache: lf_printf(file, "get-values-from-icache"); break; case put_values_in_icache: lf_printf(file, "put-values-in-icache"); break; case both_values_and_icache: lf_printf(file, "get-values-from-icache|put-values-in-icache"); break; case do_not_use_icache: lf_printf(file, "do-not-use-icache"); break; } lf_printf(file, " */\n"); for (cur_field = instruction->fields->first; cur_field->first < insn_bit_size; cur_field = cur_field->next) { if (cur_field->is_string) { insn_bits *bits; int found_rule = 0; /* find any corresponding value */ for (bits = expanded_bits; bits != NULL; bits = bits->last) { if (bits->field == cur_field) break; } /* try the cache rule table for what to do */ { cache_table *cache_rule; for (cache_rule = cache_rules; cache_rule != NULL; cache_rule = cache_rule->next) { if (strcmp(cur_field->val_string, cache_rule->field_name) == 0) { found_rule = 1; if (cache_rule->type == scratch_value && ((what_to_do & put_values_in_icache) || what_to_do == do_not_use_icache)) print_icache_extraction(file, instruction, cache_rule->derived_name, cache_rule->type_def, cache_rule->expression, cache_rule->field_name, cache_rule->file_entry->file_name, cache_rule->file_entry->line_nr, cur_field, bits, what_to_declare, do_not_use_icache, "icache scratch"); else if (cache_rule->type == compute_value && ((what_to_do & get_values_from_icache) || what_to_do == do_not_use_icache)) print_icache_extraction(file, instruction, cache_rule->derived_name, cache_rule->type_def, cache_rule->expression, cache_rule->field_name, cache_rule->file_entry->file_name, cache_rule->file_entry->line_nr, cur_field, bits, what_to_declare, do_not_use_icache, "semantic compute"); else if (cache_rule->type == cache_value && ((what_to_declare != undef_variables) || !(what_to_do & put_values_in_icache))) print_icache_extraction(file, instruction, cache_rule->derived_name, cache_rule->type_def, cache_rule->expression, cache_rule->field_name, cache_rule->file_entry->file_name, cache_rule->file_entry->line_nr, cur_field, bits, ((what_to_do & put_values_in_icache) ? declare_variables : what_to_declare), what_to_do, "in icache"); } } } /* No rule at all, assume that this is needed in the semantic function (when values are extracted from the icache) and hence must be put into the cache */ if (found_rule == 0 && ((what_to_declare != undef_variables) || !(what_to_do & put_values_in_icache))) print_icache_extraction(file, instruction, cur_field->val_string, NULL, NULL, NULL, /* type, exp, orig */ instruction->file_entry->file_name, instruction->file_entry->line_nr, cur_field, bits, ((what_to_do & put_values_in_icache) ? 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); } }
void print_icache_body (lf *file, insn_entry * instruction, opcode_bits *expanded_bits, cache_entry *cache_rules, icache_decl_type what_to_declare, icache_body_type what_to_do, int nr_prefetched_words) { /* extract instruction fields */ lf_printf (file, "/* Extraction: %s\n", instruction->name); lf_printf (file, " "); switch (what_to_declare) { case define_variables: lf_printf (file, "#define"); break; case declare_variables: lf_printf (file, "declare"); break; case undef_variables: lf_printf (file, "#undef"); break; } lf_printf (file, " "); switch (what_to_do) { case get_values_from_icache: lf_printf (file, "get-values-from-icache"); break; case put_values_in_icache: lf_printf (file, "put-values-in-icache"); break; case both_values_and_icache: lf_printf (file, "get-values-from-icache|put-values-in-icache"); break; case do_not_use_icache: lf_printf (file, "do-not-use-icache"); break; } lf_printf (file, "\n "); print_insn_words (file, instruction); lf_printf (file, " */\n"); /* pass zero - fetch from memory any missing instructions. Some of the instructions will have already been fetched (in the instruction array), others will still need fetching. */ switch (what_to_do) { case get_values_from_icache: break; case put_values_in_icache: case both_values_and_icache: case do_not_use_icache: { int word_nr; switch (what_to_declare) { case undef_variables: break; case define_variables: case declare_variables: for (word_nr = nr_prefetched_words; word_nr < instruction->nr_words; word_nr++) { /* FIXME - should be using print_icache_extraction? */ lf_printf (file, "%sinstruction_word instruction_%d UNUSED = ", options.module.global.prefix.l, word_nr); lf_printf (file, "IMEM%d_IMMED (cia, %d)", options.insn_bit_size, word_nr); lf_printf (file, ";\n"); } } } } /* if putting the instruction words in the cache, define references for them */ if (options.gen.insn_in_icache) { /* FIXME: is the instruction_word type correct? */ print_icache_extraction (file, instruction->format_name, cache_value, "insn", /* name */ "instruction_word", /* type */ "instruction", /* expression */ NULL, /* origin */ NULL, /* line */ 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) { /* Always expand named fields (even if constant), so references are valid. */ 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); }