Home | History | Annotate | Line # | Download | only in ppc
gen-model.c revision 1.1.1.2
      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.1.1.2  christos 		      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.1.1.2  christos   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.1.1.2  christos   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.1.1.2  christos   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