예제 #1
0
static void
gen_icache_h(insn_table *table,
	     lf *file,
	     igen_code generate)
{
  lf_printf(file, "typedef %s idecode_icache\n(%s);\n",
	    ICACHE_FUNCTION_TYPE,
	    ICACHE_FUNCTION_FORMAL);
  lf_printf(file, "\n");
  if ((code & generate_calls)
      && (code & generate_with_icache)) {
    insn_table_traverse_function(table,
				 file, NULL,
				 print_icache_internal_function_declaration);
    if (generate_expanded_instructions)
      insn_table_traverse_tree(table,
			       file, NULL,
			       1,
			       NULL, /* start */
			       print_icache_declaration, /* leaf */
			       NULL, /* end */
			       NULL); /* padding */
    else
      insn_table_traverse_insn(table,
			       file, NULL,
			       print_icache_declaration);
    
  }
  else {
    lf_print__this_file_is_empty(file);
  }
}
예제 #2
0
static void
gen_semantics_h(insn_table *table,
		lf *file,
		igen_code generate)
{
  lf_printf(file, "typedef %s idecode_semantic\n(%s);\n",
	    SEMANTIC_FUNCTION_TYPE,
	    SEMANTIC_FUNCTION_FORMAL);
  lf_printf(file, "\n");
  if ((code & generate_calls)) {
    lf_printf(file, "extern int option_mpc860c0;\n");
    lf_printf(file, "#define PAGE_SIZE 0x1000\n");
    lf_printf(file, "\n");
    lf_printf(file, "PSIM_EXTERN_SEMANTICS(void)\n");
    lf_printf(file, "semantic_init(device* root);\n");
    lf_printf(file, "\n");
    if (generate_expanded_instructions)
      insn_table_traverse_tree(table,
			       file, NULL,
			       1,
			       NULL, /* start */
			       print_semantic_declaration, /* leaf */
			       NULL, /* end */
			       NULL); /* padding */
    else
      insn_table_traverse_insn(table,
			       file, NULL,
			       print_semantic_declaration);
    
  }
  else {
    lf_print__this_file_is_empty(file);
  }
}
예제 #3
0
static void
gen_semantics_c(insn_table *table,
		cache_table *cache_rules,
		lf *file,
		igen_code generate)
{
  if ((code & generate_calls)) {
    lf_printf(file, "\n");
    lf_printf(file, "#include \"cpu.h\"\n");
    lf_printf(file, "#include \"idecode.h\"\n");
    lf_printf(file, "#include \"semantics.h\"\n");
    lf_printf(file, "#ifdef HAVE_COMMON_FPU\n");
    lf_printf(file, "#include \"sim-inline.h\"\n");
    lf_printf(file, "#include \"sim-fpu.h\"\n");
    lf_printf(file, "#endif\n");
    lf_printf(file, "#include \"support.h\"\n");
    lf_printf(file, "\n");
    lf_printf(file, "int option_mpc860c0 = 0;\n");
    lf_printf(file, "\n");
    lf_printf(file, "PSIM_EXTERN_SEMANTICS(void)\n");
    lf_printf(file, "semantic_init(device* root)\n");
    lf_printf(file, "{\n");
    lf_printf(file, "  option_mpc860c0 = 0;\n");
    lf_printf(file, "  if (tree_find_property(root, \"/options/mpc860c0\"))\n");
    lf_printf(file, "    option_mpc860c0 = tree_find_integer_property(root, \"/options/mpc860c0\");\n");
    lf_printf(file, "    option_mpc860c0 *= 4;   /* convert word count to byte count */\n");
    lf_printf(file, "}\n");
    lf_printf(file, "\n");
    if (generate_expanded_instructions)
      insn_table_traverse_tree(table,
			       file, cache_rules,
			       1,
			       NULL, /* start */
			       print_semantic_definition, /* leaf */
			       NULL, /* end */
			       NULL); /* padding */
    else
      insn_table_traverse_insn(table,
			       file, cache_rules,
			       print_semantic_definition);
    
  }
  else {
    lf_print__this_file_is_empty(file);
  }
}
예제 #4
0
static void
gen_icache_c(insn_table *table,
	     cache_table *cache_rules,
	     lf *file,
	     igen_code generate)
{
  /* output `internal' invalid/floating-point unavailable functions
     where needed */
  if ((code & generate_calls)
      && (code & generate_with_icache)) {
    lf_printf(file, "\n");
    lf_printf(file, "#include \"cpu.h\"\n");
    lf_printf(file, "#include \"idecode.h\"\n");
    lf_printf(file, "#include \"semantics.h\"\n");
    lf_printf(file, "#include \"icache.h\"\n");
    lf_printf(file, "#ifdef HAVE_COMMON_FPU\n");
    lf_printf(file, "#include \"sim-inline.h\"\n");
    lf_printf(file, "#include \"sim-fpu.h\"\n");
    lf_printf(file, "#endif\n");
    lf_printf(file, "#include \"support.h\"\n");
    lf_printf(file, "\n");
    insn_table_traverse_function(table,
				 file, NULL,
				 print_icache_internal_function_definition);
    lf_printf(file, "\n");
    if (generate_expanded_instructions)
      insn_table_traverse_tree(table,
			       file, cache_rules,
			       1,
			       NULL, /* start */
			       print_icache_definition, /* leaf */
			       NULL, /* end */
			       NULL); /* padding */
    else
      insn_table_traverse_insn(table,
			       file, cache_rules,
			       print_icache_definition);
    
  }
  else {
    lf_print__this_file_is_empty(file);
  }
}
예제 #5
0
extern void
gen_itable_c (lf *file, insn_table *isa)
{
  /* leader */
  lf_printf (file, "#include \"%sitable.h\"\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "\n");

  /* FIXME - output model data??? */
  /* FIXME - output assembler data??? */

  /* output the flag, option and processor name tables */
  itable_print_names (file, isa->flags, "flag");
  itable_print_names (file, isa->options, "option");
  itable_print_names (file, isa->model->processors, "processor");

  /* output the table that contains the actual instruction info */
  lf_printf (file, "%sitable_info %sitable[nr_%sitable_entries] = {\n",
	     options.module.itable.prefix.l,
	     options.module.itable.prefix.l, options.module.itable.prefix.l);
  insn_table_traverse_insn (file, isa, itable_c_insn, NULL);

  lf_printf (file, "};\n");
}
예제 #6
0
extern void
gen_itable_h (lf *file, insn_table *isa)
{
  itable_info *info = ZALLOC (itable_info);

  /* output an enumerated type for each instruction */
  lf_printf (file, "typedef enum {\n");
  insn_table_traverse_insn (file, isa, itable_h_insn, info);
  lf_printf (file, "  nr_%sitable_entries,\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "} %sitable_index;\n", options.module.itable.prefix.l);
  lf_printf (file, "\n");

  /* output an enumeration type for each flag */
  itable_print_enum (file, isa->flags, "flag");
  lf_printf (file, "extern const char *%sitable_flag_names[];\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "\n");

  /* output an enumeration of all the possible options */
  itable_print_enum (file, isa->options, "option");
  lf_printf (file, "extern const char *%sitable_option_names[];\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "\n");

  /* output an enumeration of all the processor models */
  itable_print_enum (file, isa->model->processors, "processor");
  lf_printf (file, "extern const char *%sitable_processor_names[];\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "\n");

  /* output the table that contains the actual instruction info */
  lf_printf (file, "typedef struct _%sitable_instruction_info {\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "  %sitable_index nr;\n", options.module.itable.prefix.l);
  lf_printf (file, "  char *format;\n");
  lf_printf (file, "  char *form;\n");
  lf_printf (file, "  char *flags;\n");

  /* nr_itable_* may be zero, so we add 1 to avoid an
     illegal zero-sized array. */
  lf_printf (file, "  char flag[nr_%sitable_flags + 1];\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "  char *options;\n");
  lf_printf (file, "  char option[nr_%sitable_options + 1];\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "  char *processors;\n");
  lf_printf (file, "  char processor[nr_%sitable_processors + 1];\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "  char *name;\n");
  lf_printf (file, "  char *file;\n");
  lf_printf (file, "  int line_nr;\n");
  lf_printf (file, "} %sitable_info;\n", options.module.itable.prefix.l);
  lf_printf (file, "\n");
  lf_printf (file, "extern %sitable_info %sitable[nr_%sitable_entries];\n",
	     options.module.itable.prefix.l, options.module.itable.prefix.l,
	     options.module.itable.prefix.l);
  if (strlen (options.module.itable.prefix.l) > 0)
    {
      lf_indent_suppress (file);
      lf_printf (file, "#define itable %sitable\n",
		 options.module.itable.prefix.l);
    }
  lf_printf (file, "\n");

  /* output an enum defining the max size of various itable members */
  lf_printf (file, "enum {\n");
  lf_printf (file, "  sizeof_%sitable_form = %d,\n",
	     options.module.itable.prefix.l, info->sizeof_form);
  lf_printf (file, "  sizeof_%sitable_name = %d,\n",
	     options.module.itable.prefix.l, info->sizeof_name);
  lf_printf (file, "  sizeof_%sitable_file = %d,\n",
	     options.module.itable.prefix.l, info->sizeof_file);
  lf_printf (file, "};\n");
}
예제 #7
0
void 
gen_model_c(insn_table *table, lf *file)
{
  insn *insn_ptr;
  model *model_ptr;
  char *name;
  int model_create_p = 0;
  int model_init_p = 0;
  int model_halt_p = 0;
  int model_mon_info_p = 0;
  int model_mon_info_free_p = 0;

  lf_printf(file, "\n");
  lf_printf(file, "#include \"cpu.h\"\n");
  lf_printf(file, "#include \"mon.h\"\n");
  lf_printf(file, "\n");
  lf_printf(file, "#ifdef HAVE_STDLIB_H\n");
  lf_printf(file, "#include <stdlib.h>\n");
  lf_printf(file, "#endif\n");
  lf_printf(file, "\n");

  for(insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next) {
    model_c_or_h_data(table, file, insn_ptr->file_entry);
  }

  for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
    model_c_or_h_function(table, file, insn_ptr->file_entry, "/*h*/STATIC");
  }

  for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
    model_c_or_h_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
  }

  for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
    model_c_function(table, file, insn_ptr->file_entry, "/*c*/STATIC");
  }

  for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
    model_c_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
  }

  for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
    model_c_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
    name = insn_ptr->file_entry->fields[function_name];
    if (strcmp (name, "model_create") == 0)
      model_create_p = 1;
    else if (strcmp (name, "model_init") == 0)
      model_init_p = 1;
    else if (strcmp (name, "model_halt") == 0)
      model_halt_p = 1;
    else if (strcmp (name, "model_mon_info") == 0)
      model_mon_info_p = 1;
    else if (strcmp (name, "model_mon_info_free") == 0)
      model_mon_info_free_p = 1;
  }

  if (!model_create_p) {
    lf_print_function_type(file, "model_data *", "INLINE_MODEL", "\n");
    lf_printf(file, "model_create(cpu *processor)\n");
    lf_printf(file, "{\n");
    lf_printf(file, "  return (model_data *)0;\n");
    lf_printf(file, "}\n");
    lf_printf(file, "\n");
  }

  if (!model_init_p) {
    lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
    lf_printf(file, "model_init(model_data *model_ptr)\n");
    lf_printf(file, "{\n");
    lf_printf(file, "}\n");
    lf_printf(file, "\n");
  }

  if (!model_halt_p) {
    lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
    lf_printf(file, "model_halt(model_data *model_ptr)\n");
    lf_printf(file, "{\n");
    lf_printf(file, "}\n");
    lf_printf(file, "\n");
  }

  if (!model_mon_info_p) {
    lf_print_function_type(file, "model_print *", "INLINE_MODEL", "\n");
    lf_printf(file, "model_mon_info(model_data *model_ptr)\n");
    lf_printf(file, "{\n");
    lf_printf(file, "  return (model_print *)0;\n");
    lf_printf(file, "}\n");
    lf_printf(file, "\n");
  }

  if (!model_mon_info_free_p) {
    lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
    lf_printf(file, "model_mon_info_free(model_data *model_ptr,\n");
    lf_printf(file, "                    model_print *info_ptr)\n");
    lf_printf(file, "{\n");
    lf_printf(file, "}\n");
    lf_printf(file, "\n");
  }

  lf_printf(file, "/* Insn functional unit info */\n");
  for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
    model_c_passed_data data;

    lf_printf(file, "static const model_time model_time_%s[] = {\n", model_ptr->name);
    data.file = file;
    data.model_ptr = model_ptr;
    insn_table_traverse_insn(table,
			     NULL, (void *)&data,
			     model_c_insn);

    lf_printf(file, "};\n");
    lf_printf(file, "\n");
    lf_printf(file, "\f\n");
  }

  lf_printf(file, "#ifndef _INLINE_C_\n");
  lf_printf(file, "const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
  lf_printf(file, "  (const model_time *const)0,\n");
  for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
    lf_printf(file, "  model_time_%s,\n", model_ptr->name);
  }
  lf_printf(file, "};\n");
  lf_printf(file, "#endif\n");
  lf_printf(file, "\n");

  lf_printf(file, "\f\n");
  lf_printf(file, "/* map model enumeration into printable string */\n");
  lf_printf(file, "#ifndef _INLINE_C_\n");
  lf_printf(file, "const char *model_name[ (int)nr_models ] = {\n");
  lf_printf(file, "  \"NONE\",\n");
  for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
    lf_printf(file, "  \"%s\",\n", model_ptr->printable_name);
  }
  lf_printf(file, "};\n");
  lf_printf(file, "#endif\n");
  lf_printf(file, "\n");

  lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
  lf_printf(file, "model_set(const char *name)\n");
  lf_printf(file, "{\n");
  if (models) {
    lf_printf(file, "  model_enum model;\n");
    lf_printf(file, "  for(model = MODEL_%s; model < nr_models; model++) {\n", models->name);
    lf_printf(file, "    if(strcmp(name, model_name[model]) == 0) {\n");
    lf_printf(file, "      current_model = model;\n");
    lf_printf(file, "      return;\n");
    lf_printf(file, "    }\n");
    lf_printf(file, "  }\n");
    lf_printf(file, "\n");
    lf_printf(file, "  error(\"Unknown model '%%s', Models which are known are:%%s\\n\",\n");
    lf_printf(file, "        name,\n");
    lf_printf(file, "        \"");
    for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
      lf_printf(file, "\\n\\t%s", model_ptr->printable_name);
    }
    lf_printf(file, "\");\n");
  } else {
    lf_printf(file, "  error(\"No models are currently known about\");\n");
  }

  lf_printf(file, "}\n");
}