void print_semantic_body(lf *file, insn *instruction, insn_bits *expanded_bits, opcode_field *opcodes) { print_itrace(file, instruction->file_entry, 0/*put_value_in_cache*/); /* validate the instruction, if a cache this has already been done */ if (!(code & generate_with_icache)) print_idecode_validate(file, instruction, opcodes); /* generate the profiling call - this is delayed until after the instruction has been verified */ lf_printf(file, "\n"); lf_printf(file, "/* monitoring: */\n"); lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE) {\n"); lf_printf(file, " mon_issue("); print_function_name(file, instruction->file_entry->fields[insn_name], NULL, function_name_prefix_itable); lf_printf(file, ", processor, cia);\n"); lf_printf(file, "}\n"); /* generate the code (or at least something */ lf_printf(file, "\n"); lf_printf(file, "/* semantics: */\n"); lf_printf(file, "nia = cia + %d;\n", insn_bit_size / 8); if (instruction->file_entry->annex != NULL) { /* true code */ table_entry_print_cpp_line_nr(file, instruction->file_entry); lf_printf(file, "{\n"); lf_indent(file, +2); lf_print__c_code(file, instruction->file_entry->annex); lf_indent(file, -2); lf_printf(file, "}\n"); lf_print__internal_reference(file); } else if (it_is("nop", instruction->file_entry->fields[insn_flags])) { lf_print__internal_reference(file); } else { /* abort so it is implemented now */ table_entry_print_cpp_line_nr(file, instruction->file_entry); lf_putstr(file, "error(\"%s:%d:0x%08lx:%s unimplemented\\n\",\n"); lf_printf(file, " itable[MY_INDEX].file, itable[MY_INDEX].line_nr, (long)cia, itable[MY_INDEX].name);\n"); lf_print__internal_reference(file); } }
static void print_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"); }
void print_semantic_body (lf *file, insn_entry * instruction, opcode_bits *expanded_bits, insn_opcodes *opcodes) { /* validate the instruction, if a cache this has already been done */ if (!options.gen.icache) { print_idecode_validate (file, instruction, opcodes); } print_itrace (file, instruction, 0 /*put_value_in_cache */ ); /* generate the instruction profile call - this is delayed until after the instruction has been verified. The count macro generated is prefixed by ITABLE_PREFIX */ { lf_printf (file, "\n"); lf_indent_suppress (file); lf_printf (file, "#if defined (%sPROFILE_COUNT_INSN)\n", options.module.itable.prefix.u); lf_printf (file, "%sPROFILE_COUNT_INSN (CPU, CIA, MY_INDEX);\n", options.module.itable.prefix.u); lf_indent_suppress (file); lf_printf (file, "#endif\n"); } /* generate the model call - this is delayed until after the instruction has been verified */ { lf_printf (file, "\n"); lf_indent_suppress (file); lf_printf (file, "#if defined (WITH_MON)\n"); lf_printf (file, "/* monitoring: */\n"); lf_printf (file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n"); lf_printf (file, " mon_issue ("); print_function_name (file, instruction->name, instruction->format_name, NULL, NULL, function_name_prefix_itable); lf_printf (file, ", cpu, cia);\n"); lf_indent_suppress (file); lf_printf (file, "#endif\n"); lf_printf (file, "\n"); } /* determine the new instruction address */ { lf_printf (file, "/* keep the next instruction address handy */\n"); if (options.gen.nia == nia_is_invalid) { lf_printf (file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n", options.module.global.prefix.u); } else { int nr_immeds = instruction->nr_words - 1; if (options.gen.delayed_branch) { if (nr_immeds > 0) { lf_printf (file, "cia.dp += %d * %d; %s\n", options.insn_bit_size / 8, nr_immeds, "/* skip dp immeds */"); } lf_printf (file, "nia.ip = cia.dp; %s\n", "/* instruction pointer */"); lf_printf (file, "nia.dp = cia.dp + %d; %s\n", options.insn_bit_size / 8, "/* delayed-slot pointer */"); } else { if (nr_immeds > 0) { lf_printf (file, "nia = cia + %d * (%d + 1); %s\n", options.insn_bit_size / 8, nr_immeds, "/* skip immeds as well */"); } else { lf_printf (file, "nia = cia + %d;\n", options.insn_bit_size / 8); } } } } /* if conditional, generate code to verify that the instruction should be issued */ if (filter_is_member (instruction->options, "c") || options.gen.conditional_issue) { lf_printf (file, "\n"); lf_printf (file, "/* execute only if conditional passes */\n"); lf_printf (file, "if (IS_CONDITION_OK)\n"); lf_printf (file, " {\n"); lf_indent (file, +4); /* FIXME - need to log a conditional failure */ } /* Architecture expects a REG to be zero. Instead of having to check every read to see if it is refering to that REG just zap it at the start of every instruction */ if (options.gen.zero_reg) { lf_printf (file, "\n"); lf_printf (file, "/* Architecture expects REG to be zero */\n"); lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr); } /* generate the code (or at least something */ lf_printf (file, "\n"); lf_printf (file, "/* semantics: */\n"); if (instruction->code != NULL) { /* true code */ lf_printf (file, "{\n"); lf_indent (file, +2); lf_print__line_ref (file, instruction->code->line); table_print_code (file, instruction->code); lf_indent (file, -2); lf_printf (file, "}\n"); lf_print__internal_ref (file); } else if (filter_is_member (instruction->options, "nop")) { lf_print__internal_ref (file); } else { const char *prefix = "sim_engine_abort ("; int indent = strlen (prefix); /* abort so it is implemented now */ lf_print__line_ref (file, instruction->line); lf_printf (file, "%sSD, CPU, cia, \\\n", prefix); lf_indent (file, +indent); lf_printf (file, "\"%s:%d:0x%%08lx:%%s unimplemented\\n\", \\\n", filter_filename (instruction->line->file_name), instruction->line->line_nr); lf_printf (file, "(long) CIA, \\\n"); lf_printf (file, "%sitable[MY_INDEX].name);\n", options.module.itable.prefix.l); lf_indent (file, -indent); lf_print__internal_ref (file); } /* Close off the conditional execution */ if (filter_is_member (instruction->options, "c") || options.gen.conditional_issue) { lf_indent (file, -4); lf_printf (file, " }\n"); } }
static void print_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"); }