Home | History | Annotate | Line # | Download | only in ppc
gen-model.c revision 1.5.26.1
      1       1.1  christos /*  This file is part of the program psim.
      2       1.1  christos 
      3       1.1  christos     Copyright (C) 1994-1995, Andrew Cagney <cagney (at) highland.com.au>
      4       1.1  christos 
      5       1.1  christos     This program is free software; you can redistribute it and/or modify
      6       1.1  christos     it under the terms of the GNU General Public License as published by
      7       1.1  christos     the Free Software Foundation; either version 3 of the License, or
      8       1.1  christos     (at your option) any later version.
      9       1.1  christos 
     10       1.1  christos     This program is distributed in the hope that it will be useful,
     11       1.1  christos     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12       1.1  christos     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13       1.1  christos     GNU General Public License for more details.
     14       1.1  christos 
     15       1.1  christos     You should have received a copy of the GNU General Public License
     16       1.1  christos     along with this program; if not, see <http://www.gnu.org/licenses/>.
     17       1.1  christos 
     18       1.1  christos     */
     19       1.1  christos 
     20       1.1  christos 
     21       1.1  christos #include "misc.h"
     22       1.1  christos #include "lf.h"
     23       1.1  christos #include "table.h"
     24       1.1  christos 
     25       1.1  christos #include "filter.h"
     26       1.1  christos 
     27       1.1  christos #include "ld-cache.h"
     28       1.1  christos #include "ld-decode.h"
     29       1.1  christos #include "ld-insn.h"
     30       1.1  christos 
     31       1.1  christos #include "gen-model.h"
     32       1.1  christos 
     33       1.1  christos 
     34       1.1  christos static void
     35       1.1  christos model_c_or_h_data(insn_table *table,
     36       1.1  christos 		  lf *file,
     37       1.1  christos 		  table_entry *data)
     38       1.1  christos {
     39       1.1  christos   if (data->annex) {
     40       1.1  christos     table_entry_print_cpp_line_nr(file, data);
     41       1.1  christos     lf_print__c_code(file, data->annex);
     42       1.1  christos     lf_print__internal_reference(file);
     43       1.1  christos     lf_printf(file, "\n");
     44       1.1  christos   }
     45       1.1  christos }
     46       1.1  christos 
     47       1.1  christos static void
     48       1.1  christos model_c_or_h_function(insn_table *entry,
     49       1.1  christos 		      lf *file,
     50       1.1  christos 		      table_entry *function,
     51  1.5.26.1  perseant 		      const char *prefix)
     52       1.1  christos {
     53       1.1  christos   if (function->fields[function_type] == NULL
     54       1.1  christos       || function->fields[function_type][0] == '\0') {
     55       1.1  christos     error("Model function type not specified for %s", function->fields[function_name]);
     56       1.1  christos   }
     57       1.1  christos   lf_printf(file, "\n");
     58       1.1  christos   lf_print_function_type(file, function->fields[function_type], prefix, " ");
     59       1.1  christos   lf_printf(file, "%s\n(%s);\n",
     60       1.1  christos 	    function->fields[function_name],
     61       1.1  christos 	    function->fields[function_param]);
     62       1.1  christos   lf_printf(file, "\n");
     63       1.1  christos }
     64       1.1  christos 
     65       1.1  christos void
     66       1.1  christos gen_model_h(insn_table *table, lf *file)
     67       1.1  christos {
     68       1.1  christos   insn *insn_ptr;
     69       1.1  christos   model *model_ptr;
     70       1.1  christos   insn *macro;
     71  1.5.26.1  perseant   const char *name;
     72       1.1  christos   int model_create_p = 0;
     73       1.1  christos   int model_init_p = 0;
     74       1.1  christos   int model_halt_p = 0;
     75       1.1  christos   int model_mon_info_p = 0;
     76       1.1  christos   int model_mon_info_free_p = 0;
     77       1.1  christos 
     78       1.1  christos   for(macro = model_macros; macro; macro = macro->next) {
     79       1.1  christos     model_c_or_h_data(table, file, macro->file_entry);
     80       1.1  christos   }
     81       1.1  christos 
     82       1.1  christos   lf_printf(file, "typedef enum _model_enum {\n");
     83       1.1  christos   lf_printf(file, "  MODEL_NONE,\n");
     84       1.1  christos   for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
     85       1.1  christos     lf_printf(file, "  MODEL_%s,\n", model_ptr->name);
     86       1.1  christos   }
     87       1.1  christos   lf_printf(file, "  nr_models\n");
     88       1.1  christos   lf_printf(file, "} model_enum;\n");
     89       1.1  christos   lf_printf(file, "\n");
     90       1.1  christos 
     91       1.1  christos   lf_printf(file, "#define DEFAULT_MODEL MODEL_%s\n", (models) ? models->name : "NONE");
     92       1.1  christos   lf_printf(file, "\n");
     93       1.1  christos 
     94       1.1  christos   lf_printf(file, "typedef struct _model_data model_data;\n");
     95       1.1  christos   lf_printf(file, "typedef struct _model_time model_time;\n");
     96       1.1  christos   lf_printf(file, "\n");
     97       1.1  christos 
     98       1.1  christos   lf_printf(file, "extern model_enum current_model;\n");
     99       1.1  christos   lf_printf(file, "extern const char *model_name[ (int)nr_models ];\n");
    100       1.1  christos   lf_printf(file, "extern const char *const *const model_func_unit_name[ (int)nr_models ];\n");
    101       1.1  christos   lf_printf(file, "extern const model_time *const model_time_mapping[ (int)nr_models ];\n");
    102       1.1  christos   lf_printf(file, "\n");
    103       1.1  christos 
    104       1.1  christos   for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
    105       1.1  christos     model_c_or_h_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
    106       1.1  christos     name = insn_ptr->file_entry->fields[function_name];
    107       1.1  christos     if (strcmp (name, "model_create") == 0)
    108       1.1  christos       model_create_p = 1;
    109       1.1  christos     else if (strcmp (name, "model_init") == 0)
    110       1.1  christos       model_init_p = 1;
    111       1.1  christos     else if (strcmp (name, "model_halt") == 0)
    112       1.1  christos       model_halt_p = 1;
    113       1.1  christos     else if (strcmp (name, "model_mon_info") == 0)
    114       1.1  christos       model_mon_info_p = 1;
    115       1.1  christos     else if (strcmp (name, "model_mon_info_free") == 0)
    116       1.1  christos       model_mon_info_free_p = 1;
    117       1.1  christos   }
    118       1.1  christos 
    119       1.1  christos   if (!model_create_p) {
    120       1.1  christos     lf_print_function_type(file, "model_data *", "INLINE_MODEL", " ");
    121       1.1  christos     lf_printf(file, "model_create\n");
    122       1.1  christos     lf_printf(file, "(cpu *processor);\n");
    123       1.1  christos     lf_printf(file, "\n");
    124       1.1  christos   }
    125       1.1  christos 
    126       1.1  christos   if (!model_init_p) {
    127       1.1  christos     lf_print_function_type(file, "void", "INLINE_MODEL", " ");
    128       1.1  christos     lf_printf(file, "model_init\n");
    129       1.1  christos     lf_printf(file, "(model_data *model_ptr);\n");
    130       1.1  christos     lf_printf(file, "\n");
    131       1.1  christos   }
    132       1.1  christos 
    133       1.1  christos   if (!model_halt_p) {
    134       1.1  christos     lf_print_function_type(file, "void", "INLINE_MODEL", " ");
    135       1.1  christos     lf_printf(file, "model_halt\n");
    136       1.1  christos     lf_printf(file, "(model_data *model_ptr);\n");
    137       1.1  christos     lf_printf(file, "\n");
    138       1.1  christos   }
    139       1.1  christos 
    140       1.1  christos   if (!model_mon_info_p) {
    141       1.1  christos     lf_print_function_type(file, "model_print *", "INLINE_MODEL", " ");
    142       1.1  christos     lf_printf(file, "model_mon_info\n");
    143       1.1  christos     lf_printf(file, "(model_data *model_ptr);\n");
    144       1.1  christos     lf_printf(file, "\n");
    145       1.1  christos   }
    146       1.1  christos 
    147       1.1  christos   if (!model_mon_info_free_p) {
    148       1.1  christos     lf_print_function_type(file, "void", "INLINE_MODEL", " ");
    149       1.1  christos     lf_printf(file, "model_mon_info_free\n");
    150       1.1  christos     lf_printf(file, "(model_data *model_ptr,\n");
    151       1.1  christos     lf_printf(file, " model_print *info_ptr);\n");
    152       1.1  christos     lf_printf(file, "\n");
    153       1.1  christos   }
    154       1.1  christos 
    155       1.1  christos   lf_print_function_type(file, "void", "INLINE_MODEL", " ");
    156       1.1  christos   lf_printf(file, "model_set\n");
    157       1.1  christos   lf_printf(file, "(const char *name);\n");
    158       1.1  christos }
    159       1.1  christos 
    160       1.1  christos /****************************************************************/
    161       1.1  christos 
    162       1.1  christos typedef struct _model_c_passed_data model_c_passed_data;
    163       1.1  christos struct _model_c_passed_data {
    164       1.1  christos   lf *file;
    165       1.1  christos   model *model_ptr;
    166       1.1  christos };
    167       1.1  christos 
    168       1.1  christos static void
    169       1.1  christos model_c_insn(insn_table *entry,
    170       1.1  christos 	     lf *phony_file,
    171       1.1  christos 	     void *data,
    172       1.1  christos 	     insn *instruction,
    173       1.1  christos 	     int depth)
    174       1.1  christos {
    175       1.1  christos   model_c_passed_data *data_ptr = (model_c_passed_data *)data;
    176       1.1  christos   lf *file = data_ptr->file;
    177  1.5.26.1  perseant   const char *current_name = data_ptr->model_ptr->printable_name;
    178       1.1  christos   table_model_entry *model_ptr = instruction->file_entry->model_first;
    179       1.1  christos 
    180       1.1  christos   while (model_ptr) {
    181       1.1  christos     if (model_ptr->fields[insn_model_name] == current_name) {
    182       1.1  christos       lf_printf(file, "  { %-*s },  /* %s */\n",
    183       1.1  christos 		max_model_fields_len,
    184       1.1  christos 		model_ptr->fields[insn_model_fields],
    185       1.1  christos 		instruction->file_entry->fields[insn_name]);
    186       1.1  christos       return;
    187       1.1  christos     }
    188       1.1  christos 
    189       1.1  christos     model_ptr = model_ptr->next;
    190       1.1  christos   }
    191       1.1  christos 
    192       1.1  christos   lf_printf(file, "  { %-*s },  /* %s */\n",
    193       1.1  christos 	    max_model_fields_len,
    194       1.1  christos 	    data_ptr->model_ptr->insn_default,
    195       1.1  christos 	    instruction->file_entry->fields[insn_name]);
    196       1.1  christos }
    197       1.1  christos 
    198       1.1  christos static void
    199       1.1  christos model_c_function(insn_table *table,
    200       1.1  christos 		 lf *file,
    201       1.1  christos 		 table_entry *function,
    202       1.1  christos 		 const char *prefix)
    203       1.1  christos {
    204       1.1  christos   if (function->fields[function_type] == NULL
    205       1.1  christos       || function->fields[function_type][0] == '\0') {
    206       1.1  christos     error("Model function return type not specified for %s", function->fields[function_name]);
    207       1.1  christos   }
    208       1.1  christos   else {
    209       1.1  christos     lf_printf(file, "\n");
    210       1.1  christos     lf_print_function_type(file, function->fields[function_type], prefix, "\n");
    211       1.1  christos     lf_printf(file, "%s(%s)\n",
    212       1.1  christos 	      function->fields[function_name],
    213       1.1  christos 	      function->fields[function_param]);
    214       1.1  christos   }
    215       1.1  christos   table_entry_print_cpp_line_nr(file, function);
    216       1.1  christos   lf_printf(file, "{\n");
    217       1.1  christos   if (function->annex) {
    218       1.1  christos     lf_indent(file, +2);
    219       1.1  christos     lf_print__c_code(file, function->annex);
    220       1.1  christos     lf_indent(file, -2);
    221       1.1  christos   }
    222       1.1  christos   lf_printf(file, "}\n");
    223       1.1  christos   lf_print__internal_reference(file);
    224       1.1  christos   lf_printf(file, "\n");
    225       1.1  christos }
    226       1.1  christos 
    227       1.1  christos void
    228       1.1  christos gen_model_c(insn_table *table, lf *file)
    229       1.1  christos {
    230       1.1  christos   insn *insn_ptr;
    231       1.1  christos   model *model_ptr;
    232  1.5.26.1  perseant   const char *name;
    233       1.1  christos   int model_create_p = 0;
    234       1.1  christos   int model_init_p = 0;
    235       1.1  christos   int model_halt_p = 0;
    236       1.1  christos   int model_mon_info_p = 0;
    237       1.1  christos   int model_mon_info_free_p = 0;
    238       1.1  christos 
    239       1.1  christos   lf_printf(file, "\n");
    240       1.1  christos   lf_printf(file, "#include \"cpu.h\"\n");
    241       1.1  christos   lf_printf(file, "#include \"mon.h\"\n");
    242       1.1  christos   lf_printf(file, "\n");
    243       1.1  christos   lf_printf(file, "#include <stdlib.h>\n");
    244       1.1  christos   lf_printf(file, "\n");
    245       1.1  christos 
    246       1.1  christos   for(insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next) {
    247       1.1  christos     model_c_or_h_data(table, file, insn_ptr->file_entry);
    248       1.1  christos   }
    249       1.1  christos 
    250       1.1  christos   for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
    251       1.1  christos     model_c_or_h_function(table, file, insn_ptr->file_entry, "/*h*/STATIC");
    252       1.1  christos   }
    253       1.1  christos 
    254       1.1  christos   for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
    255       1.1  christos     model_c_or_h_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
    256       1.1  christos   }
    257       1.1  christos 
    258       1.1  christos   for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
    259       1.1  christos     model_c_function(table, file, insn_ptr->file_entry, "/*c*/STATIC");
    260       1.1  christos   }
    261       1.1  christos 
    262       1.1  christos   for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
    263       1.1  christos     model_c_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
    264       1.1  christos   }
    265       1.1  christos 
    266       1.1  christos   for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
    267       1.1  christos     model_c_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
    268       1.1  christos     name = insn_ptr->file_entry->fields[function_name];
    269       1.1  christos     if (strcmp (name, "model_create") == 0)
    270       1.1  christos       model_create_p = 1;
    271       1.1  christos     else if (strcmp (name, "model_init") == 0)
    272       1.1  christos       model_init_p = 1;
    273       1.1  christos     else if (strcmp (name, "model_halt") == 0)
    274       1.1  christos       model_halt_p = 1;
    275       1.1  christos     else if (strcmp (name, "model_mon_info") == 0)
    276       1.1  christos       model_mon_info_p = 1;
    277       1.1  christos     else if (strcmp (name, "model_mon_info_free") == 0)
    278       1.1  christos       model_mon_info_free_p = 1;
    279       1.1  christos   }
    280       1.1  christos 
    281       1.1  christos   if (!model_create_p) {
    282       1.1  christos     lf_print_function_type(file, "model_data *", "INLINE_MODEL", "\n");
    283       1.1  christos     lf_printf(file, "model_create(cpu *processor)\n");
    284       1.1  christos     lf_printf(file, "{\n");
    285       1.1  christos     lf_printf(file, "  return (model_data *)0;\n");
    286       1.1  christos     lf_printf(file, "}\n");
    287       1.1  christos     lf_printf(file, "\n");
    288       1.1  christos   }
    289       1.1  christos 
    290       1.1  christos   if (!model_init_p) {
    291       1.1  christos     lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
    292       1.1  christos     lf_printf(file, "model_init(model_data *model_ptr)\n");
    293       1.1  christos     lf_printf(file, "{\n");
    294       1.1  christos     lf_printf(file, "}\n");
    295       1.1  christos     lf_printf(file, "\n");
    296       1.1  christos   }
    297       1.1  christos 
    298       1.1  christos   if (!model_halt_p) {
    299       1.1  christos     lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
    300       1.1  christos     lf_printf(file, "model_halt(model_data *model_ptr)\n");
    301       1.1  christos     lf_printf(file, "{\n");
    302       1.1  christos     lf_printf(file, "}\n");
    303       1.1  christos     lf_printf(file, "\n");
    304       1.1  christos   }
    305       1.1  christos 
    306       1.1  christos   if (!model_mon_info_p) {
    307       1.1  christos     lf_print_function_type(file, "model_print *", "INLINE_MODEL", "\n");
    308       1.1  christos     lf_printf(file, "model_mon_info(model_data *model_ptr)\n");
    309       1.1  christos     lf_printf(file, "{\n");
    310       1.1  christos     lf_printf(file, "  return (model_print *)0;\n");
    311       1.1  christos     lf_printf(file, "}\n");
    312       1.1  christos     lf_printf(file, "\n");
    313       1.1  christos   }
    314       1.1  christos 
    315       1.1  christos   if (!model_mon_info_free_p) {
    316       1.1  christos     lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
    317       1.1  christos     lf_printf(file, "model_mon_info_free(model_data *model_ptr,\n");
    318       1.1  christos     lf_printf(file, "                    model_print *info_ptr)\n");
    319       1.1  christos     lf_printf(file, "{\n");
    320       1.1  christos     lf_printf(file, "}\n");
    321       1.1  christos     lf_printf(file, "\n");
    322       1.1  christos   }
    323       1.1  christos 
    324       1.1  christos   lf_printf(file, "/* Insn functional unit info */\n");
    325       1.1  christos   for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
    326       1.1  christos     model_c_passed_data data;
    327       1.1  christos 
    328       1.1  christos     lf_printf(file, "static const model_time model_time_%s[] = {\n", model_ptr->name);
    329       1.1  christos     data.file = file;
    330       1.1  christos     data.model_ptr = model_ptr;
    331       1.1  christos     insn_table_traverse_insn(table,
    332       1.1  christos 			     NULL, (void *)&data,
    333       1.1  christos 			     model_c_insn);
    334       1.1  christos 
    335       1.1  christos     lf_printf(file, "};\n");
    336       1.1  christos     lf_printf(file, "\n");
    337       1.1  christos     lf_printf(file, "\f\n");
    338       1.1  christos   }
    339       1.1  christos 
    340       1.1  christos   lf_printf(file, "#ifndef _INLINE_C_\n");
    341       1.1  christos   lf_printf(file, "const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
    342       1.1  christos   lf_printf(file, "  (const model_time *const)0,\n");
    343       1.1  christos   for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
    344       1.1  christos     lf_printf(file, "  model_time_%s,\n", model_ptr->name);
    345       1.1  christos   }
    346       1.1  christos   lf_printf(file, "};\n");
    347       1.1  christos   lf_printf(file, "#endif\n");
    348       1.1  christos   lf_printf(file, "\n");
    349       1.1  christos 
    350       1.1  christos   lf_printf(file, "\f\n");
    351       1.1  christos   lf_printf(file, "/* map model enumeration into printable string */\n");
    352       1.1  christos   lf_printf(file, "#ifndef _INLINE_C_\n");
    353       1.1  christos   lf_printf(file, "const char *model_name[ (int)nr_models ] = {\n");
    354       1.1  christos   lf_printf(file, "  \"NONE\",\n");
    355       1.1  christos   for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
    356       1.1  christos     lf_printf(file, "  \"%s\",\n", model_ptr->printable_name);
    357       1.1  christos   }
    358       1.1  christos   lf_printf(file, "};\n");
    359       1.1  christos   lf_printf(file, "#endif\n");
    360       1.1  christos   lf_printf(file, "\n");
    361       1.1  christos 
    362       1.1  christos   lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
    363       1.1  christos   lf_printf(file, "model_set(const char *name)\n");
    364       1.1  christos   lf_printf(file, "{\n");
    365       1.1  christos   if (models) {
    366       1.1  christos     lf_printf(file, "  model_enum model;\n");
    367       1.1  christos     lf_printf(file, "  for(model = MODEL_%s; model < nr_models; model++) {\n", models->name);
    368       1.1  christos     lf_printf(file, "    if(strcmp(name, model_name[model]) == 0) {\n");
    369       1.1  christos     lf_printf(file, "      current_model = model;\n");
    370       1.1  christos     lf_printf(file, "      return;\n");
    371       1.1  christos     lf_printf(file, "    }\n");
    372       1.1  christos     lf_printf(file, "  }\n");
    373       1.1  christos     lf_printf(file, "\n");
    374       1.1  christos     lf_printf(file, "  error(\"Unknown model '%%s', Models which are known are:%%s\\n\",\n");
    375       1.1  christos     lf_printf(file, "        name,\n");
    376       1.1  christos     lf_printf(file, "        \"");
    377       1.1  christos     for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
    378       1.1  christos       lf_printf(file, "\\n\\t%s", model_ptr->printable_name);
    379       1.1  christos     }
    380       1.1  christos     lf_printf(file, "\");\n");
    381       1.1  christos   } else {
    382       1.1  christos     lf_printf(file, "  error(\"No models are currently known about\");\n");
    383       1.1  christos   }
    384       1.1  christos 
    385       1.1  christos   lf_printf(file, "}\n");
    386       1.1  christos }
    387       1.1  christos 
    388