1 1.1 christos /* This file is part of the program psim. 2 1.1 christos 3 1.1 christos Copyright (C) 1994-1997, 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.1.2 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.1.2 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.1.3 christos #include <stdlib.h> 21 1.1 christos 22 1.1 christos #include "misc.h" 23 1.1 christos #include "lf.h" 24 1.1.1.4 christos #include "lf-ppc.h" 25 1.1 christos #include "table.h" 26 1.1 christos 27 1.1 christos #include "filter.h" 28 1.1.1.4 christos #include "filter-ppc.h" 29 1.1 christos 30 1.1 christos #include "ld-decode.h" 31 1.1 christos #include "ld-cache.h" 32 1.1 christos #include "ld-insn.h" 33 1.1 christos 34 1.1 christos #include "igen.h" 35 1.1 christos 36 1.1 christos #include "gen-semantics.h" 37 1.1 christos #include "gen-idecode.h" 38 1.1 christos #include "gen-icache.h" 39 1.1 christos 40 1.1 christos 41 1.1 christos 42 1.1 christos static void 43 1.1 christos print_icache_function_header(lf *file, 44 1.1 christos const char *basename, 45 1.1 christos insn_bits *expanded_bits, 46 1.1 christos int is_function_definition) 47 1.1 christos { 48 1.1 christos lf_printf(file, "\n"); 49 1.1.1.4 christos lf_print__function_type(file, ICACHE_FUNCTION_TYPE, "EXTERN_ICACHE", " "); 50 1.1 christos print_function_name(file, 51 1.1 christos basename, 52 1.1 christos expanded_bits, 53 1.1 christos function_name_prefix_icache); 54 1.1 christos lf_printf(file, "\n(%s)", ICACHE_FUNCTION_FORMAL); 55 1.1 christos if (!is_function_definition) 56 1.1 christos lf_printf(file, ";"); 57 1.1 christos lf_printf(file, "\n"); 58 1.1 christos } 59 1.1 christos 60 1.1 christos 61 1.1 christos void 62 1.1 christos print_icache_declaration(insn_table *entry, 63 1.1 christos lf *file, 64 1.1 christos void *data, 65 1.1 christos insn *instruction, 66 1.1 christos int depth) 67 1.1 christos { 68 1.1 christos if (generate_expanded_instructions) { 69 1.1 christos ASSERT(entry->nr_insn == 1); 70 1.1 christos print_icache_function_header(file, 71 1.1 christos entry->insns->file_entry->fields[insn_name], 72 1.1 christos entry->expanded_bits, 73 1.1 christos 0/* is not function definition */); 74 1.1 christos } 75 1.1 christos else { 76 1.1 christos print_icache_function_header(file, 77 1.1 christos instruction->file_entry->fields[insn_name], 78 1.1 christos NULL, 79 1.1 christos 0/* is not function definition */); 80 1.1 christos } 81 1.1 christos } 82 1.1 christos 83 1.1 christos 84 1.1 christos 85 1.1 christos static void 86 1.1 christos print_icache_extraction(lf *file, 87 1.1 christos insn *instruction, 88 1.1 christos const char *entry_name, 89 1.1 christos const char *entry_type, 90 1.1 christos const char *entry_expression, 91 1.1 christos const char *original_name, 92 1.1 christos const char *file_name, 93 1.1 christos int line_nr, 94 1.1 christos insn_field *cur_field, 95 1.1 christos insn_bits *bits, 96 1.1 christos icache_decl_type what_to_declare, 97 1.1 christos icache_body_type what_to_do, 98 1.1 christos const char *reason) 99 1.1 christos { 100 1.1 christos const char *expression; 101 1.1 christos ASSERT(entry_name != NULL); 102 1.1 christos 103 1.1 christos /* Define a storage area for the cache element */ 104 1.1 christos if (what_to_declare == undef_variables) { 105 1.1.1.5 christos /* We've finished with the value - destroy it */ 106 1.1 christos lf_indent_suppress(file); 107 1.1 christos lf_printf(file, "#undef %s\n", entry_name); 108 1.1 christos return; 109 1.1 christos } 110 1.1 christos else if (what_to_declare == define_variables) { 111 1.1 christos lf_indent_suppress(file); 112 1.1 christos lf_printf(file, "#define %s ", entry_name); 113 1.1 christos } 114 1.1 christos else { 115 1.1 christos if (file_name != NULL) 116 1.1.1.4 christos lf_print__external_ref(file, line_nr, file_name); 117 1.1.1.3 christos lf_printf(file, "%s const %s ATTRIBUTE_UNUSED = ", 118 1.1 christos entry_type == NULL ? "unsigned" : entry_type, 119 1.1 christos entry_name); 120 1.1 christos } 121 1.1 christos 122 1.1 christos /* define a value for that storage area as determined by what is in 123 1.1 christos the cache */ 124 1.1 christos if (bits != NULL 125 1.1 christos && strcmp(entry_name, cur_field->val_string) == 0 126 1.1 christos && ((bits->opcode->is_boolean && bits->value == 0) 127 1.1 christos || (!bits->opcode->is_boolean))) { 128 1.1 christos /* The simple field has been made constant (as a result of 129 1.1 christos expanding instructions or similar). Remember that for a 130 1.1 christos boolean field, value is either 0 (implying the required 131 1.1 christos boolean_constant) or nonzero (implying some other value and 132 1.1 christos handled later below) - Define the variable accordingly */ 133 1.1 christos expression = "constant field"; 134 1.1 christos ASSERT(bits->field == cur_field); 135 1.1 christos ASSERT(entry_type == NULL); 136 1.1 christos if (bits->opcode->is_boolean) 137 1.1 christos lf_printf(file, "%d", bits->opcode->boolean_constant); 138 1.1 christos else if (bits->opcode->last < bits->field->last) 139 1.1 christos lf_printf(file, "%d", 140 1.1 christos bits->value << (bits->field->last - bits->opcode->last)); 141 1.1 christos else 142 1.1 christos lf_printf(file, "%d", bits->value); 143 1.1 christos } 144 1.1 christos else if (bits != NULL 145 1.1 christos && original_name != NULL 146 1.1 christos && strncmp(entry_name, 147 1.1 christos original_name, strlen(original_name)) == 0 148 1.1 christos && strncmp(entry_name + strlen(original_name), 149 1.1 christos "_is_", strlen("_is_")) == 0 150 1.1 christos && ((bits->opcode->is_boolean 151 1.1 christos && (atol(entry_name + strlen(original_name) + strlen("_is_")) 152 1.1 christos == bits->opcode->boolean_constant)) 153 1.1 christos || (!bits->opcode->is_boolean))) { 154 1.1 christos expression = "constant compare"; 155 1.1 christos /* An entry, derived from ORIGINAL_NAME, is testing to see of the 156 1.1 christos ORIGINAL_NAME has a specific constant value. That value 157 1.1 christos matching a boolean or constant field */ 158 1.1 christos if (bits->opcode->is_boolean) 159 1.1 christos lf_printf(file, "%d /* %s == %d */", 160 1.1 christos bits->value == 0, 161 1.1 christos original_name, 162 1.1 christos bits->opcode->boolean_constant); 163 1.1 christos else if (bits->opcode->last < bits->field->last) 164 1.1 christos lf_printf(file, "%d /* %s == %d */", 165 1.1 christos (atol(entry_name + strlen(original_name) + strlen("_is_")) 166 1.1 christos == (bits->value << (bits->field->last - bits->opcode->last))), 167 1.1 christos original_name, 168 1.1 christos (bits->value << (bits->field->last - bits->opcode->last))); 169 1.1 christos else 170 1.1 christos lf_printf(file, "%d /* %s == %d */", 171 1.1 christos (atol(entry_name + strlen(original_name) + strlen("_is_")) 172 1.1 christos == bits->value), 173 1.1 christos original_name, 174 1.1 christos bits->value); 175 1.1 christos } 176 1.1 christos else { 177 1.1 christos /* put the field in the local variable, possibly also enter it 178 1.1 christos into the cache */ 179 1.1 christos expression = "extraction"; 180 1.1 christos /* handle the cache */ 181 1.1 christos if ((what_to_do & get_values_from_icache) 182 1.1 christos || (what_to_do & put_values_in_icache)) { 183 1.1 christos lf_printf(file, "cache_entry->crack.%s.%s", 184 1.1 christos instruction->file_entry->fields[insn_form], 185 1.1 christos entry_name); 186 1.1 christos if (what_to_do & put_values_in_icache) /* also put it in the cache? */ 187 1.1 christos lf_printf(file, " = "); 188 1.1 christos } 189 1.1 christos if ((what_to_do & put_values_in_icache) 190 1.1 christos || what_to_do == do_not_use_icache) { 191 1.1 christos if (cur_field != NULL && strcmp(entry_name, cur_field->val_string) == 0) 192 1.1 christos lf_printf(file, "EXTRACTED32(instruction, %d, %d)", 193 1.1 christos i2target(hi_bit_nr, cur_field->first), 194 1.1 christos i2target(hi_bit_nr, cur_field->last)); 195 1.1 christos else if (entry_expression != NULL) 196 1.1 christos lf_printf(file, "%s", entry_expression); 197 1.1 christos else 198 1.1 christos lf_printf(file, "eval_%s", entry_name); 199 1.1 christos } 200 1.1 christos } 201 1.1 christos 202 1.1 christos if (!((what_to_declare == define_variables) 203 1.1 christos || (what_to_declare == undef_variables))) 204 1.1 christos lf_printf(file, ";"); 205 1.1 christos if (reason != NULL) 206 1.1 christos lf_printf(file, " /* %s - %s */", reason, expression); 207 1.1 christos lf_printf(file, "\n"); 208 1.1 christos } 209 1.1 christos 210 1.1 christos 211 1.1 christos void 212 1.1 christos print_icache_body(lf *file, 213 1.1 christos insn *instruction, 214 1.1 christos insn_bits *expanded_bits, 215 1.1 christos cache_table *cache_rules, 216 1.1 christos icache_decl_type what_to_declare, 217 1.1 christos icache_body_type what_to_do) 218 1.1 christos { 219 1.1 christos insn_field *cur_field; 220 1.1 christos 221 1.1 christos /* extract instruction fields */ 222 1.1 christos lf_printf(file, "/* extraction: %s ", 223 1.1 christos instruction->file_entry->fields[insn_format]); 224 1.1 christos switch (what_to_declare) { 225 1.1 christos case define_variables: 226 1.1 christos lf_printf(file, "#define"); 227 1.1 christos break; 228 1.1 christos case declare_variables: 229 1.1 christos lf_printf(file, "declare"); 230 1.1 christos break; 231 1.1 christos case undef_variables: 232 1.1 christos lf_printf(file, "#undef"); 233 1.1 christos break; 234 1.1 christos } 235 1.1 christos lf_printf(file, " "); 236 1.1 christos switch (what_to_do) { 237 1.1 christos case get_values_from_icache: 238 1.1 christos lf_printf(file, "get-values-from-icache"); 239 1.1 christos break; 240 1.1 christos case put_values_in_icache: 241 1.1 christos lf_printf(file, "put-values-in-icache"); 242 1.1 christos break; 243 1.1 christos case both_values_and_icache: 244 1.1 christos lf_printf(file, "get-values-from-icache|put-values-in-icache"); 245 1.1 christos break; 246 1.1 christos case do_not_use_icache: 247 1.1 christos lf_printf(file, "do-not-use-icache"); 248 1.1 christos break; 249 1.1 christos } 250 1.1 christos lf_printf(file, " */\n"); 251 1.1 christos 252 1.1 christos for (cur_field = instruction->fields->first; 253 1.1 christos cur_field->first < insn_bit_size; 254 1.1 christos cur_field = cur_field->next) { 255 1.1 christos if (cur_field->is_string) { 256 1.1 christos insn_bits *bits; 257 1.1 christos int found_rule = 0; 258 1.1 christos /* find any corresponding value */ 259 1.1 christos for (bits = expanded_bits; 260 1.1 christos bits != NULL; 261 1.1 christos bits = bits->last) { 262 1.1 christos if (bits->field == cur_field) 263 1.1 christos break; 264 1.1 christos } 265 1.1 christos /* try the cache rule table for what to do */ 266 1.1 christos { 267 1.1 christos cache_table *cache_rule; 268 1.1 christos for (cache_rule = cache_rules; 269 1.1 christos cache_rule != NULL; 270 1.1 christos cache_rule = cache_rule->next) { 271 1.1 christos if (strcmp(cur_field->val_string, cache_rule->field_name) == 0) { 272 1.1 christos found_rule = 1; 273 1.1 christos if (cache_rule->type == scratch_value 274 1.1 christos && ((what_to_do & put_values_in_icache) 275 1.1 christos || what_to_do == do_not_use_icache)) 276 1.1 christos print_icache_extraction(file, 277 1.1 christos instruction, 278 1.1 christos cache_rule->derived_name, 279 1.1 christos cache_rule->type_def, 280 1.1 christos cache_rule->expression, 281 1.1 christos cache_rule->field_name, 282 1.1 christos cache_rule->file_entry->file_name, 283 1.1 christos cache_rule->file_entry->line_nr, 284 1.1 christos cur_field, 285 1.1 christos bits, 286 1.1 christos what_to_declare, 287 1.1 christos do_not_use_icache, 288 1.1 christos "icache scratch"); 289 1.1 christos else if (cache_rule->type == compute_value 290 1.1 christos && ((what_to_do & get_values_from_icache) 291 1.1 christos || what_to_do == do_not_use_icache)) 292 1.1 christos print_icache_extraction(file, 293 1.1 christos instruction, 294 1.1 christos cache_rule->derived_name, 295 1.1 christos cache_rule->type_def, 296 1.1 christos cache_rule->expression, 297 1.1 christos cache_rule->field_name, 298 1.1 christos cache_rule->file_entry->file_name, 299 1.1 christos cache_rule->file_entry->line_nr, 300 1.1 christos cur_field, 301 1.1 christos bits, 302 1.1 christos what_to_declare, 303 1.1 christos do_not_use_icache, 304 1.1 christos "semantic compute"); 305 1.1 christos else if (cache_rule->type == cache_value 306 1.1 christos && ((what_to_declare != undef_variables) 307 1.1 christos || !(what_to_do & put_values_in_icache))) 308 1.1 christos print_icache_extraction(file, 309 1.1 christos instruction, 310 1.1 christos cache_rule->derived_name, 311 1.1 christos cache_rule->type_def, 312 1.1 christos cache_rule->expression, 313 1.1 christos cache_rule->field_name, 314 1.1 christos cache_rule->file_entry->file_name, 315 1.1 christos cache_rule->file_entry->line_nr, 316 1.1 christos cur_field, 317 1.1 christos bits, 318 1.1 christos ((what_to_do & put_values_in_icache) 319 1.1 christos ? declare_variables 320 1.1 christos : what_to_declare), 321 1.1 christos what_to_do, 322 1.1 christos "in icache"); 323 1.1 christos } 324 1.1 christos } 325 1.1 christos } 326 1.1 christos /* No rule at all, assume that this is needed in the semantic 327 1.1 christos function (when values are extracted from the icache) and 328 1.1 christos hence must be put into the cache */ 329 1.1 christos if (found_rule == 0 330 1.1 christos && ((what_to_declare != undef_variables) 331 1.1 christos || !(what_to_do & put_values_in_icache))) 332 1.1 christos print_icache_extraction(file, 333 1.1 christos instruction, 334 1.1 christos cur_field->val_string, 335 1.1 christos NULL, NULL, NULL, /* type, exp, orig */ 336 1.1 christos instruction->file_entry->file_name, 337 1.1 christos instruction->file_entry->line_nr, 338 1.1 christos cur_field, 339 1.1 christos bits, 340 1.1 christos ((what_to_do & put_values_in_icache) 341 1.1 christos ? declare_variables 342 1.1 christos : what_to_declare), 343 1.1 christos what_to_do, 344 1.1 christos "default in icache"); 345 1.1 christos /* any thing else ... */ 346 1.1 christos } 347 1.1 christos } 348 1.1 christos 349 1.1.1.4 christos lf_print__internal_ref(file); 350 1.1 christos 351 1.1 christos if ((code & generate_with_insn_in_icache)) { 352 1.1 christos lf_printf(file, "\n"); 353 1.1 christos print_icache_extraction(file, 354 1.1 christos instruction, 355 1.1 christos "insn", 356 1.1 christos "instruction_word", 357 1.1 christos "instruction", 358 1.1 christos NULL, /* origin */ 359 1.1 christos NULL, 0, /* file_name & line_nr */ 360 1.1 christos NULL, NULL, 361 1.1 christos what_to_declare, 362 1.1 christos what_to_do, 363 1.1 christos NULL); 364 1.1 christos } 365 1.1 christos } 366 1.1 christos 367 1.1 christos 368 1.1 christos 369 1.1 christos typedef struct _icache_tree icache_tree; 370 1.1 christos struct _icache_tree { 371 1.1.1.3 christos const char *name; 372 1.1 christos icache_tree *next; 373 1.1 christos icache_tree *children; 374 1.1 christos }; 375 1.1 christos 376 1.1 christos static icache_tree * 377 1.1 christos icache_tree_insert(icache_tree *tree, 378 1.1.1.3 christos const char *name) 379 1.1 christos { 380 1.1 christos icache_tree *new_tree; 381 1.1 christos /* find it */ 382 1.1 christos icache_tree **ptr_to_cur_tree = &tree->children; 383 1.1 christos icache_tree *cur_tree = *ptr_to_cur_tree; 384 1.1 christos while (cur_tree != NULL 385 1.1 christos && strcmp(cur_tree->name, name) < 0) { 386 1.1 christos ptr_to_cur_tree = &cur_tree->next; 387 1.1 christos cur_tree = *ptr_to_cur_tree; 388 1.1 christos } 389 1.1 christos ASSERT(cur_tree == NULL 390 1.1 christos || strcmp(cur_tree->name, name) >= 0); 391 1.1 christos /* already in the tree */ 392 1.1 christos if (cur_tree != NULL 393 1.1 christos && strcmp(cur_tree->name, name) == 0) 394 1.1 christos return cur_tree; 395 1.1 christos /* missing, insert it */ 396 1.1 christos ASSERT(cur_tree == NULL 397 1.1 christos || strcmp(cur_tree->name, name) > 0); 398 1.1 christos new_tree = ZALLOC(icache_tree); 399 1.1 christos new_tree->name = name; 400 1.1 christos new_tree->next = cur_tree; 401 1.1 christos *ptr_to_cur_tree = new_tree; 402 1.1 christos return new_tree; 403 1.1 christos } 404 1.1 christos 405 1.1 christos 406 1.1 christos static icache_tree * 407 1.1 christos insn_table_cache_fields(insn_table *table) 408 1.1 christos { 409 1.1 christos icache_tree *tree = ZALLOC(icache_tree); 410 1.1 christos insn *instruction; 411 1.1 christos for (instruction = table->insns; 412 1.1 christos instruction != NULL; 413 1.1 christos instruction = instruction->next) { 414 1.1 christos insn_field *field; 415 1.1 christos icache_tree *form = 416 1.1 christos icache_tree_insert(tree, 417 1.1 christos instruction->file_entry->fields[insn_form]); 418 1.1 christos for (field = instruction->fields->first; 419 1.1 christos field != NULL; 420 1.1 christos field = field->next) { 421 1.1 christos if (field->is_string) 422 1.1 christos icache_tree_insert(form, field->val_string); 423 1.1 christos } 424 1.1 christos } 425 1.1 christos return tree; 426 1.1 christos } 427 1.1 christos 428 1.1 christos 429 1.1 christos 430 1.1 christos extern void 431 1.1 christos print_icache_struct(insn_table *instructions, 432 1.1 christos cache_table *cache_rules, 433 1.1 christos lf *file) 434 1.1 christos { 435 1.1 christos icache_tree *tree = insn_table_cache_fields(instructions); 436 1.1 christos 437 1.1 christos lf_printf(file, "\n"); 438 1.1 christos lf_printf(file, "#define WITH_IDECODE_CACHE_SIZE %d\n", 439 1.1 christos (code & generate_with_icache) ? icache_size : 0); 440 1.1 christos lf_printf(file, "\n"); 441 1.1 christos 442 1.1 christos /* create an instruction cache if being used */ 443 1.1 christos if ((code & generate_with_icache)) { 444 1.1 christos icache_tree *form; 445 1.1 christos lf_printf(file, "typedef struct _idecode_cache {\n"); 446 1.1 christos lf_printf(file, " unsigned_word address;\n"); 447 1.1 christos lf_printf(file, " void *semantic;\n"); 448 1.1 christos lf_printf(file, " union {\n"); 449 1.1 christos for (form = tree->children; 450 1.1 christos form != NULL; 451 1.1 christos form = form->next) { 452 1.1 christos icache_tree *field; 453 1.1 christos lf_printf(file, " struct {\n"); 454 1.1 christos if (code & generate_with_insn_in_icache) 455 1.1 christos lf_printf(file, " instruction_word insn;\n"); 456 1.1 christos for (field = form->children; 457 1.1 christos field != NULL; 458 1.1 christos field = field->next) { 459 1.1 christos cache_table *cache_rule; 460 1.1 christos int found_rule = 0; 461 1.1 christos for (cache_rule = cache_rules; 462 1.1 christos cache_rule != NULL; 463 1.1 christos cache_rule = cache_rule->next) { 464 1.1 christos if (strcmp(field->name, cache_rule->field_name) == 0) { 465 1.1 christos found_rule = 1; 466 1.1 christos if (cache_rule->derived_name != NULL) 467 1.1 christos lf_printf(file, " %s %s; /* %s */\n", 468 1.1 christos (cache_rule->type_def == NULL 469 1.1 christos ? "unsigned" 470 1.1 christos : cache_rule->type_def), 471 1.1 christos cache_rule->derived_name, 472 1.1 christos cache_rule->field_name); 473 1.1 christos } 474 1.1 christos } 475 1.1 christos if (!found_rule) 476 1.1 christos lf_printf(file, " unsigned %s;\n", field->name); 477 1.1 christos } 478 1.1 christos lf_printf(file, " } %s;\n", form->name); 479 1.1 christos } 480 1.1 christos lf_printf(file, " } crack;\n"); 481 1.1 christos lf_printf(file, "} idecode_cache;\n"); 482 1.1 christos } 483 1.1 christos else { 484 1.1 christos /* alernativly, since no cache, emit a dummy definition for 485 1.1.1.5 christos idecode_cache so that code referring to the type can still compile */ 486 1.1 christos lf_printf(file, "typedef void idecode_cache;\n"); 487 1.1 christos } 488 1.1 christos lf_printf(file, "\n"); 489 1.1 christos } 490 1.1 christos 491 1.1 christos 492 1.1 christos 493 1.1 christos static void 494 1.1 christos print_icache_function(lf *file, 495 1.1 christos insn *instruction, 496 1.1 christos insn_bits *expanded_bits, 497 1.1 christos opcode_field *opcodes, 498 1.1 christos cache_table *cache_rules) 499 1.1 christos { 500 1.1 christos int indent; 501 1.1 christos 502 1.1 christos /* generate code to enter decoded instruction into the icache */ 503 1.1 christos lf_printf(file, "\n"); 504 1.1.1.4 christos lf_print__function_type(file, ICACHE_FUNCTION_TYPE, "EXTERN_ICACHE", "\n"); 505 1.1 christos indent = print_function_name(file, 506 1.1 christos instruction->file_entry->fields[insn_name], 507 1.1 christos expanded_bits, 508 1.1 christos function_name_prefix_icache); 509 1.1 christos lf_indent(file, +indent); 510 1.1 christos lf_printf(file, "(%s)\n", ICACHE_FUNCTION_FORMAL); 511 1.1 christos lf_indent(file, -indent); 512 1.1 christos 513 1.1 christos /* function header */ 514 1.1 christos lf_printf(file, "{\n"); 515 1.1 christos lf_indent(file, +2); 516 1.1 christos 517 1.1 christos print_my_defines(file, expanded_bits, instruction->file_entry); 518 1.1 christos print_itrace(file, instruction->file_entry, 1/*putting-value-in-cache*/); 519 1.1 christos 520 1.1 christos print_idecode_validate(file, instruction, opcodes); 521 1.1 christos 522 1.1 christos lf_printf(file, "\n"); 523 1.1 christos lf_printf(file, "{\n"); 524 1.1 christos lf_indent(file, +2); 525 1.1 christos if ((code & generate_with_semantic_icache)) 526 1.1 christos lf_printf(file, "unsigned_word nia;\n"); 527 1.1 christos print_icache_body(file, 528 1.1 christos instruction, 529 1.1 christos expanded_bits, 530 1.1 christos cache_rules, 531 1.1 christos ((code & generate_with_direct_access) 532 1.1 christos ? define_variables 533 1.1 christos : declare_variables), 534 1.1 christos ((code & generate_with_semantic_icache) 535 1.1 christos ? both_values_and_icache 536 1.1 christos : put_values_in_icache)); 537 1.1 christos 538 1.1 christos lf_printf(file, "\n"); 539 1.1 christos lf_printf(file, "cache_entry->address = cia;\n"); 540 1.1 christos lf_printf(file, "cache_entry->semantic = "); 541 1.1 christos print_function_name(file, 542 1.1 christos instruction->file_entry->fields[insn_name], 543 1.1 christos expanded_bits, 544 1.1 christos function_name_prefix_semantics); 545 1.1 christos lf_printf(file, ";\n"); 546 1.1 christos lf_printf(file, "\n"); 547 1.1 christos 548 1.1 christos if ((code & generate_with_semantic_icache)) { 549 1.1 christos lf_printf(file, "/* semantic routine */\n"); 550 1.1 christos print_semantic_body(file, 551 1.1 christos instruction, 552 1.1 christos expanded_bits, 553 1.1 christos opcodes); 554 1.1 christos lf_printf(file, "return nia;\n"); 555 1.1 christos } 556 1.1 christos 557 1.1 christos if (!(code & generate_with_semantic_icache)) { 558 1.1 christos lf_printf(file, "/* return the function proper */\n"); 559 1.1 christos lf_printf(file, "return "); 560 1.1 christos print_function_name(file, 561 1.1 christos instruction->file_entry->fields[insn_name], 562 1.1 christos expanded_bits, 563 1.1 christos function_name_prefix_semantics); 564 1.1 christos lf_printf(file, ";\n"); 565 1.1 christos } 566 1.1 christos 567 1.1 christos if ((code & generate_with_direct_access)) 568 1.1 christos print_icache_body(file, 569 1.1 christos instruction, 570 1.1 christos expanded_bits, 571 1.1 christos cache_rules, 572 1.1 christos undef_variables, 573 1.1 christos ((code & generate_with_semantic_icache) 574 1.1 christos ? both_values_and_icache 575 1.1 christos : put_values_in_icache)); 576 1.1 christos 577 1.1 christos lf_indent(file, -2); 578 1.1 christos lf_printf(file, "}\n"); 579 1.1 christos lf_indent(file, -2); 580 1.1 christos lf_printf(file, "}\n"); 581 1.1 christos } 582 1.1 christos 583 1.1 christos 584 1.1 christos void 585 1.1 christos print_icache_definition(insn_table *entry, 586 1.1 christos lf *file, 587 1.1 christos void *data, 588 1.1 christos insn *instruction, 589 1.1 christos int depth) 590 1.1 christos { 591 1.1 christos cache_table *cache_rules = (cache_table*)data; 592 1.1 christos if (generate_expanded_instructions) { 593 1.1 christos ASSERT(entry->nr_insn == 1 594 1.1 christos && entry->opcode == NULL 595 1.1 christos && entry->parent != NULL 596 1.1 christos && entry->parent->opcode != NULL); 597 1.1 christos ASSERT(entry->nr_insn == 1 598 1.1 christos && entry->opcode == NULL 599 1.1 christos && entry->parent != NULL 600 1.1 christos && entry->parent->opcode != NULL 601 1.1 christos && entry->parent->opcode_rule != NULL); 602 1.1 christos print_icache_function(file, 603 1.1 christos entry->insns, 604 1.1 christos entry->expanded_bits, 605 1.1 christos entry->opcode, 606 1.1 christos cache_rules); 607 1.1 christos } 608 1.1 christos else { 609 1.1 christos print_icache_function(file, 610 1.1 christos instruction, 611 1.1 christos NULL, 612 1.1 christos NULL, 613 1.1 christos cache_rules); 614 1.1 christos } 615 1.1 christos } 616 1.1 christos 617 1.1 christos 618 1.1 christos 619 1.1 christos void 620 1.1 christos print_icache_internal_function_declaration(insn_table *table, 621 1.1 christos lf *file, 622 1.1 christos void *data, 623 1.1 christos table_entry *function) 624 1.1 christos { 625 1.1 christos ASSERT((code & generate_with_icache) != 0); 626 1.1 christos if (it_is("internal", function->fields[insn_flags])) { 627 1.1 christos lf_printf(file, "\n"); 628 1.1.1.4 christos lf_print__function_type(file, ICACHE_FUNCTION_TYPE, "PSIM_INLINE_ICACHE", 629 1.1 christos "\n"); 630 1.1 christos print_function_name(file, 631 1.1 christos function->fields[insn_name], 632 1.1 christos NULL, 633 1.1 christos function_name_prefix_icache); 634 1.1 christos lf_printf(file, "\n(%s);\n", ICACHE_FUNCTION_FORMAL); 635 1.1 christos } 636 1.1 christos } 637 1.1 christos 638 1.1 christos 639 1.1 christos void 640 1.1 christos print_icache_internal_function_definition(insn_table *table, 641 1.1 christos lf *file, 642 1.1 christos void *data, 643 1.1 christos table_entry *function) 644 1.1 christos { 645 1.1 christos ASSERT((code & generate_with_icache) != 0); 646 1.1 christos if (it_is("internal", function->fields[insn_flags])) { 647 1.1 christos lf_printf(file, "\n"); 648 1.1.1.4 christos lf_print__function_type(file, ICACHE_FUNCTION_TYPE, "PSIM_INLINE_ICACHE", 649 1.1 christos "\n"); 650 1.1 christos print_function_name(file, 651 1.1 christos function->fields[insn_name], 652 1.1 christos NULL, 653 1.1 christos function_name_prefix_icache); 654 1.1 christos lf_printf(file, "\n(%s)\n", ICACHE_FUNCTION_FORMAL); 655 1.1 christos lf_printf(file, "{\n"); 656 1.1 christos lf_indent(file, +2); 657 1.1 christos lf_printf(file, "/* semantic routine */\n"); 658 1.1 christos table_entry_print_cpp_line_nr(file, function); 659 1.1 christos if ((code & generate_with_semantic_icache)) { 660 1.1 christos lf_print__c_code(file, function->annex); 661 1.1 christos lf_printf(file, "error(\"Internal function must longjump\\n\");\n"); 662 1.1 christos lf_printf(file, "return 0;\n"); 663 1.1 christos } 664 1.1 christos else { 665 1.1 christos lf_printf(file, "return "); 666 1.1 christos print_function_name(file, 667 1.1 christos function->fields[insn_name], 668 1.1 christos NULL, 669 1.1 christos function_name_prefix_semantics); 670 1.1 christos lf_printf(file, ";\n"); 671 1.1 christos } 672 1.1 christos 673 1.1.1.4 christos lf_print__internal_ref(file); 674 1.1 christos lf_indent(file, -2); 675 1.1 christos lf_printf(file, "}\n"); 676 1.1 christos } 677 1.1 christos } 678