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