1 1.1 christos /* The IGEN simulator generator for GDB, the GNU Debugger. 2 1.1 christos 3 1.1.1.12 christos Copyright 2002-2025 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos Contributed by Andrew Cagney. 6 1.1 christos 7 1.1 christos This file is part of GDB. 8 1.1 christos 9 1.1 christos This program is free software; you can redistribute it and/or modify 10 1.1 christos it under the terms of the GNU General Public License as published by 11 1.1 christos the Free Software Foundation; either version 3 of the License, or 12 1.1 christos (at your option) any later version. 13 1.1 christos 14 1.1 christos This program is distributed in the hope that it will be useful, 15 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 16 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 1.1 christos GNU General Public License for more details. 18 1.1 christos 19 1.1 christos You should have received a copy of the GNU General Public License 20 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 1.1 christos 22 1.1 christos 23 1.1 christos #include "misc.h" 24 1.1 christos #include "lf.h" 25 1.1 christos #include "table.h" 26 1.1 christos #include "filter.h" 27 1.1 christos #include "igen.h" 28 1.1 christos #include "ld-insn.h" 29 1.1 christos 30 1.1 christos static insn_word_entry * 31 1.1.1.9 christos parse_insn_word (const line_ref *line, char *string, int word_nr) 32 1.1 christos { 33 1.1 christos char *chp; 34 1.1 christos insn_word_entry *word = ZALLOC (insn_word_entry); 35 1.1 christos 36 1.1 christos /* create a leading sentinal */ 37 1.1 christos word->first = ZALLOC (insn_field_entry); 38 1.1 christos word->first->first = -1; 39 1.1 christos word->first->last = -1; 40 1.1 christos word->first->width = 0; 41 1.1 christos 42 1.1 christos /* and a trailing sentinal */ 43 1.1 christos word->last = ZALLOC (insn_field_entry); 44 1.1 christos word->last->first = options.insn_bit_size; 45 1.1 christos word->last->last = options.insn_bit_size; 46 1.1 christos word->last->width = 0; 47 1.1 christos 48 1.1 christos /* link them together */ 49 1.1 christos word->first->next = word->last; 50 1.1 christos word->last->prev = word->first; 51 1.1 christos 52 1.1 christos /* now work through the formats */ 53 1.1 christos chp = skip_spaces (string); 54 1.1 christos 55 1.1 christos while (*chp != '\0') 56 1.1 christos { 57 1.1 christos char *start_pos; 58 1.1 christos int strlen_pos; 59 1.1 christos char *start_val; 60 1.1 christos int strlen_val; 61 1.1 christos insn_field_entry *new_field; 62 1.1 christos 63 1.1 christos /* create / link in the new field */ 64 1.1 christos new_field = ZALLOC (insn_field_entry); 65 1.1 christos new_field->next = word->last; 66 1.1 christos new_field->prev = word->last->prev; 67 1.1 christos new_field->next->prev = new_field; 68 1.1 christos new_field->prev->next = new_field; 69 1.1 christos new_field->word_nr = word_nr; 70 1.1 christos 71 1.1 christos /* break out the first field (if present) */ 72 1.1 christos start_pos = chp; 73 1.1 christos chp = skip_to_separator (chp, ".,!"); 74 1.1 christos strlen_pos = back_spaces (start_pos, chp) - start_pos; 75 1.1 christos 76 1.1 christos /* break out the second field (if present) */ 77 1.1 christos if (*chp != '.') 78 1.1 christos { 79 1.1 christos /* assume what was specified was the value (and not the start 80 1.1 christos position). Assume the value length implicitly specifies 81 1.1 christos the number of bits */ 82 1.1 christos start_val = start_pos; 83 1.1 christos strlen_val = strlen_pos; 84 1.1 christos start_pos = ""; 85 1.1 christos strlen_pos = 0; 86 1.1 christos } 87 1.1 christos else 88 1.1 christos { 89 1.1 christos chp++; /* skip `.' */ 90 1.1 christos chp = skip_spaces (chp); 91 1.1 christos start_val = chp; 92 1.1 christos if (*chp == '/' || *chp == '*') 93 1.1 christos { 94 1.1 christos do 95 1.1 christos { 96 1.1 christos chp++; 97 1.1 christos } 98 1.1 christos while (*chp == '/' || *chp == '*'); 99 1.1 christos } 100 1.1 christos else if (isalpha (*start_val)) 101 1.1 christos { 102 1.1 christos do 103 1.1 christos { 104 1.1 christos chp++; 105 1.1 christos } 106 1.1 christos while (isalnum (*chp) || *chp == '_'); 107 1.1 christos } 108 1.1 christos else if (isdigit (*start_val)) 109 1.1 christos { 110 1.1 christos do 111 1.1 christos { 112 1.1 christos chp++; 113 1.1 christos } 114 1.1 christos while (isalnum (*chp)); 115 1.1 christos } 116 1.1 christos strlen_val = chp - start_val; 117 1.1 christos chp = skip_spaces (chp); 118 1.1 christos } 119 1.1 christos if (strlen_val == 0) 120 1.1 christos error (line, "Empty value field\n"); 121 1.1 christos 122 1.1 christos /* break out any conditional fields - { [ "!" | "=" [ <value> | <field-name> } */ 123 1.1 christos while (*chp == '!' || *chp == '=') 124 1.1 christos { 125 1.1 christos char *start; 126 1.1 christos char *end; 127 1.1 christos int len; 128 1.1 christos insn_field_cond *new_cond = ZALLOC (insn_field_cond); 129 1.1 christos 130 1.1 christos /* determine the conditional test */ 131 1.1 christos switch (*chp) 132 1.1 christos { 133 1.1 christos case '=': 134 1.1 christos new_cond->test = insn_field_cond_eq; 135 1.1 christos break; 136 1.1 christos case '!': 137 1.1 christos new_cond->test = insn_field_cond_ne; 138 1.1 christos break; 139 1.1 christos default: 140 1.1 christos ASSERT (0); 141 1.1 christos } 142 1.1 christos 143 1.1 christos /* save the value */ 144 1.1 christos chp++; 145 1.1 christos chp = skip_spaces (chp); 146 1.1 christos start = chp; 147 1.1 christos chp = skip_to_separator (chp, "+,:!="); 148 1.1 christos end = back_spaces (start, chp); 149 1.1 christos len = end - start; 150 1.1 christos if (len == 0) 151 1.1 christos error (line, "Missing or invalid conditional value\n"); 152 1.1 christos new_cond->string = NZALLOC (char, len + 1); 153 1.1 christos strncpy (new_cond->string, start, len); 154 1.1 christos 155 1.1 christos /* determine the conditional type */ 156 1.1 christos if (isdigit (*start)) 157 1.1 christos { 158 1.1 christos /* [ "!" | "=" ] <value> */ 159 1.1 christos new_cond->type = insn_field_cond_value; 160 1.1 christos new_cond->value = a2i (new_cond->string); 161 1.1 christos } 162 1.1 christos else 163 1.1 christos { 164 1.1 christos /* [ "!" | "=" ] <field> - check field valid */ 165 1.1 christos new_cond->type = insn_field_cond_field; 166 1.1 christos /* new_cond->field is determined in later */ 167 1.1 christos } 168 1.1 christos 169 1.1 christos /* Only a single `=' is permitted. */ 170 1.1 christos if ((new_cond->test == insn_field_cond_eq 171 1.1 christos && new_field->conditions != NULL) 172 1.1 christos || (new_field->conditions != NULL 173 1.1 christos && new_field->conditions->test == insn_field_cond_eq)) 174 1.1 christos error (line, "Only single conditional when `=' allowed\n"); 175 1.1 christos 176 1.1 christos /* insert it */ 177 1.1 christos { 178 1.1 christos insn_field_cond **last = &new_field->conditions; 179 1.1 christos while (*last != NULL) 180 1.1 christos last = &(*last)->next; 181 1.1 christos *last = new_cond; 182 1.1 christos } 183 1.1 christos } 184 1.1 christos 185 1.1 christos /* NOW verify that the field was finished */ 186 1.1 christos if (*chp == ',') 187 1.1 christos { 188 1.1 christos chp = skip_spaces (chp + 1); 189 1.1 christos if (*chp == '\0') 190 1.1 christos error (line, "empty field\n"); 191 1.1 christos } 192 1.1 christos else if (*chp != '\0') 193 1.1 christos { 194 1.1 christos error (line, "Missing field separator\n"); 195 1.1 christos } 196 1.1 christos 197 1.1 christos /* copy the value */ 198 1.1 christos new_field->val_string = NZALLOC (char, strlen_val + 1); 199 1.1 christos strncpy (new_field->val_string, start_val, strlen_val); 200 1.1 christos if (isdigit (new_field->val_string[0])) 201 1.1 christos { 202 1.1 christos if (strlen_pos == 0) 203 1.1 christos { 204 1.1.1.11 christos /* when the length/pos field is omitted, an integer field 205 1.1 christos is always binary */ 206 1.1.1.9 christos uint64_t val = 0; 207 1.1 christos int i; 208 1.1 christos for (i = 0; i < strlen_val; i++) 209 1.1 christos { 210 1.1 christos if (new_field->val_string[i] != '0' 211 1.1 christos && new_field->val_string[i] != '1') 212 1.1 christos error (line, "invalid binary field %s\n", 213 1.1 christos new_field->val_string); 214 1.1 christos val = (val << 1) + (new_field->val_string[i] == '1'); 215 1.1 christos } 216 1.1 christos new_field->val_int = val; 217 1.1 christos new_field->type = insn_field_int; 218 1.1 christos } 219 1.1 christos else 220 1.1 christos { 221 1.1 christos new_field->val_int = a2i (new_field->val_string); 222 1.1 christos new_field->type = insn_field_int; 223 1.1 christos } 224 1.1 christos } 225 1.1 christos else if (new_field->val_string[0] == '/') 226 1.1 christos { 227 1.1 christos new_field->type = insn_field_reserved; 228 1.1 christos } 229 1.1 christos else if (new_field->val_string[0] == '*') 230 1.1 christos { 231 1.1 christos new_field->type = insn_field_wild; 232 1.1 christos } 233 1.1 christos else 234 1.1 christos { 235 1.1 christos new_field->type = insn_field_string; 236 1.1 christos if (filter_is_member (word->field_names, new_field->val_string)) 237 1.1 christos error (line, "Field name %s is duplicated\n", 238 1.1 christos new_field->val_string); 239 1.1 christos filter_parse (&word->field_names, new_field->val_string); 240 1.1 christos } 241 1.1 christos if (new_field->type != insn_field_string 242 1.1 christos && new_field->conditions != NULL) 243 1.1 christos error (line, "Conditionals can only be applied to named fields\n"); 244 1.1 christos 245 1.1 christos /* the copy the position */ 246 1.1 christos new_field->pos_string = NZALLOC (char, strlen_pos + 1); 247 1.1 christos strncpy (new_field->pos_string, start_pos, strlen_pos); 248 1.1 christos if (strlen_pos == 0) 249 1.1 christos { 250 1.1 christos new_field->first = new_field->prev->last + 1; 251 1.1 christos if (new_field->first == 0 /* first field */ 252 1.1 christos && *chp == '\0' /* no further fields */ 253 1.1 christos && new_field->type == insn_field_string) 254 1.1 christos { 255 1.1 christos /* A single string without any position, assume that it 256 1.1 christos represents the entire instruction word */ 257 1.1 christos new_field->width = options.insn_bit_size; 258 1.1 christos } 259 1.1 christos else 260 1.1 christos { 261 1.1 christos /* No explicit width/position, assume value implicitly 262 1.1 christos supplies the width */ 263 1.1 christos new_field->width = strlen_val; 264 1.1 christos } 265 1.1 christos new_field->last = new_field->first + new_field->width - 1; 266 1.1 christos if (new_field->last >= options.insn_bit_size) 267 1.1 christos error (line, "Bit position %d exceed instruction bit size (%d)\n", 268 1.1 christos new_field->last, options.insn_bit_size); 269 1.1 christos } 270 1.1 christos else if (options.insn_specifying_widths) 271 1.1 christos { 272 1.1 christos new_field->first = new_field->prev->last + 1; 273 1.1 christos new_field->width = a2i (new_field->pos_string); 274 1.1 christos new_field->last = new_field->first + new_field->width - 1; 275 1.1 christos if (new_field->last >= options.insn_bit_size) 276 1.1 christos error (line, "Bit position %d exceed instruction bit size (%d)\n", 277 1.1 christos new_field->last, options.insn_bit_size); 278 1.1 christos } 279 1.1 christos else 280 1.1 christos { 281 1.1 christos new_field->first = target_a2i (options.hi_bit_nr, 282 1.1 christos new_field->pos_string); 283 1.1 christos new_field->last = new_field->next->first - 1; /* guess */ 284 1.1 christos new_field->width = new_field->last - new_field->first + 1; /* guess */ 285 1.1 christos new_field->prev->last = new_field->first - 1; /*fix */ 286 1.1 christos new_field->prev->width = new_field->first - new_field->prev->first; /*fix */ 287 1.1 christos } 288 1.1 christos } 289 1.1 christos 290 1.1 christos /* fiddle first/last so that the sentinals disapear */ 291 1.1 christos ASSERT (word->first->last < 0); 292 1.1 christos ASSERT (word->last->first >= options.insn_bit_size); 293 1.1 christos word->first = word->first->next; 294 1.1 christos word->last = word->last->prev; 295 1.1 christos 296 1.1 christos /* check that the last field goes all the way to the last bit */ 297 1.1 christos if (word->last->last != options.insn_bit_size - 1) 298 1.1 christos { 299 1.1 christos if (options.warn.width) 300 1.1 christos options.warning (line, "Instruction format is not %d bits wide\n", 301 1.1 christos options.insn_bit_size); 302 1.1 christos word->last->last = options.insn_bit_size - 1; 303 1.1 christos } 304 1.1 christos 305 1.1 christos /* now go over this again, pointing each bit position at a field 306 1.1 christos record */ 307 1.1 christos { 308 1.1 christos insn_field_entry *field; 309 1.1 christos for (field = word->first; 310 1.1 christos field->last < options.insn_bit_size; field = field->next) 311 1.1 christos { 312 1.1 christos int i; 313 1.1 christos for (i = field->first; i <= field->last; i++) 314 1.1 christos { 315 1.1 christos word->bit[i] = ZALLOC (insn_bit_entry); 316 1.1 christos word->bit[i]->field = field; 317 1.1 christos switch (field->type) 318 1.1 christos { 319 1.1 christos case insn_field_invalid: 320 1.1 christos ASSERT (0); 321 1.1 christos break; 322 1.1 christos case insn_field_int: 323 1.1 christos word->bit[i]->mask = 1; 324 1.1 christos word->bit[i]->value = ((field->val_int 325 1.1 christos & ((insn_uint) 1 << 326 1.1 christos (field->last - i))) != 0); 327 1.1 christos case insn_field_reserved: 328 1.1 christos case insn_field_wild: 329 1.1 christos case insn_field_string: 330 1.1 christos /* if we encounter a constant conditional, encode 331 1.1 christos their bit value. */ 332 1.1 christos if (field->conditions != NULL 333 1.1 christos && field->conditions->test == insn_field_cond_eq 334 1.1 christos && field->conditions->type == insn_field_cond_value) 335 1.1 christos { 336 1.1 christos word->bit[i]->mask = 1; 337 1.1 christos word->bit[i]->value = ((field->conditions->value 338 1.1 christos & ((insn_uint) 1 << 339 1.1 christos (field->last - i))) != 0); 340 1.1 christos } 341 1.1 christos break; 342 1.1 christos } 343 1.1 christos } 344 1.1 christos } 345 1.1 christos } 346 1.1 christos 347 1.1 christos return word; 348 1.1 christos } 349 1.1 christos 350 1.1 christos 351 1.1 christos static void 352 1.1 christos parse_insn_words (insn_entry * insn, char *formats) 353 1.1 christos { 354 1.1 christos insn_word_entry **last_word = &insn->words; 355 1.1 christos char *chp; 356 1.1 christos 357 1.1 christos /* now work through the formats */ 358 1.1 christos insn->nr_words = 0; 359 1.1 christos chp = formats; 360 1.1 christos 361 1.1 christos while (1) 362 1.1 christos { 363 1.1 christos char *start_pos; 364 1.1 christos char *end_pos; 365 1.1 christos int strlen_pos; 366 1.1 christos char *format; 367 1.1 christos insn_word_entry *new_word; 368 1.1 christos 369 1.1 christos /* skip leading spaces */ 370 1.1 christos chp = skip_spaces (chp); 371 1.1 christos 372 1.1 christos /* break out the format */ 373 1.1 christos start_pos = chp; 374 1.1 christos chp = skip_to_separator (chp, "+"); 375 1.1 christos end_pos = back_spaces (start_pos, chp); 376 1.1 christos strlen_pos = end_pos - start_pos; 377 1.1 christos 378 1.1 christos /* check that something was there */ 379 1.1 christos if (strlen_pos == 0) 380 1.1 christos error (insn->line, "missing or empty instruction format\n"); 381 1.1 christos 382 1.1 christos /* parse the field */ 383 1.1 christos format = NZALLOC (char, strlen_pos + 1); 384 1.1 christos strncpy (format, start_pos, strlen_pos); 385 1.1 christos new_word = parse_insn_word (insn->line, format, insn->nr_words); 386 1.1 christos insn->nr_words++; 387 1.1 christos if (filter_is_common (insn->field_names, new_word->field_names)) 388 1.1 christos error (insn->line, "Field name duplicated between two words\n"); 389 1.1 christos filter_add (&insn->field_names, new_word->field_names); 390 1.1 christos 391 1.1 christos /* insert it */ 392 1.1 christos *last_word = new_word; 393 1.1 christos last_word = &new_word->next; 394 1.1 christos 395 1.1 christos /* last format? */ 396 1.1 christos if (*chp == '\0') 397 1.1 christos break; 398 1.1 christos ASSERT (*chp == '+'); 399 1.1 christos chp++; 400 1.1 christos } 401 1.1 christos 402 1.1 christos /* create a quick access array (indexed by word) of the same structure */ 403 1.1 christos { 404 1.1 christos int i; 405 1.1 christos insn_word_entry *word; 406 1.1 christos insn->word = NZALLOC (insn_word_entry *, insn->nr_words + 1); 407 1.1 christos for (i = 0, word = insn->words; 408 1.1 christos i < insn->nr_words; i++, word = word->next) 409 1.1 christos insn->word[i] = word; 410 1.1 christos } 411 1.1 christos 412 1.1.1.11 christos /* Go over all fields that have conditionals referring to other 413 1.1 christos fields. Link the fields up. Verify that the two fields have the 414 1.1 christos same size. Verify that the two fields are different */ 415 1.1 christos { 416 1.1 christos int i; 417 1.1 christos for (i = 0; i < insn->nr_words; i++) 418 1.1 christos { 419 1.1 christos insn_word_entry *word = insn->word[i]; 420 1.1 christos insn_field_entry *f; 421 1.1 christos for (f = word->first; f->last < options.insn_bit_size; f = f->next) 422 1.1 christos { 423 1.1 christos insn_field_cond *cond; 424 1.1 christos for (cond = f->conditions; cond != NULL; cond = cond->next) 425 1.1 christos { 426 1.1 christos if (cond->type == insn_field_cond_field) 427 1.1 christos { 428 1.1 christos int j; 429 1.1 christos if (strcmp (cond->string, f->val_string) == 0) 430 1.1 christos error (insn->line, 431 1.1 christos "Conditional `%s' of field `%s' refers to its self\n", 432 1.1 christos cond->string, f->val_string); 433 1.1 christos for (j = 0; j <= i && cond->field == NULL; j++) 434 1.1 christos { 435 1.1 christos insn_word_entry *refered_word = insn->word[j]; 436 1.1 christos insn_field_entry *refered_field; 437 1.1 christos for (refered_field = refered_word->first; 438 1.1 christos refered_field != NULL && cond->field == NULL; 439 1.1 christos refered_field = refered_field->next) 440 1.1 christos { 441 1.1 christos if (refered_field->type == insn_field_string 442 1.1 christos && strcmp (refered_field->val_string, 443 1.1 christos cond->string) == 0) 444 1.1 christos { 445 1.1.1.11 christos /* found field being referred to by conditonal */ 446 1.1 christos cond->field = refered_field; 447 1.1.1.11 christos /* check referred to and this field are 448 1.1 christos the same size */ 449 1.1 christos if (f->width != refered_field->width) 450 1.1 christos error (insn->line, 451 1.1.1.9 christos "Conditional `%s' of field `%s' should be of size %i\n", 452 1.1 christos cond->string, f->val_string, 453 1.1 christos refered_field->width); 454 1.1 christos } 455 1.1 christos } 456 1.1 christos } 457 1.1 christos if (cond->field == NULL) 458 1.1 christos error (insn->line, 459 1.1 christos "Conditional `%s' of field `%s' not yet defined\n", 460 1.1 christos cond->string, f->val_string); 461 1.1 christos } 462 1.1 christos } 463 1.1 christos } 464 1.1 christos } 465 1.1 christos } 466 1.1 christos 467 1.1 christos } 468 1.1 christos 469 1.1 christos typedef enum 470 1.1 christos { 471 1.1 christos unknown_record = 0, 472 1.1 christos insn_record, /* default */ 473 1.1 christos code_record, 474 1.1 christos cache_record, 475 1.1 christos compute_record, 476 1.1 christos scratch_record, 477 1.1 christos option_record, 478 1.1 christos string_function_record, 479 1.1 christos function_record, 480 1.1 christos internal_record, 481 1.1 christos define_record, 482 1.1 christos include_record, 483 1.1 christos model_processor_record, 484 1.1 christos model_macro_record, 485 1.1 christos model_data_record, 486 1.1 christos model_static_record, 487 1.1 christos model_function_record, 488 1.1 christos model_internal_record, 489 1.1 christos } 490 1.1 christos insn_record_type; 491 1.1 christos 492 1.1 christos static const name_map insn_type_map[] = { 493 1.1 christos {"option", option_record}, 494 1.1 christos {"cache", cache_record}, 495 1.1 christos {"compute", compute_record}, 496 1.1 christos {"scratch", scratch_record}, 497 1.1 christos {"define", define_record}, 498 1.1 christos {"include", include_record}, 499 1.1 christos {"%s", string_function_record}, 500 1.1 christos {"function", function_record}, 501 1.1 christos {"internal", internal_record}, 502 1.1 christos {"model", model_processor_record}, 503 1.1 christos {"model-macro", model_macro_record}, 504 1.1 christos {"model-data", model_data_record}, 505 1.1 christos {"model-static", model_static_record}, 506 1.1 christos {"model-internal", model_internal_record}, 507 1.1 christos {"model-function", model_function_record}, 508 1.1 christos {NULL, insn_record}, 509 1.1 christos }; 510 1.1 christos 511 1.1 christos 512 1.1 christos static int 513 1.1 christos record_is_old (table_entry *entry) 514 1.1 christos { 515 1.1 christos if (entry->nr_fields > record_type_field 516 1.1 christos && strlen (entry->field[record_type_field]) == 0) 517 1.1 christos return 1; 518 1.1 christos return 0; 519 1.1 christos } 520 1.1 christos 521 1.1 christos static insn_record_type 522 1.1 christos record_type (table_entry *entry) 523 1.1 christos { 524 1.1 christos switch (entry->type) 525 1.1 christos { 526 1.1 christos case table_code_entry: 527 1.1 christos return code_record; 528 1.1 christos 529 1.1 christos case table_colon_entry: 530 1.1 christos if (record_is_old (entry)) 531 1.1 christos { 532 1.1 christos /* old-format? */ 533 1.1 christos if (entry->nr_fields > old_record_type_field) 534 1.1 christos { 535 1.1 christos int i = name2i (entry->field[old_record_type_field], 536 1.1 christos insn_type_map); 537 1.1 christos return i; 538 1.1 christos } 539 1.1 christos else 540 1.1 christos { 541 1.1 christos return unknown_record; 542 1.1 christos } 543 1.1 christos } 544 1.1 christos else if (entry->nr_fields > record_type_field 545 1.1 christos && entry->field[0][0] == '\0') 546 1.1 christos { 547 1.1 christos /* new-format? */ 548 1.1 christos int i = name2i (entry->field[record_type_field], 549 1.1 christos insn_type_map); 550 1.1 christos return i; 551 1.1 christos } 552 1.1 christos else 553 1.1 christos return insn_record; /* default */ 554 1.1 christos } 555 1.1 christos return unknown_record; 556 1.1 christos } 557 1.1 christos 558 1.1 christos static int 559 1.1 christos record_prefix_is (table_entry *entry, char ch, int nr_fields) 560 1.1 christos { 561 1.1 christos if (entry->type != table_colon_entry) 562 1.1 christos return 0; 563 1.1 christos if (entry->nr_fields < nr_fields) 564 1.1 christos return 0; 565 1.1 christos if (entry->field[0][0] != ch && ch != '\0') 566 1.1 christos return 0; 567 1.1 christos return 1; 568 1.1 christos } 569 1.1 christos 570 1.1 christos static table_entry * 571 1.1 christos parse_model_data_record (insn_table *isa, 572 1.1 christos table *file, 573 1.1 christos table_entry *record, 574 1.1 christos int nr_fields, model_data **list) 575 1.1 christos { 576 1.1 christos table_entry *model_record = record; 577 1.1 christos table_entry *code_record = NULL; 578 1.1 christos model_data *new_data; 579 1.1 christos if (record->nr_fields < nr_fields) 580 1.1 christos error (record->line, "Incorrect number of fields\n"); 581 1.1 christos record = table_read (file); 582 1.1 christos if (record->type == table_code_entry) 583 1.1 christos { 584 1.1 christos code_record = record; 585 1.1 christos record = table_read (file); 586 1.1 christos } 587 1.1 christos /* create the new data record */ 588 1.1 christos new_data = ZALLOC (model_data); 589 1.1 christos new_data->line = model_record->line; 590 1.1 christos filter_parse (&new_data->flags, 591 1.1 christos model_record->field[record_filter_flags_field]); 592 1.1 christos new_data->entry = model_record; 593 1.1 christos new_data->code = code_record; 594 1.1 christos /* append it if not filtered out */ 595 1.1 christos if (!is_filtered_out (options.flags_filter, 596 1.1 christos model_record->field[record_filter_flags_field]) 597 1.1 christos && !is_filtered_out (options.model_filter, 598 1.1 christos model_record->field[record_filter_models_field])) 599 1.1 christos { 600 1.1 christos while (*list != NULL) 601 1.1 christos list = &(*list)->next; 602 1.1 christos *list = new_data; 603 1.1 christos } 604 1.1 christos return record; 605 1.1 christos } 606 1.1 christos 607 1.1 christos 608 1.1 christos typedef enum 609 1.1 christos { 610 1.1 christos insn_bit_size_option = 1, 611 1.1 christos insn_specifying_widths_option, 612 1.1 christos hi_bit_nr_option, 613 1.1 christos flags_filter_option, 614 1.1 christos model_filter_option, 615 1.1 christos multi_sim_option, 616 1.1 christos format_names_option, 617 1.1 christos gen_delayed_branch, 618 1.1 christos unknown_option, 619 1.1 christos } 620 1.1 christos option_names; 621 1.1 christos 622 1.1 christos static const name_map option_map[] = { 623 1.1 christos {"insn-bit-size", insn_bit_size_option}, 624 1.1 christos {"insn-specifying-widths", insn_specifying_widths_option}, 625 1.1 christos {"hi-bit-nr", hi_bit_nr_option}, 626 1.1 christos {"flags-filter", flags_filter_option}, 627 1.1 christos {"model-filter", model_filter_option}, 628 1.1 christos {"multi-sim", multi_sim_option}, 629 1.1 christos {"format-names", format_names_option}, 630 1.1 christos {"gen-delayed-branch", gen_delayed_branch}, 631 1.1 christos {NULL, unknown_option}, 632 1.1 christos }; 633 1.1 christos 634 1.1 christos static table_entry * 635 1.1 christos parse_include_record (table *file, table_entry *record) 636 1.1 christos { 637 1.1 christos /* parse the include record */ 638 1.1 christos if (record->nr_fields < nr_include_fields) 639 1.1 christos error (record->line, "Incorrect nr fields for include record\n"); 640 1.1 christos /* process it */ 641 1.1 christos if (!is_filtered_out (options.flags_filter, 642 1.1 christos record->field[record_filter_flags_field]) 643 1.1 christos && !is_filtered_out (options.model_filter, 644 1.1 christos record->field[record_filter_models_field])) 645 1.1 christos { 646 1.1 christos table_push (file, record->line, options.include, 647 1.1 christos record->field[include_filename_field]); 648 1.1 christos } 649 1.1 christos /* nb: can't read next record until after the file has been pushed */ 650 1.1 christos record = table_read (file); 651 1.1 christos return record; 652 1.1 christos } 653 1.1 christos 654 1.1 christos 655 1.1 christos static table_entry * 656 1.1 christos parse_option_record (table *file, table_entry *record) 657 1.1 christos { 658 1.1 christos table_entry *option_record; 659 1.1 christos /* parse the option record */ 660 1.1 christos option_record = record; 661 1.1 christos if (record->nr_fields < nr_option_fields) 662 1.1 christos error (record->line, "Incorrect nr of fields for option record\n"); 663 1.1 christos record = table_read (file); 664 1.1 christos /* process it */ 665 1.1 christos if (!is_filtered_out (options.flags_filter, 666 1.1 christos option_record->field[record_filter_flags_field]) 667 1.1 christos && !is_filtered_out (options.model_filter, 668 1.1 christos option_record->field[record_filter_models_field])) 669 1.1 christos { 670 1.1 christos char *name = option_record->field[option_name_field]; 671 1.1 christos option_names option = name2i (name, option_map); 672 1.1 christos char *value = option_record->field[option_value_field]; 673 1.1 christos switch (option) 674 1.1 christos { 675 1.1 christos case insn_bit_size_option: 676 1.1 christos { 677 1.1 christos options.insn_bit_size = a2i (value); 678 1.1 christos if (options.insn_bit_size < 0 679 1.1 christos || options.insn_bit_size > max_insn_bit_size) 680 1.1 christos error (option_record->line, 681 1.1 christos "Instruction bit size out of range\n"); 682 1.1 christos if (options.hi_bit_nr != options.insn_bit_size - 1 683 1.1 christos && options.hi_bit_nr != 0) 684 1.1 christos error (option_record->line, 685 1.1 christos "insn-bit-size / hi-bit-nr conflict\n"); 686 1.1 christos break; 687 1.1 christos } 688 1.1 christos case insn_specifying_widths_option: 689 1.1 christos { 690 1.1 christos options.insn_specifying_widths = a2i (value); 691 1.1 christos break; 692 1.1 christos } 693 1.1 christos case hi_bit_nr_option: 694 1.1 christos { 695 1.1 christos options.hi_bit_nr = a2i (value); 696 1.1 christos if (options.hi_bit_nr != 0 697 1.1 christos && options.hi_bit_nr != options.insn_bit_size - 1) 698 1.1 christos error (option_record->line, 699 1.1 christos "hi-bit-nr / insn-bit-size conflict\n"); 700 1.1 christos break; 701 1.1 christos } 702 1.1 christos case flags_filter_option: 703 1.1 christos { 704 1.1 christos filter_parse (&options.flags_filter, value); 705 1.1 christos break; 706 1.1 christos } 707 1.1 christos case model_filter_option: 708 1.1 christos { 709 1.1 christos filter_parse (&options.model_filter, value); 710 1.1 christos break; 711 1.1 christos } 712 1.1 christos case multi_sim_option: 713 1.1 christos { 714 1.1 christos options.gen.multi_sim = a2i (value); 715 1.1 christos break; 716 1.1 christos } 717 1.1 christos case format_names_option: 718 1.1 christos { 719 1.1 christos filter_parse (&options.format_name_filter, value); 720 1.1 christos break; 721 1.1 christos } 722 1.1 christos case gen_delayed_branch: 723 1.1 christos { 724 1.1 christos options.gen.delayed_branch = a2i (value); 725 1.1 christos break; 726 1.1 christos } 727 1.1 christos case unknown_option: 728 1.1 christos { 729 1.1 christos error (option_record->line, "Unknown option - %s\n", name); 730 1.1 christos break; 731 1.1 christos } 732 1.1 christos } 733 1.1 christos } 734 1.1 christos return record; 735 1.1 christos } 736 1.1 christos 737 1.1 christos 738 1.1 christos static table_entry * 739 1.1 christos parse_function_record (table *file, 740 1.1 christos table_entry *record, 741 1.1 christos function_entry ** list, 742 1.1 christos function_entry ** list_entry, 743 1.1 christos int is_internal, model_table *model) 744 1.1 christos { 745 1.1 christos function_entry *new_function; 746 1.1 christos new_function = ZALLOC (function_entry); 747 1.1 christos new_function->line = record->line; 748 1.1 christos new_function->is_internal = is_internal; 749 1.1 christos /* parse the function header */ 750 1.1 christos if (record_is_old (record)) 751 1.1 christos { 752 1.1 christos if (record->nr_fields < nr_old_function_fields) 753 1.1 christos error (record->line, "Missing fields from (old) function record\n"); 754 1.1 christos new_function->type = record->field[old_function_typedef_field]; 755 1.1 christos new_function->type = record->field[old_function_typedef_field]; 756 1.1 christos if (record->nr_fields > old_function_param_field) 757 1.1 christos new_function->param = record->field[old_function_param_field]; 758 1.1 christos new_function->name = record->field[old_function_name_field]; 759 1.1 christos } 760 1.1 christos else 761 1.1 christos { 762 1.1 christos if (record->nr_fields < nr_function_fields) 763 1.1 christos error (record->line, "Missing fields from function record\n"); 764 1.1 christos filter_parse (&new_function->flags, 765 1.1 christos record->field[record_filter_flags_field]); 766 1.1 christos filter_parse (&new_function->models, 767 1.1 christos record->field[record_filter_models_field]); 768 1.1 christos new_function->type = record->field[function_typedef_field]; 769 1.1 christos new_function->param = record->field[function_param_field]; 770 1.1 christos new_function->name = record->field[function_name_field]; 771 1.1 christos } 772 1.1 christos record = table_read (file); 773 1.1 christos /* parse any function-model records */ 774 1.1 christos while (record != NULL 775 1.1 christos && record_prefix_is (record, '*', nr_function_model_fields)) 776 1.1 christos { 777 1.1 christos char *model_name = record->field[function_model_name_field] + 1; /*skip `*' */ 778 1.1 christos filter_parse (&new_function->models, model_name); 779 1.1 christos if (!filter_is_subset (model->processors, new_function->models)) 780 1.1 christos { 781 1.1 christos error (record->line, "machine model `%s' undefined\n", model_name); 782 1.1 christos } 783 1.1 christos record = table_read (file); 784 1.1 christos } 785 1.1 christos /* parse the function body */ 786 1.1 christos if (record->type == table_code_entry) 787 1.1 christos { 788 1.1 christos new_function->code = record; 789 1.1 christos record = table_read (file); 790 1.1 christos } 791 1.1 christos /* insert it */ 792 1.1 christos if (!filter_is_subset (options.flags_filter, new_function->flags)) 793 1.1 christos { 794 1.1 christos if (options.warn.discard) 795 1.1 christos notify (new_function->line, "Discarding function %s - filter flags\n", 796 1.1 christos new_function->name); 797 1.1 christos } 798 1.1 christos else if (new_function->models != NULL 799 1.1 christos && !filter_is_common (options.model_filter, new_function->models)) 800 1.1 christos { 801 1.1 christos if (options.warn.discard) 802 1.1 christos notify (new_function->line, 803 1.1 christos "Discarding function %s - filter models\n", 804 1.1 christos new_function->name); 805 1.1 christos } 806 1.1 christos else 807 1.1 christos { 808 1.1 christos while (*list != NULL) 809 1.1 christos list = &(*list)->next; 810 1.1 christos *list = new_function; 811 1.1 christos if (list_entry != NULL) 812 1.1 christos *list_entry = new_function; 813 1.1 christos } 814 1.1 christos /* done */ 815 1.1 christos return record; 816 1.1 christos } 817 1.1 christos 818 1.1 christos static void 819 1.1 christos parse_insn_model_record (table *file, 820 1.1 christos table_entry *record, 821 1.1 christos insn_entry * insn, model_table *model) 822 1.1 christos { 823 1.1 christos insn_model_entry **last_insn_model; 824 1.1 christos insn_model_entry *new_insn_model = ZALLOC (insn_model_entry); 825 1.1 christos /* parse it */ 826 1.1 christos new_insn_model->line = record->line; 827 1.1 christos if (record->nr_fields > insn_model_unit_data_field) 828 1.1 christos new_insn_model->unit_data = record->field[insn_model_unit_data_field]; 829 1.1 christos new_insn_model->insn = insn; 830 1.1 christos /* parse the model names, verify that all were defined */ 831 1.1 christos new_insn_model->names = NULL; 832 1.1 christos filter_parse (&new_insn_model->names, 833 1.1 christos record->field[insn_model_name_field] + 1 /*skip `*' */ ); 834 1.1 christos if (new_insn_model->names == NULL) 835 1.1 christos { 836 1.1 christos /* No processor names - a generic model entry, enter it into all 837 1.1 christos the non-empty fields */ 838 1.1 christos int index; 839 1.1 christos for (index = 0; index < model->nr_models; index++) 840 1.1 christos if (insn->model[index] == 0) 841 1.1 christos { 842 1.1 christos insn->model[index] = new_insn_model; 843 1.1 christos } 844 1.1 christos /* also add the complete processor set to this processor's set */ 845 1.1 christos filter_add (&insn->processors, model->processors); 846 1.1 christos } 847 1.1 christos else 848 1.1 christos { 849 1.1 christos /* Find the corresponding master model record for each name so 850 1.1 christos that they can be linked in. */ 851 1.1 christos int index; 852 1.1.1.9 christos const char *name = ""; 853 1.1 christos while (1) 854 1.1 christos { 855 1.1 christos name = filter_next (new_insn_model->names, name); 856 1.1 christos if (name == NULL) 857 1.1 christos break; 858 1.1 christos index = filter_is_member (model->processors, name) - 1; 859 1.1 christos if (index < 0) 860 1.1 christos { 861 1.1 christos error (new_insn_model->line, 862 1.1 christos "machine model `%s' undefined\n", name); 863 1.1 christos } 864 1.1 christos /* store it in the corresponding model array entry */ 865 1.1 christos if (insn->model[index] != NULL && insn->model[index]->names != NULL) 866 1.1 christos { 867 1.1 christos warning (new_insn_model->line, 868 1.1 christos "machine model `%s' previously defined\n", name); 869 1.1 christos error (insn->model[index]->line, "earlier definition\n"); 870 1.1 christos } 871 1.1 christos insn->model[index] = new_insn_model; 872 1.1 christos /* also add the name to the instructions processor set as an 873 1.1 christos alternative lookup mechanism */ 874 1.1 christos filter_parse (&insn->processors, name); 875 1.1 christos } 876 1.1 christos } 877 1.1 christos /* link it in */ 878 1.1 christos last_insn_model = &insn->models; 879 1.1 christos while ((*last_insn_model) != NULL) 880 1.1 christos last_insn_model = &(*last_insn_model)->next; 881 1.1 christos *last_insn_model = new_insn_model; 882 1.1 christos } 883 1.1 christos 884 1.1 christos 885 1.1 christos static void 886 1.1 christos parse_insn_mnemonic_record (table *file, 887 1.1 christos table_entry *record, insn_entry * insn) 888 1.1 christos { 889 1.1 christos insn_mnemonic_entry **last_insn_mnemonic; 890 1.1 christos insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry); 891 1.1 christos /* parse it */ 892 1.1 christos new_insn_mnemonic->line = record->line; 893 1.1 christos ASSERT (record->nr_fields > insn_mnemonic_format_field); 894 1.1 christos new_insn_mnemonic->format = record->field[insn_mnemonic_format_field]; 895 1.1 christos ASSERT (new_insn_mnemonic->format[0] == '"'); 896 1.1 christos if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] != 897 1.1 christos '"') 898 1.1 christos error (new_insn_mnemonic->line, 899 1.1 christos "Missing closing double quote in mnemonic field\n"); 900 1.1 christos if (record->nr_fields > insn_mnemonic_condition_field) 901 1.1 christos new_insn_mnemonic->condition = 902 1.1 christos record->field[insn_mnemonic_condition_field]; 903 1.1 christos new_insn_mnemonic->insn = insn; 904 1.1 christos /* insert it */ 905 1.1 christos last_insn_mnemonic = &insn->mnemonics; 906 1.1 christos while ((*last_insn_mnemonic) != NULL) 907 1.1 christos last_insn_mnemonic = &(*last_insn_mnemonic)->next; 908 1.1 christos insn->nr_mnemonics++; 909 1.1 christos *last_insn_mnemonic = new_insn_mnemonic; 910 1.1 christos } 911 1.1 christos 912 1.1 christos 913 1.1 christos static table_entry * 914 1.1 christos parse_macro_record (table *file, table_entry *record) 915 1.1 christos { 916 1.1 christos #if 1 917 1.1.1.9 christos error (record->line, "Macros are not implemented\n"); 918 1.1 christos #else 919 1.1 christos /* parse the define record */ 920 1.1 christos if (record->nr_fields < nr_define_fields) 921 1.1 christos error (record->line, "Incorrect nr fields for define record\n"); 922 1.1 christos /* process it */ 923 1.1 christos if (!is_filtered_out (options.flags_filter, 924 1.1 christos record->field[record_filter_flags_field]) 925 1.1 christos && !is_filtered_out (options.model_filter, 926 1.1 christos record->field[record_filter_models_field])) 927 1.1 christos { 928 1.1 christos table_define (file, 929 1.1 christos record->line, 930 1.1 christos record->field[macro_name_field], 931 1.1 christos record->field[macro_args_field], 932 1.1 christos record->field[macro_expr_field]); 933 1.1 christos } 934 1.1 christos record = table_read (file); 935 1.1 christos #endif 936 1.1 christos return record; 937 1.1 christos } 938 1.1 christos 939 1.1 christos 940 1.1 christos insn_table * 941 1.1.1.9 christos load_insn_table (const char *file_name, cache_entry *cache) 942 1.1 christos { 943 1.1 christos table *file = table_open (file_name); 944 1.1 christos table_entry *record = table_read (file); 945 1.1 christos 946 1.1 christos insn_table *isa = ZALLOC (insn_table); 947 1.1 christos model_table *model = ZALLOC (model_table); 948 1.1 christos 949 1.1 christos isa->model = model; 950 1.1 christos isa->caches = cache; 951 1.1 christos 952 1.1 christos while (record != NULL) 953 1.1 christos { 954 1.1 christos 955 1.1 christos switch (record_type (record)) 956 1.1 christos { 957 1.1 christos 958 1.1 christos case include_record: 959 1.1 christos { 960 1.1 christos record = parse_include_record (file, record); 961 1.1 christos break; 962 1.1 christos } 963 1.1 christos 964 1.1 christos case option_record: 965 1.1 christos { 966 1.1 christos if (isa->insns != NULL) 967 1.1 christos error (record->line, "Option after first instruction\n"); 968 1.1 christos record = parse_option_record (file, record); 969 1.1 christos break; 970 1.1 christos } 971 1.1 christos 972 1.1 christos case string_function_record: 973 1.1 christos { 974 1.1 christos function_entry *function = NULL; 975 1.1 christos record = parse_function_record (file, record, 976 1.1 christos &isa->functions, 977 1.1 christos &function, 0 /*is-internal */ , 978 1.1 christos model); 979 1.1 christos /* convert a string function record into an internal function */ 980 1.1 christos if (function != NULL) 981 1.1 christos { 982 1.1 christos char *name = NZALLOC (char, 983 1.1 christos (strlen ("str_") 984 1.1 christos + strlen (function->name) + 1)); 985 1.1 christos strcat (name, "str_"); 986 1.1 christos strcat (name, function->name); 987 1.1 christos function->name = name; 988 1.1 christos function->type = "const char *"; 989 1.1 christos } 990 1.1 christos break; 991 1.1 christos } 992 1.1 christos 993 1.1 christos case function_record: /* function record */ 994 1.1 christos { 995 1.1 christos record = parse_function_record (file, record, 996 1.1 christos &isa->functions, 997 1.1 christos NULL, 0 /*is-internal */ , 998 1.1 christos model); 999 1.1 christos break; 1000 1.1 christos } 1001 1.1 christos 1002 1.1 christos case internal_record: 1003 1.1 christos { 1004 1.1 christos /* only insert it into the function list if it is unknown */ 1005 1.1 christos function_entry *function = NULL; 1006 1.1 christos record = parse_function_record (file, record, 1007 1.1 christos &isa->functions, 1008 1.1 christos &function, 1 /*is-internal */ , 1009 1.1 christos model); 1010 1.1 christos /* check what was inserted to see if a pseudo-instruction 1011 1.1 christos entry also needs to be created */ 1012 1.1 christos if (function != NULL) 1013 1.1 christos { 1014 1.1 christos insn_entry **insn = NULL; 1015 1.1 christos if (strcmp (function->name, "illegal") == 0) 1016 1.1 christos { 1017 1.1 christos /* illegal function save it away */ 1018 1.1 christos if (isa->illegal_insn != NULL) 1019 1.1 christos { 1020 1.1 christos warning (function->line, 1021 1.1 christos "Multiple illegal instruction definitions\n"); 1022 1.1 christos error (isa->illegal_insn->line, 1023 1.1 christos "Location of first illegal instruction\n"); 1024 1.1 christos } 1025 1.1 christos else 1026 1.1 christos insn = &isa->illegal_insn; 1027 1.1 christos } 1028 1.1 christos if (insn != NULL) 1029 1.1 christos { 1030 1.1 christos *insn = ZALLOC (insn_entry); 1031 1.1 christos (*insn)->line = function->line; 1032 1.1 christos (*insn)->name = function->name; 1033 1.1 christos (*insn)->code = function->code; 1034 1.1 christos } 1035 1.1 christos } 1036 1.1 christos break; 1037 1.1 christos } 1038 1.1 christos 1039 1.1 christos case scratch_record: /* cache macro records */ 1040 1.1 christos case cache_record: 1041 1.1 christos case compute_record: 1042 1.1 christos { 1043 1.1 christos cache_entry *new_cache; 1044 1.1 christos /* parse the cache record */ 1045 1.1 christos if (record->nr_fields < nr_cache_fields) 1046 1.1 christos error (record->line, 1047 1.1 christos "Incorrect nr of fields for scratch/cache/compute record\n"); 1048 1.1 christos /* create it */ 1049 1.1 christos new_cache = ZALLOC (cache_entry); 1050 1.1 christos new_cache->line = record->line; 1051 1.1 christos filter_parse (&new_cache->flags, 1052 1.1 christos record->field[record_filter_flags_field]); 1053 1.1 christos filter_parse (&new_cache->models, 1054 1.1 christos record->field[record_filter_models_field]); 1055 1.1 christos new_cache->type = record->field[cache_typedef_field]; 1056 1.1 christos new_cache->name = record->field[cache_name_field]; 1057 1.1 christos filter_parse (&new_cache->original_fields, 1058 1.1 christos record->field[cache_original_fields_field]); 1059 1.1 christos new_cache->expression = record->field[cache_expression_field]; 1060 1.1 christos /* insert it but only if not filtered out */ 1061 1.1 christos if (!filter_is_subset (options.flags_filter, new_cache->flags)) 1062 1.1 christos { 1063 1.1 christos notify (new_cache->line, 1064 1.1 christos "Discarding cache entry %s - filter flags\n", 1065 1.1 christos new_cache->name); 1066 1.1 christos } 1067 1.1 christos else if (is_filtered_out (options.model_filter, 1068 1.1 christos record-> 1069 1.1 christos field[record_filter_models_field])) 1070 1.1 christos { 1071 1.1 christos notify (new_cache->line, 1072 1.1 christos "Discarding cache entry %s - filter models\n", 1073 1.1 christos new_cache->name); 1074 1.1 christos } 1075 1.1 christos else 1076 1.1 christos { 1077 1.1 christos cache_entry **last; 1078 1.1 christos last = &isa->caches; 1079 1.1 christos while (*last != NULL) 1080 1.1 christos last = &(*last)->next; 1081 1.1 christos *last = new_cache; 1082 1.1 christos } 1083 1.1 christos /* advance things */ 1084 1.1 christos record = table_read (file); 1085 1.1 christos break; 1086 1.1 christos } 1087 1.1 christos 1088 1.1 christos /* model records */ 1089 1.1 christos case model_processor_record: 1090 1.1 christos { 1091 1.1 christos model_entry *new_model; 1092 1.1 christos /* parse the model */ 1093 1.1 christos if (record->nr_fields < nr_model_processor_fields) 1094 1.1 christos error (record->line, 1095 1.1 christos "Incorrect nr of fields for model record\n"); 1096 1.1 christos if (isa->insns != NULL) 1097 1.1 christos error (record->line, "Model appears after first instruction\n"); 1098 1.1 christos new_model = ZALLOC (model_entry); 1099 1.1 christos filter_parse (&new_model->flags, 1100 1.1 christos record->field[record_filter_flags_field]); 1101 1.1 christos new_model->line = record->line; 1102 1.1 christos new_model->name = record->field[model_name_field]; 1103 1.1 christos new_model->full_name = record->field[model_full_name_field]; 1104 1.1 christos new_model->unit_data = record->field[model_unit_data_field]; 1105 1.1 christos /* only insert it if not filtered out */ 1106 1.1 christos if (!filter_is_subset (options.flags_filter, new_model->flags)) 1107 1.1 christos { 1108 1.1 christos notify (new_model->line, 1109 1.1 christos "Discarding processor model %s - filter flags\n", 1110 1.1 christos new_model->name); 1111 1.1 christos } 1112 1.1 christos else if (is_filtered_out (options.model_filter, 1113 1.1 christos record-> 1114 1.1 christos field[record_filter_models_field])) 1115 1.1 christos { 1116 1.1 christos notify (new_model->line, 1117 1.1 christos "Discarding processor model %s - filter models\n", 1118 1.1 christos new_model->name); 1119 1.1 christos } 1120 1.1 christos else if (filter_is_member (model->processors, new_model->name)) 1121 1.1 christos { 1122 1.1 christos error (new_model->line, "Duplicate processor model %s\n", 1123 1.1 christos new_model->name); 1124 1.1 christos } 1125 1.1 christos else 1126 1.1 christos { 1127 1.1 christos model_entry **last; 1128 1.1 christos last = &model->models; 1129 1.1 christos while (*last != NULL) 1130 1.1 christos last = &(*last)->next; 1131 1.1 christos *last = new_model; 1132 1.1 christos /* count it */ 1133 1.1 christos model->nr_models++; 1134 1.1 christos filter_parse (&model->processors, new_model->name); 1135 1.1 christos } 1136 1.1 christos /* advance things */ 1137 1.1 christos record = table_read (file); 1138 1.1 christos } 1139 1.1 christos break; 1140 1.1 christos 1141 1.1 christos case model_macro_record: 1142 1.1 christos record = parse_model_data_record (isa, file, record, 1143 1.1 christos nr_model_macro_fields, 1144 1.1 christos &model->macros); 1145 1.1 christos break; 1146 1.1 christos 1147 1.1 christos case model_data_record: 1148 1.1 christos record = parse_model_data_record (isa, file, record, 1149 1.1 christos nr_model_data_fields, 1150 1.1 christos &model->data); 1151 1.1 christos break; 1152 1.1 christos 1153 1.1 christos case model_static_record: 1154 1.1 christos record = parse_function_record (file, record, 1155 1.1 christos &model->statics, 1156 1.1 christos NULL, 0 /*is internal */ , 1157 1.1 christos model); 1158 1.1 christos break; 1159 1.1 christos 1160 1.1 christos case model_internal_record: 1161 1.1 christos record = parse_function_record (file, record, 1162 1.1 christos &model->internals, 1163 1.1 christos NULL, 1 /*is internal */ , 1164 1.1 christos model); 1165 1.1 christos break; 1166 1.1 christos 1167 1.1 christos case model_function_record: 1168 1.1 christos record = parse_function_record (file, record, 1169 1.1 christos &model->functions, 1170 1.1 christos NULL, 0 /*is internal */ , 1171 1.1 christos model); 1172 1.1 christos break; 1173 1.1 christos 1174 1.1 christos case insn_record: /* instruction records */ 1175 1.1 christos { 1176 1.1 christos insn_entry *new_insn; 1177 1.1 christos char *format; 1178 1.1 christos /* parse the instruction */ 1179 1.1 christos if (record->nr_fields < nr_insn_fields) 1180 1.1 christos error (record->line, 1181 1.1 christos "Incorrect nr of fields for insn record\n"); 1182 1.1 christos new_insn = ZALLOC (insn_entry); 1183 1.1 christos new_insn->line = record->line; 1184 1.1 christos filter_parse (&new_insn->flags, 1185 1.1 christos record->field[record_filter_flags_field]); 1186 1.1 christos /* save the format field. Can't parse it until after the 1187 1.1 christos filter-out checks. Could be filtered out because the 1188 1.1 christos format is invalid */ 1189 1.1 christos format = record->field[insn_word_field]; 1190 1.1 christos new_insn->format_name = record->field[insn_format_name_field]; 1191 1.1 christos if (options.format_name_filter != NULL 1192 1.1 christos && !filter_is_member (options.format_name_filter, 1193 1.1 christos new_insn->format_name)) 1194 1.1 christos error (new_insn->line, 1195 1.1 christos "Unreconized instruction format name `%s'\n", 1196 1.1 christos new_insn->format_name); 1197 1.1 christos filter_parse (&new_insn->options, 1198 1.1 christos record->field[insn_options_field]); 1199 1.1 christos new_insn->name = record->field[insn_name_field]; 1200 1.1 christos record = table_read (file); 1201 1.1 christos /* Parse any model/assember records */ 1202 1.1 christos new_insn->nr_models = model->nr_models; 1203 1.1 christos new_insn->model = 1204 1.1 christos NZALLOC (insn_model_entry *, model->nr_models + 1); 1205 1.1 christos while (record != NULL) 1206 1.1 christos { 1207 1.1 christos if (record_prefix_is (record, '*', nr_insn_model_fields)) 1208 1.1 christos parse_insn_model_record (file, record, new_insn, model); 1209 1.1 christos else 1210 1.1 christos if (record_prefix_is (record, '"', nr_insn_mnemonic_fields)) 1211 1.1 christos parse_insn_mnemonic_record (file, record, new_insn); 1212 1.1 christos else 1213 1.1 christos break; 1214 1.1 christos /* advance */ 1215 1.1 christos record = table_read (file); 1216 1.1 christos } 1217 1.1 christos /* Parse the code record */ 1218 1.1 christos if (record != NULL && record->type == table_code_entry) 1219 1.1 christos { 1220 1.1 christos new_insn->code = record; 1221 1.1 christos record = table_read (file); 1222 1.1 christos } 1223 1.1 christos else if (options.warn.unimplemented) 1224 1.1 christos notify (new_insn->line, "unimplemented\n"); 1225 1.1 christos /* insert it */ 1226 1.1 christos if (!filter_is_subset (options.flags_filter, new_insn->flags)) 1227 1.1 christos { 1228 1.1 christos if (options.warn.discard) 1229 1.1 christos notify (new_insn->line, 1230 1.1 christos "Discarding instruction %s (flags-filter)\n", 1231 1.1 christos new_insn->name); 1232 1.1 christos } 1233 1.1 christos else if (new_insn->processors != NULL 1234 1.1 christos && options.model_filter != NULL 1235 1.1 christos && !filter_is_common (options.model_filter, 1236 1.1 christos new_insn->processors)) 1237 1.1 christos { 1238 1.1 christos /* only discard an instruction based in the processor 1239 1.1 christos model when both the instruction and the options are 1240 1.1 christos nonempty */ 1241 1.1 christos if (options.warn.discard) 1242 1.1 christos notify (new_insn->line, 1243 1.1 christos "Discarding instruction %s (processor-model)\n", 1244 1.1 christos new_insn->name); 1245 1.1 christos } 1246 1.1 christos else 1247 1.1 christos { 1248 1.1 christos insn_entry **last; 1249 1.1 christos /* finish the parsing */ 1250 1.1 christos parse_insn_words (new_insn, format); 1251 1.1 christos /* append it */ 1252 1.1 christos last = &isa->insns; 1253 1.1 christos while (*last) 1254 1.1 christos last = &(*last)->next; 1255 1.1 christos *last = new_insn; 1256 1.1 christos /* update global isa counters */ 1257 1.1 christos isa->nr_insns++; 1258 1.1 christos if (isa->max_nr_words < new_insn->nr_words) 1259 1.1 christos isa->max_nr_words = new_insn->nr_words; 1260 1.1 christos filter_add (&isa->flags, new_insn->flags); 1261 1.1 christos filter_add (&isa->options, new_insn->options); 1262 1.1 christos } 1263 1.1 christos break; 1264 1.1 christos } 1265 1.1 christos 1266 1.1 christos case define_record: 1267 1.1 christos record = parse_macro_record (file, record); 1268 1.1 christos break; 1269 1.1 christos 1270 1.1 christos case unknown_record: 1271 1.1 christos case code_record: 1272 1.1 christos error (record->line, "Unknown or unexpected entry\n"); 1273 1.1 christos 1274 1.1 christos 1275 1.1 christos } 1276 1.1 christos } 1277 1.1 christos return isa; 1278 1.1 christos } 1279 1.1 christos 1280 1.1 christos 1281 1.1 christos void 1282 1.1.1.9 christos print_insn_words (lf *file, const insn_entry *insn) 1283 1.1 christos { 1284 1.1 christos insn_word_entry *word = insn->words; 1285 1.1 christos if (word != NULL) 1286 1.1 christos { 1287 1.1 christos while (1) 1288 1.1 christos { 1289 1.1 christos insn_field_entry *field = word->first; 1290 1.1 christos while (1) 1291 1.1 christos { 1292 1.1.1.2 christos insn_field_cond *cond; 1293 1.1.1.2 christos 1294 1.1 christos if (options.insn_specifying_widths) 1295 1.1 christos lf_printf (file, "%d.", field->width); 1296 1.1 christos else 1297 1.1 christos lf_printf (file, "%d.", 1298 1.1 christos i2target (options.hi_bit_nr, field->first)); 1299 1.1 christos switch (field->type) 1300 1.1 christos { 1301 1.1 christos case insn_field_invalid: 1302 1.1 christos ASSERT (0); 1303 1.1 christos break; 1304 1.1 christos case insn_field_int: 1305 1.1 christos lf_printf (file, "0x%lx", (long) field->val_int); 1306 1.1 christos break; 1307 1.1 christos case insn_field_reserved: 1308 1.1 christos lf_printf (file, "/"); 1309 1.1 christos break; 1310 1.1 christos case insn_field_wild: 1311 1.1 christos lf_printf (file, "*"); 1312 1.1 christos break; 1313 1.1 christos case insn_field_string: 1314 1.1 christos lf_printf (file, "%s", field->val_string); 1315 1.1.1.2 christos 1316 1.1.1.2 christos if (field->conditions == NULL) 1317 1.1.1.2 christos break; 1318 1.1.1.2 christos 1319 1.1.1.2 christos if (field->conditions->test == insn_field_cond_eq) 1320 1.1.1.2 christos { 1321 1.1.1.2 christos if (field->conditions->type == insn_field_cond_value) 1322 1.1.1.2 christos lf_printf (file, "=%ld", 1323 1.1.1.2 christos (long) field->conditions->value); 1324 1.1.1.2 christos else 1325 1.1.1.2 christos lf_printf (file, "=%s", field->conditions->string); 1326 1.1.1.2 christos 1327 1.1.1.2 christos /* There can be only one equality condition. */ 1328 1.1.1.2 christos ASSERT (field->conditions->next == NULL); 1329 1.1.1.2 christos break; 1330 1.1.1.2 christos } 1331 1.1.1.2 christos 1332 1.1.1.2 christos for (cond = field->conditions; 1333 1.1.1.2 christos cond != NULL; 1334 1.1.1.2 christos cond = cond->next) 1335 1.1.1.2 christos { 1336 1.1.1.2 christos ASSERT (cond->test == insn_field_cond_ne); 1337 1.1.1.2 christos 1338 1.1.1.2 christos if (cond->type == insn_field_cond_value) 1339 1.1.1.2 christos lf_printf (file, "!%ld", (long) cond->value); 1340 1.1.1.2 christos else 1341 1.1.1.2 christos lf_printf (file, "!%s", cond->string); 1342 1.1.1.2 christos } 1343 1.1 christos break; 1344 1.1 christos } 1345 1.1 christos if (field == word->last) 1346 1.1 christos break; 1347 1.1 christos field = field->next; 1348 1.1 christos lf_printf (file, ","); 1349 1.1 christos } 1350 1.1 christos word = word->next; 1351 1.1 christos if (word == NULL) 1352 1.1 christos break; 1353 1.1 christos lf_printf (file, "+"); 1354 1.1 christos } 1355 1.1 christos } 1356 1.1 christos } 1357 1.1 christos 1358 1.1 christos 1360 1.1 christos 1361 1.1 christos void 1362 1.1.1.9 christos function_entry_traverse (lf *file, 1363 1.1 christos const function_entry *functions, 1364 1.1 christos function_entry_handler * handler, void *data) 1365 1.1.1.9 christos { 1366 1.1 christos const function_entry *function; 1367 1.1 christos for (function = functions; function != NULL; function = function->next) 1368 1.1 christos { 1369 1.1 christos handler (file, function, data); 1370 1.1 christos } 1371 1.1 christos } 1372 1.1 christos 1373 1.1 christos void 1374 1.1.1.9 christos insn_table_traverse_insn (lf *file, 1375 1.1 christos const insn_table *isa, 1376 1.1 christos insn_entry_handler * handler, void *data) 1377 1.1.1.9 christos { 1378 1.1 christos const insn_entry *insn; 1379 1.1 christos for (insn = isa->insns; insn != NULL; insn = insn->next) 1380 1.1 christos { 1381 1.1 christos handler (file, isa, insn, data); 1382 1.1 christos } 1383 1.1 christos } 1384 1.1 christos 1385 1.1 christos 1387 1.1.1.9 christos static void 1388 1.1.1.9 christos dump_function_entry (lf *file, 1389 1.1.1.9 christos const char *prefix, 1390 1.1 christos const function_entry *entry, 1391 1.1.1.9 christos const char *suffix) 1392 1.1 christos { 1393 1.1 christos lf_printf (file, "%s(function_entry *) %p", prefix, entry); 1394 1.1 christos if (entry != NULL) 1395 1.1 christos { 1396 1.1 christos dump_line_ref (file, "\n(line ", entry->line, ")"); 1397 1.1 christos dump_filter (file, "\n(flags ", entry->flags, ")"); 1398 1.1 christos lf_printf (file, "\n(type \"%s\")", entry->type); 1399 1.1 christos lf_printf (file, "\n(name \"%s\")", entry->name); 1400 1.1 christos lf_printf (file, "\n(param \"%s\")", entry->param); 1401 1.1.1.9 christos dump_table_entry (file, "\n(code ", entry->code, ")"); 1402 1.1 christos lf_printf (file, "\n(is_internal %d)", entry->is_internal); 1403 1.1 christos lf_printf (file, "\n(next %p)", entry->next); 1404 1.1 christos } 1405 1.1 christos lf_printf (file, "%s", suffix); 1406 1.1 christos } 1407 1.1 christos 1408 1.1.1.9 christos static void 1409 1.1.1.9 christos dump_function_entries (lf *file, 1410 1.1.1.9 christos const char *prefix, 1411 1.1 christos const function_entry *entry, 1412 1.1 christos const char *suffix) 1413 1.1 christos { 1414 1.1 christos lf_printf (file, "%s", prefix); 1415 1.1 christos lf_indent (file, +1); 1416 1.1 christos while (entry != NULL) 1417 1.1 christos { 1418 1.1 christos dump_function_entry (file, "\n(", entry, ")"); 1419 1.1 christos entry = entry->next; 1420 1.1 christos } 1421 1.1 christos lf_indent (file, -1); 1422 1.1 christos lf_printf (file, "%s", suffix); 1423 1.1 christos } 1424 1.1 christos 1425 1.1 christos static char * 1426 1.1 christos cache_entry_type_to_str (cache_entry_type type) 1427 1.1 christos { 1428 1.1 christos switch (type) 1429 1.1 christos { 1430 1.1 christos case scratch_value: 1431 1.1 christos return "scratch"; 1432 1.1 christos case cache_value: 1433 1.1 christos return "cache"; 1434 1.1 christos case compute_value: 1435 1.1 christos return "compute"; 1436 1.1 christos } 1437 1.1 christos ERROR ("Bad switch"); 1438 1.1 christos return 0; 1439 1.1 christos } 1440 1.1.1.9 christos 1441 1.1.1.9 christos static void 1442 1.1.1.9 christos dump_cache_entry (lf *file, 1443 1.1.1.9 christos const char *prefix, 1444 1.1 christos const cache_entry *entry, 1445 1.1.1.9 christos const char *suffix) 1446 1.1 christos { 1447 1.1 christos lf_printf (file, "%s(cache_entry *) %p", prefix, entry); 1448 1.1 christos if (entry != NULL) 1449 1.1 christos { 1450 1.1 christos dump_line_ref (file, "\n(line ", entry->line, ")"); 1451 1.1 christos dump_filter (file, "\n(flags ", entry->flags, ")"); 1452 1.1 christos lf_printf (file, "\n(entry_type \"%s\")", 1453 1.1 christos cache_entry_type_to_str (entry->entry_type)); 1454 1.1 christos lf_printf (file, "\n(name \"%s\")", entry->name); 1455 1.1 christos dump_filter (file, "\n(original_fields ", entry->original_fields, ")"); 1456 1.1.1.9 christos lf_printf (file, "\n(type \"%s\")", entry->type); 1457 1.1 christos lf_printf (file, "\n(expression \"%s\")", entry->expression); 1458 1.1 christos lf_printf (file, "\n(next %p)", entry->next); 1459 1.1 christos } 1460 1.1 christos lf_printf (file, "%s", suffix); 1461 1.1 christos } 1462 1.1.1.9 christos 1463 1.1.1.9 christos void 1464 1.1.1.9 christos dump_cache_entries (lf *file, 1465 1.1.1.9 christos const char *prefix, 1466 1.1 christos const cache_entry *entry, 1467 1.1 christos const char *suffix) 1468 1.1 christos { 1469 1.1 christos lf_printf (file, "%s", prefix); 1470 1.1 christos lf_indent (file, +1); 1471 1.1 christos while (entry != NULL) 1472 1.1 christos { 1473 1.1 christos dump_cache_entry (file, "\n(", entry, ")"); 1474 1.1 christos entry = entry->next; 1475 1.1 christos } 1476 1.1 christos lf_indent (file, -1); 1477 1.1 christos lf_printf (file, "%s", suffix); 1478 1.1 christos } 1479 1.1.1.9 christos 1480 1.1.1.9 christos static void 1481 1.1.1.9 christos dump_model_data (lf *file, 1482 1.1.1.9 christos const char *prefix, 1483 1.1 christos const model_data *entry, 1484 1.1.1.9 christos const char *suffix) 1485 1.1 christos { 1486 1.1 christos lf_printf (file, "%s(model_data *) %p", prefix, entry); 1487 1.1 christos if (entry != NULL) 1488 1.1 christos { 1489 1.1 christos lf_indent (file, +1); 1490 1.1 christos dump_line_ref (file, "\n(line ", entry->line, ")"); 1491 1.1 christos dump_filter (file, "\n(flags ", entry->flags, ")"); 1492 1.1.1.9 christos dump_table_entry (file, "\n(entry ", entry->entry, ")"); 1493 1.1 christos dump_table_entry (file, "\n(code ", entry->code, ")"); 1494 1.1 christos lf_printf (file, "\n(next %p)", entry->next); 1495 1.1 christos lf_indent (file, -1); 1496 1.1 christos } 1497 1.1 christos lf_printf (file, "%s", prefix); 1498 1.1 christos } 1499 1.1.1.9 christos 1500 1.1.1.9 christos static void 1501 1.1.1.9 christos dump_model_datas (lf *file, 1502 1.1.1.9 christos const char *prefix, 1503 1.1 christos const model_data *entry, 1504 1.1 christos const char *suffix) 1505 1.1 christos { 1506 1.1 christos lf_printf (file, "%s", prefix); 1507 1.1 christos lf_indent (file, +1); 1508 1.1 christos while (entry != NULL) 1509 1.1 christos { 1510 1.1 christos dump_model_data (file, "\n(", entry, ")"); 1511 1.1 christos entry = entry->next; 1512 1.1 christos } 1513 1.1 christos lf_indent (file, -1); 1514 1.1 christos lf_printf (file, "%s", suffix); 1515 1.1 christos } 1516 1.1.1.9 christos 1517 1.1.1.9 christos static void 1518 1.1.1.9 christos dump_model_entry (lf *file, 1519 1.1.1.9 christos const char *prefix, 1520 1.1 christos const model_entry *entry, 1521 1.1.1.9 christos const char *suffix) 1522 1.1 christos { 1523 1.1 christos lf_printf (file, "%s(model_entry *) %p", prefix, entry); 1524 1.1 christos if (entry != NULL) 1525 1.1 christos { 1526 1.1 christos lf_indent (file, +1); 1527 1.1 christos dump_line_ref (file, "\n(line ", entry->line, ")"); 1528 1.1 christos dump_filter (file, "\n(flags ", entry->flags, ")"); 1529 1.1 christos lf_printf (file, "\n(name \"%s\")", entry->name); 1530 1.1.1.9 christos lf_printf (file, "\n(full_name \"%s\")", entry->full_name); 1531 1.1 christos lf_printf (file, "\n(unit_data \"%s\")", entry->unit_data); 1532 1.1 christos lf_printf (file, "\n(next %p)", entry->next); 1533 1.1 christos lf_indent (file, -1); 1534 1.1 christos } 1535 1.1 christos lf_printf (file, "%s", prefix); 1536 1.1 christos } 1537 1.1.1.9 christos 1538 1.1.1.9 christos static void 1539 1.1.1.9 christos dump_model_entries (lf *file, 1540 1.1.1.9 christos const char *prefix, 1541 1.1 christos const model_entry *entry, 1542 1.1 christos const char *suffix) 1543 1.1 christos { 1544 1.1 christos lf_printf (file, "%s", prefix); 1545 1.1 christos lf_indent (file, +1); 1546 1.1 christos while (entry != NULL) 1547 1.1 christos { 1548 1.1 christos dump_model_entry (file, "\n(", entry, ")"); 1549 1.1 christos entry = entry->next; 1550 1.1 christos } 1551 1.1 christos lf_indent (file, -1); 1552 1.1 christos lf_printf (file, "%s", suffix); 1553 1.1 christos } 1554 1.1 christos 1555 1.1.1.9 christos 1556 1.1.1.9 christos static void 1557 1.1.1.9 christos dump_model_table (lf *file, 1558 1.1.1.9 christos const char *prefix, 1559 1.1 christos const model_table *entry, 1560 1.1.1.9 christos const char *suffix) 1561 1.1 christos { 1562 1.1 christos lf_printf (file, "%s(model_table *) %p", prefix, entry); 1563 1.1 christos if (entry != NULL) 1564 1.1 christos { 1565 1.1 christos lf_indent (file, +1); 1566 1.1 christos dump_filter (file, "\n(processors ", entry->processors, ")"); 1567 1.1 christos lf_printf (file, "\n(nr_models %d)", entry->nr_models); 1568 1.1 christos dump_model_entries (file, "\n(models ", entry->models, ")"); 1569 1.1 christos dump_model_datas (file, "\n(macros ", entry->macros, ")"); 1570 1.1 christos dump_model_datas (file, "\n(data ", entry->data, ")"); 1571 1.1 christos dump_function_entries (file, "\n(statics ", entry->statics, ")"); 1572 1.1 christos dump_function_entries (file, "\n(internals ", entry->functions, ")"); 1573 1.1 christos dump_function_entries (file, "\n(functions ", entry->functions, ")"); 1574 1.1 christos lf_indent (file, -1); 1575 1.1 christos } 1576 1.1 christos lf_printf (file, "%s", suffix); 1577 1.1 christos } 1578 1.1 christos 1579 1.1 christos 1580 1.1 christos static char * 1581 1.1 christos insn_field_type_to_str (insn_field_type type) 1582 1.1 christos { 1583 1.1 christos switch (type) 1584 1.1 christos { 1585 1.1 christos case insn_field_invalid: 1586 1.1 christos ASSERT (0); 1587 1.1 christos return "(invalid)"; 1588 1.1 christos case insn_field_int: 1589 1.1 christos return "int"; 1590 1.1 christos case insn_field_reserved: 1591 1.1 christos return "reserved"; 1592 1.1 christos case insn_field_wild: 1593 1.1 christos return "wild"; 1594 1.1 christos case insn_field_string: 1595 1.1 christos return "string"; 1596 1.1 christos } 1597 1.1 christos ERROR ("bad switch"); 1598 1.1 christos return 0; 1599 1.1 christos } 1600 1.1 christos 1601 1.1.1.9 christos void 1602 1.1.1.9 christos dump_insn_field (lf *file, 1603 1.1.1.9 christos const char *prefix, 1604 1.1 christos const insn_field_entry *field, 1605 1.1 christos const char *suffix) 1606 1.1.1.9 christos { 1607 1.1 christos char *sep = " "; 1608 1.1 christos lf_printf (file, "%s(insn_field_entry *) %p", prefix, field); 1609 1.1 christos if (field != NULL) 1610 1.1 christos { 1611 1.1 christos lf_indent (file, +1); 1612 1.1 christos lf_printf (file, "%s(first %d)", sep, field->first); 1613 1.1 christos lf_printf (file, "%s(last %d)", sep, field->last); 1614 1.1 christos lf_printf (file, "%s(width %d)", sep, field->width); 1615 1.1 christos lf_printf (file, "%s(type %s)", sep, 1616 1.1 christos insn_field_type_to_str (field->type)); 1617 1.1 christos switch (field->type) 1618 1.1 christos { 1619 1.1 christos case insn_field_invalid: 1620 1.1 christos ASSERT (0); 1621 1.1 christos break; 1622 1.1 christos case insn_field_int: 1623 1.1 christos lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int); 1624 1.1 christos break; 1625 1.1 christos case insn_field_reserved: 1626 1.1 christos /* nothing output */ 1627 1.1 christos break; 1628 1.1 christos case insn_field_wild: 1629 1.1 christos /* nothing output */ 1630 1.1 christos break; 1631 1.1 christos case insn_field_string: 1632 1.1 christos lf_printf (file, "%s(val \"%s\")", sep, field->val_string); 1633 1.1.1.9 christos break; 1634 1.1.1.9 christos } 1635 1.1 christos lf_printf (file, "%s(next %p)", sep, field->next); 1636 1.1 christos lf_printf (file, "%s(prev %p)", sep, field->prev); 1637 1.1 christos lf_indent (file, -1); 1638 1.1 christos } 1639 1.1 christos lf_printf (file, "%s", suffix); 1640 1.1 christos } 1641 1.1 christos 1642 1.1.1.9 christos void 1643 1.1.1.9 christos dump_insn_word_entry (lf *file, 1644 1.1.1.9 christos const char *prefix, 1645 1.1 christos const insn_word_entry *word, 1646 1.1.1.9 christos const char *suffix) 1647 1.1 christos { 1648 1.1 christos lf_printf (file, "%s(insn_word_entry *) %p", prefix, word); 1649 1.1 christos if (word != NULL) 1650 1.1 christos { 1651 1.1 christos int i; 1652 1.1.1.9 christos insn_field_entry *field; 1653 1.1.1.9 christos lf_indent (file, +1); 1654 1.1 christos lf_printf (file, "\n(first %p)", word->first); 1655 1.1 christos lf_printf (file, "\n(last %p)", word->last); 1656 1.1.1.9 christos lf_printf (file, "\n(bit"); 1657 1.1 christos for (i = 0; i < options.insn_bit_size; i++) 1658 1.1.1.9 christos lf_printf (file, "\n ((value %d) (mask %d) (field %p))", 1659 1.1 christos word->bit[i]->value, word->bit[i]->mask, 1660 1.1 christos word->bit[i]->field); 1661 1.1 christos lf_printf (file, ")"); 1662 1.1 christos for (field = word->first; field != NULL; field = field->next) 1663 1.1.1.9 christos dump_insn_field (file, "\n(", field, ")"); 1664 1.1 christos dump_filter (file, "\n(field_names ", word->field_names, ")"); 1665 1.1 christos lf_printf (file, "\n(next %p)", word->next); 1666 1.1 christos lf_indent (file, -1); 1667 1.1 christos } 1668 1.1 christos lf_printf (file, "%s", suffix); 1669 1.1 christos } 1670 1.1 christos 1671 1.1.1.9 christos static void 1672 1.1.1.9 christos dump_insn_word_entries (lf *file, 1673 1.1.1.9 christos const char *prefix, 1674 1.1 christos const insn_word_entry *word, 1675 1.1 christos const char *suffix) 1676 1.1 christos { 1677 1.1 christos lf_printf (file, "%s", prefix); 1678 1.1 christos while (word != NULL) 1679 1.1 christos { 1680 1.1 christos dump_insn_word_entry (file, "\n(", word, ")"); 1681 1.1 christos word = word->next; 1682 1.1 christos } 1683 1.1 christos lf_printf (file, "%s", suffix); 1684 1.1 christos } 1685 1.1 christos 1686 1.1.1.9 christos static void 1687 1.1.1.9 christos dump_insn_model_entry (lf *file, 1688 1.1.1.9 christos const char *prefix, 1689 1.1 christos const insn_model_entry *model, 1690 1.1.1.9 christos const char *suffix) 1691 1.1 christos { 1692 1.1 christos lf_printf (file, "%s(insn_model_entry *) %p", prefix, model); 1693 1.1 christos if (model != NULL) 1694 1.1 christos { 1695 1.1 christos lf_indent (file, +1); 1696 1.1 christos dump_line_ref (file, "\n(line ", model->line, ")"); 1697 1.1 christos dump_filter (file, "\n(names ", model->names, ")"); 1698 1.1.1.9 christos lf_printf (file, "\n(full_name \"%s\")", model->full_name); 1699 1.1.1.9 christos lf_printf (file, "\n(unit_data \"%s\")", model->unit_data); 1700 1.1 christos lf_printf (file, "\n(insn (insn_entry *) %p)", model->insn); 1701 1.1 christos lf_printf (file, "\n(next (insn_model_entry *) %p)", model->next); 1702 1.1 christos lf_indent (file, -1); 1703 1.1 christos } 1704 1.1 christos lf_printf (file, "%s", suffix); 1705 1.1 christos } 1706 1.1 christos 1707 1.1.1.9 christos static void 1708 1.1.1.9 christos dump_insn_model_entries (lf *file, 1709 1.1.1.9 christos const char *prefix, 1710 1.1 christos const insn_model_entry *model, 1711 1.1 christos const char *suffix) 1712 1.1 christos { 1713 1.1 christos lf_printf (file, "%s", prefix); 1714 1.1 christos while (model != NULL) 1715 1.1 christos { 1716 1.1 christos dump_insn_model_entry (file, "\n", model, ""); 1717 1.1 christos model = model->next; 1718 1.1 christos } 1719 1.1 christos lf_printf (file, "%s", suffix); 1720 1.1 christos } 1721 1.1 christos 1722 1.1 christos 1723 1.1.1.9 christos static void 1724 1.1.1.9 christos dump_insn_mnemonic_entry (lf *file, 1725 1.1.1.9 christos const char *prefix, 1726 1.1 christos const insn_mnemonic_entry *mnemonic, 1727 1.1.1.9 christos const char *suffix) 1728 1.1 christos { 1729 1.1 christos lf_printf (file, "%s(insn_mnemonic_entry *) %p", prefix, mnemonic); 1730 1.1 christos if (mnemonic != NULL) 1731 1.1 christos { 1732 1.1 christos lf_indent (file, +1); 1733 1.1 christos dump_line_ref (file, "\n(line ", mnemonic->line, ")"); 1734 1.1.1.9 christos lf_printf (file, "\n(format \"%s\")", mnemonic->format); 1735 1.1.1.9 christos lf_printf (file, "\n(condition \"%s\")", mnemonic->condition); 1736 1.1 christos lf_printf (file, "\n(insn (insn_entry *) %p)", mnemonic->insn); 1737 1.1 christos lf_printf (file, "\n(next (insn_mnemonic_entry *) %p)", mnemonic->next); 1738 1.1 christos lf_indent (file, -1); 1739 1.1 christos } 1740 1.1 christos lf_printf (file, "%s", suffix); 1741 1.1 christos } 1742 1.1 christos 1743 1.1.1.9 christos static void 1744 1.1.1.9 christos dump_insn_mnemonic_entries (lf *file, 1745 1.1.1.9 christos const char *prefix, 1746 1.1 christos const insn_mnemonic_entry *mnemonic, 1747 1.1 christos const char *suffix) 1748 1.1 christos { 1749 1.1 christos lf_printf (file, "%s", prefix); 1750 1.1 christos while (mnemonic != NULL) 1751 1.1 christos { 1752 1.1 christos dump_insn_mnemonic_entry (file, "\n", mnemonic, ""); 1753 1.1 christos mnemonic = mnemonic->next; 1754 1.1 christos } 1755 1.1 christos lf_printf (file, "%s", suffix); 1756 1.1 christos } 1757 1.1.1.9 christos 1758 1.1.1.9 christos void 1759 1.1.1.9 christos dump_insn_entry (lf *file, 1760 1.1.1.9 christos const char *prefix, 1761 1.1 christos const insn_entry *entry, 1762 1.1.1.9 christos const char *suffix) 1763 1.1 christos { 1764 1.1 christos lf_printf (file, "%s(insn_entry *) %p", prefix, entry); 1765 1.1 christos if (entry != NULL) 1766 1.1 christos { 1767 1.1 christos int i; 1768 1.1 christos lf_indent (file, +1); 1769 1.1 christos dump_line_ref (file, "\n(line ", entry->line, ")"); 1770 1.1 christos dump_filter (file, "\n(flags ", entry->flags, ")"); 1771 1.1 christos lf_printf (file, "\n(nr_words %d)", entry->nr_words); 1772 1.1 christos dump_insn_word_entries (file, "\n(words ", entry->words, ")"); 1773 1.1.1.9 christos lf_printf (file, "\n(word"); 1774 1.1 christos for (i = 0; i < entry->nr_models; i++) 1775 1.1 christos lf_printf (file, " %p", entry->word[i]); 1776 1.1 christos lf_printf (file, ")"); 1777 1.1 christos dump_filter (file, "\n(field_names ", entry->field_names, ")"); 1778 1.1 christos lf_printf (file, "\n(format_name \"%s\")", entry->format_name); 1779 1.1 christos dump_filter (file, "\n(options ", entry->options, ")"); 1780 1.1 christos lf_printf (file, "\n(name \"%s\")", entry->name); 1781 1.1 christos lf_printf (file, "\n(nr_models %d)", entry->nr_models); 1782 1.1 christos dump_insn_model_entries (file, "\n(models ", entry->models, ")"); 1783 1.1.1.9 christos lf_printf (file, "\n(model"); 1784 1.1 christos for (i = 0; i < entry->nr_models; i++) 1785 1.1 christos lf_printf (file, " %p", entry->model[i]); 1786 1.1 christos lf_printf (file, ")"); 1787 1.1 christos dump_filter (file, "\n(processors ", entry->processors, ")"); 1788 1.1 christos dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics, 1789 1.1.1.9 christos ")"); 1790 1.1 christos dump_table_entry (file, "\n(code ", entry->code, ")"); 1791 1.1 christos lf_printf (file, "\n(next %p)", entry->next); 1792 1.1 christos lf_indent (file, -1); 1793 1.1 christos } 1794 1.1 christos lf_printf (file, "%s", suffix); 1795 1.1 christos } 1796 1.1.1.9 christos 1797 1.1.1.9 christos static void 1798 1.1.1.9 christos dump_insn_entries (lf *file, 1799 1.1.1.9 christos const char *prefix, 1800 1.1 christos const insn_entry *entry, 1801 1.1 christos const char *suffix) 1802 1.1 christos { 1803 1.1 christos lf_printf (file, "%s", prefix); 1804 1.1 christos lf_indent (file, +1); 1805 1.1 christos while (entry != NULL) 1806 1.1 christos { 1807 1.1 christos dump_insn_entry (file, "\n(", entry, ")"); 1808 1.1 christos entry = entry->next; 1809 1.1 christos } 1810 1.1 christos lf_indent (file, -1); 1811 1.1 christos lf_printf (file, "%s", suffix); 1812 1.1 christos } 1813 1.1 christos 1814 1.1.1.9 christos 1815 1.1.1.9 christos void 1816 1.1.1.9 christos dump_insn_table (lf *file, 1817 1.1.1.9 christos const char *prefix, 1818 1.1 christos const insn_table *isa, 1819 1.1.1.9 christos const char *suffix) 1820 1.1 christos { 1821 1.1 christos lf_printf (file, "%s(insn_table *) %p", prefix, isa); 1822 1.1 christos if (isa != NULL) 1823 1.1 christos { 1824 1.1 christos lf_indent (file, +1); 1825 1.1 christos dump_cache_entries (file, "\n(caches ", isa->caches, ")"); 1826 1.1 christos lf_printf (file, "\n(nr_insns %d)", isa->nr_insns); 1827 1.1 christos lf_printf (file, "\n(max_nr_words %d)", isa->max_nr_words); 1828 1.1 christos dump_insn_entries (file, "\n(insns ", isa->insns, ")"); 1829 1.1 christos dump_function_entries (file, "\n(functions ", isa->functions, ")"); 1830 1.1 christos dump_insn_entry (file, "\n(illegal_insn ", isa->illegal_insn, ")"); 1831 1.1 christos dump_model_table (file, "\n(model ", isa->model, ")"); 1832 1.1 christos dump_filter (file, "\n(flags ", isa->flags, ")"); 1833 1.1 christos dump_filter (file, "\n(options ", isa->options, ")"); 1834 1.1 christos lf_indent (file, -1); 1835 1.1 christos } 1836 1.1 christos lf_printf (file, "%s", suffix); 1837 1.1 christos } 1838 1.1 christos 1839 1.1 christos #ifdef MAIN 1840 1.1 christos 1841 1.1 christos igen_options options; 1842 1.1 christos 1843 1.1 christos int 1844 1.1 christos main (int argc, char **argv) 1845 1.1 christos { 1846 1.1 christos insn_table *isa; 1847 1.1.1.9 christos lf *l; 1848 1.1 christos 1849 1.1 christos INIT_OPTIONS (); 1850 1.1 christos 1851 1.1 christos if (argc == 3) 1852 1.1 christos filter_parse (&options.flags_filter, argv[2]); 1853 1.1 christos else if (argc != 2) 1854 1.1 christos error (NULL, "Usage: insn <insn-table> [ <filter-in> ]\n"); 1855 1.1 christos 1856 1.1 christos isa = load_insn_table (argv[1], NULL); 1857 1.1 christos l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn"); 1858 1.1 christos dump_insn_table (l, "(isa ", isa, ")\n"); 1859 1.1 christos 1860 1.1 christos return 0; 1861 1.1 christos } 1862 1863 #endif 1864