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