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