]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/igen/ld-insn.c
Switch the license of all files explicitly copyright the FSF
[thirdparty/binutils-gdb.git] / sim / igen / ld-insn.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
6aba47ca 3 Copyright 2002, 2007 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 *
4e0bf4c4 31parse_insn_word (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 */
206 unsigned64 val = 0;
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,
451 "Conditional `%s' of field `%s' should be of size %s\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;
852 char *name = "";
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 }
877#if 0
878 /* for some reason record the max length of any
879 function unit field */
880 int len = strlen (insn_model_ptr->field[insn_model_fields]);
881 if (model->max_model_fields_len < len)
882 model->max_model_fields_len = len;
883#endif
884 /* link it in */
885 last_insn_model = &insn->models;
886 while ((*last_insn_model) != NULL)
887 last_insn_model = &(*last_insn_model)->next;
888 *last_insn_model = new_insn_model;
889}
890
891
892static void
893parse_insn_mnemonic_record (table *file,
4e0bf4c4 894 table_entry *record, insn_entry * insn)
c906108c
SS
895{
896 insn_mnemonic_entry **last_insn_mnemonic;
897 insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry);
898 /* parse it */
899 new_insn_mnemonic->line = record->line;
900 ASSERT (record->nr_fields > insn_mnemonic_format_field);
901 new_insn_mnemonic->format = record->field[insn_mnemonic_format_field];
902 ASSERT (new_insn_mnemonic->format[0] == '"');
4e0bf4c4
AC
903 if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] !=
904 '"')
905 error (new_insn_mnemonic->line,
906 "Missing closing double quote in mnemonic field\n");
c906108c 907 if (record->nr_fields > insn_mnemonic_condition_field)
4e0bf4c4
AC
908 new_insn_mnemonic->condition =
909 record->field[insn_mnemonic_condition_field];
c906108c
SS
910 new_insn_mnemonic->insn = insn;
911 /* insert it */
912 last_insn_mnemonic = &insn->mnemonics;
913 while ((*last_insn_mnemonic) != NULL)
914 last_insn_mnemonic = &(*last_insn_mnemonic)->next;
915 insn->nr_mnemonics++;
916 *last_insn_mnemonic = new_insn_mnemonic;
917}
918
919
920static table_entry *
4e0bf4c4 921parse_macro_record (table *file, table_entry *record)
c906108c
SS
922{
923#if 1
924 error (record->line, "Macros are not implemented");
925#else
926 /* parse the define record */
927 if (record->nr_fields < nr_define_fields)
928 error (record->line, "Incorrect nr fields for define record\n");
929 /* process it */
930 if (!is_filtered_out (options.flags_filter,
931 record->field[record_filter_flags_field])
932 && !is_filtered_out (options.model_filter,
933 record->field[record_filter_models_field]))
934 {
935 table_define (file,
936 record->line,
937 record->field[macro_name_field],
938 record->field[macro_args_field],
939 record->field[macro_expr_field]);
4e0bf4c4 940 }
c906108c
SS
941 record = table_read (file);
942#endif
943 return record;
944}
945
946
947insn_table *
4e0bf4c4 948load_insn_table (char *file_name, cache_entry *cache)
c906108c
SS
949{
950 table *file = table_open (file_name);
951 table_entry *record = table_read (file);
952
953 insn_table *isa = ZALLOC (insn_table);
954 model_table *model = ZALLOC (model_table);
4e0bf4c4 955
c906108c
SS
956 isa->model = model;
957 isa->caches = cache;
958
959 while (record != NULL)
960 {
961
962 switch (record_type (record))
963 {
964
965 case include_record:
966 {
967 record = parse_include_record (file, record);
968 break;
969 }
970
971 case option_record:
972 {
973 if (isa->insns != NULL)
974 error (record->line, "Option after first instruction\n");
975 record = parse_option_record (file, record);
976 break;
977 }
4e0bf4c4 978
c906108c
SS
979 case string_function_record:
980 {
981 function_entry *function = NULL;
982 record = parse_function_record (file, record,
983 &isa->functions,
4e0bf4c4 984 &function, 0 /*is-internal */ ,
c906108c
SS
985 model);
986 /* convert a string function record into an internal function */
987 if (function != NULL)
988 {
989 char *name = NZALLOC (char,
990 (strlen ("str_")
4e0bf4c4 991 + strlen (function->name) + 1));
c906108c
SS
992 strcat (name, "str_");
993 strcat (name, function->name);
994 function->name = name;
995 function->type = "const char *";
996 }
997 break;
998 }
4e0bf4c4
AC
999
1000 case function_record: /* function record */
c906108c
SS
1001 {
1002 record = parse_function_record (file, record,
1003 &isa->functions,
4e0bf4c4 1004 NULL, 0 /*is-internal */ ,
c906108c
SS
1005 model);
1006 break;
1007 }
1008
1009 case internal_record:
1010 {
1011 /* only insert it into the function list if it is unknown */
1012 function_entry *function = NULL;
1013 record = parse_function_record (file, record,
1014 &isa->functions,
4e0bf4c4 1015 &function, 1 /*is-internal */ ,
c906108c
SS
1016 model);
1017 /* check what was inserted to see if a pseudo-instruction
4e0bf4c4 1018 entry also needs to be created */
c906108c
SS
1019 if (function != NULL)
1020 {
1021 insn_entry **insn = NULL;
1022 if (strcmp (function->name, "illegal") == 0)
1023 {
1024 /* illegal function save it away */
1025 if (isa->illegal_insn != NULL)
1026 {
1027 warning (function->line,
1028 "Multiple illegal instruction definitions\n");
1029 error (isa->illegal_insn->line,
1030 "Location of first illegal instruction\n");
1031 }
1032 else
1033 insn = &isa->illegal_insn;
1034 }
1035 if (insn != NULL)
1036 {
1037 *insn = ZALLOC (insn_entry);
1038 (*insn)->line = function->line;
1039 (*insn)->name = function->name;
1040 (*insn)->code = function->code;
1041 }
1042 }
1043 break;
1044 }
4e0bf4c4
AC
1045
1046 case scratch_record: /* cache macro records */
c906108c
SS
1047 case cache_record:
1048 case compute_record:
1049 {
1050 cache_entry *new_cache;
1051 /* parse the cache record */
1052 if (record->nr_fields < nr_cache_fields)
1053 error (record->line,
1054 "Incorrect nr of fields for scratch/cache/compute record\n");
1055 /* create it */
1056 new_cache = ZALLOC (cache_entry);
1057 new_cache->line = record->line;
1058 filter_parse (&new_cache->flags,
1059 record->field[record_filter_flags_field]);
1060 filter_parse (&new_cache->models,
1061 record->field[record_filter_models_field]);
1062 new_cache->type = record->field[cache_typedef_field];
1063 new_cache->name = record->field[cache_name_field];
1064 filter_parse (&new_cache->original_fields,
1065 record->field[cache_original_fields_field]);
1066 new_cache->expression = record->field[cache_expression_field];
1067 /* insert it but only if not filtered out */
1068 if (!filter_is_subset (options.flags_filter, new_cache->flags))
1069 {
4e0bf4c4
AC
1070 notify (new_cache->line,
1071 "Discarding cache entry %s - filter flags\n",
c906108c
SS
1072 new_cache->name);
1073 }
1074 else if (is_filtered_out (options.model_filter,
4e0bf4c4
AC
1075 record->
1076 field[record_filter_models_field]))
c906108c 1077 {
4e0bf4c4
AC
1078 notify (new_cache->line,
1079 "Discarding cache entry %s - filter models\n",
c906108c
SS
1080 new_cache->name);
1081 }
1082 else
1083 {
1084 cache_entry **last;
1085 last = &isa->caches;
1086 while (*last != NULL)
1087 last = &(*last)->next;
1088 *last = new_cache;
1089 }
1090 /* advance things */
1091 record = table_read (file);
1092 break;
1093 }
4e0bf4c4
AC
1094
1095 /* model records */
c906108c
SS
1096 case model_processor_record:
1097 {
1098 model_entry *new_model;
1099 /* parse the model */
1100 if (record->nr_fields < nr_model_processor_fields)
4e0bf4c4
AC
1101 error (record->line,
1102 "Incorrect nr of fields for model record\n");
c906108c
SS
1103 if (isa->insns != NULL)
1104 error (record->line, "Model appears after first instruction\n");
1105 new_model = ZALLOC (model_entry);
1106 filter_parse (&new_model->flags,
1107 record->field[record_filter_flags_field]);
1108 new_model->line = record->line;
1109 new_model->name = record->field[model_name_field];
1110 new_model->full_name = record->field[model_full_name_field];
1111 new_model->unit_data = record->field[model_unit_data_field];
1112 /* only insert it if not filtered out */
1113 if (!filter_is_subset (options.flags_filter, new_model->flags))
1114 {
4e0bf4c4
AC
1115 notify (new_model->line,
1116 "Discarding processor model %s - filter flags\n",
c906108c
SS
1117 new_model->name);
1118 }
1119 else if (is_filtered_out (options.model_filter,
4e0bf4c4
AC
1120 record->
1121 field[record_filter_models_field]))
c906108c 1122 {
4e0bf4c4
AC
1123 notify (new_model->line,
1124 "Discarding processor model %s - filter models\n",
c906108c
SS
1125 new_model->name);
1126 }
1127 else if (filter_is_member (model->processors, new_model->name))
1128 {
1129 error (new_model->line, "Duplicate processor model %s\n",
1130 new_model->name);
1131 }
1132 else
1133 {
1134 model_entry **last;
1135 last = &model->models;
1136 while (*last != NULL)
1137 last = &(*last)->next;
1138 *last = new_model;
1139 /* count it */
4e0bf4c4 1140 model->nr_models++;
c906108c
SS
1141 filter_parse (&model->processors, new_model->name);
1142 }
1143 /* advance things */
1144 record = table_read (file);
1145 }
1146 break;
4e0bf4c4 1147
c906108c
SS
1148 case model_macro_record:
1149 record = parse_model_data_record (isa, file, record,
1150 nr_model_macro_fields,
1151 &model->macros);
1152 break;
4e0bf4c4 1153
c906108c
SS
1154 case model_data_record:
1155 record = parse_model_data_record (isa, file, record,
1156 nr_model_data_fields,
1157 &model->data);
1158 break;
4e0bf4c4 1159
c906108c
SS
1160 case model_static_record:
1161 record = parse_function_record (file, record,
1162 &model->statics,
4e0bf4c4 1163 NULL, 0 /*is internal */ ,
c906108c
SS
1164 model);
1165 break;
4e0bf4c4 1166
c906108c
SS
1167 case model_internal_record:
1168 record = parse_function_record (file, record,
1169 &model->internals,
4e0bf4c4 1170 NULL, 1 /*is internal */ ,
c906108c
SS
1171 model);
1172 break;
4e0bf4c4 1173
c906108c
SS
1174 case model_function_record:
1175 record = parse_function_record (file, record,
1176 &model->functions,
4e0bf4c4 1177 NULL, 0 /*is internal */ ,
c906108c
SS
1178 model);
1179 break;
4e0bf4c4
AC
1180
1181 case insn_record: /* instruction records */
c906108c
SS
1182 {
1183 insn_entry *new_insn;
1184 char *format;
1185 /* parse the instruction */
1186 if (record->nr_fields < nr_insn_fields)
4e0bf4c4
AC
1187 error (record->line,
1188 "Incorrect nr of fields for insn record\n");
c906108c
SS
1189 new_insn = ZALLOC (insn_entry);
1190 new_insn->line = record->line;
1191 filter_parse (&new_insn->flags,
1192 record->field[record_filter_flags_field]);
1193 /* save the format field. Can't parse it until after the
4e0bf4c4
AC
1194 filter-out checks. Could be filtered out because the
1195 format is invalid */
c906108c
SS
1196 format = record->field[insn_word_field];
1197 new_insn->format_name = record->field[insn_format_name_field];
1198 if (options.format_name_filter != NULL
1199 && !filter_is_member (options.format_name_filter,
1200 new_insn->format_name))
4e0bf4c4
AC
1201 error (new_insn->line,
1202 "Unreconized instruction format name `%s'\n",
c906108c
SS
1203 new_insn->format_name);
1204 filter_parse (&new_insn->options,
1205 record->field[insn_options_field]);
1206 new_insn->name = record->field[insn_name_field];
1207 record = table_read (file);
1208 /* Parse any model/assember records */
1209 new_insn->nr_models = model->nr_models;
4e0bf4c4
AC
1210 new_insn->model =
1211 NZALLOC (insn_model_entry *, model->nr_models + 1);
c906108c
SS
1212 while (record != NULL)
1213 {
1214 if (record_prefix_is (record, '*', nr_insn_model_fields))
1215 parse_insn_model_record (file, record, new_insn, model);
4e0bf4c4
AC
1216 else
1217 if (record_prefix_is (record, '"', nr_insn_mnemonic_fields))
c906108c
SS
1218 parse_insn_mnemonic_record (file, record, new_insn);
1219 else
1220 break;
1221 /* advance */
1222 record = table_read (file);
1223 }
1224 /* Parse the code record */
1225 if (record != NULL && record->type == table_code_entry)
1226 {
1227 new_insn->code = record;
1228 record = table_read (file);
1229 }
1230 else if (options.warn.unimplemented)
1231 notify (new_insn->line, "unimplemented\n");
1232 /* insert it */
1233 if (!filter_is_subset (options.flags_filter, new_insn->flags))
1234 {
1235 if (options.warn.discard)
1236 notify (new_insn->line,
1237 "Discarding instruction %s (flags-filter)\n",
1238 new_insn->name);
1239 }
1240 else if (new_insn->processors != NULL
1241 && options.model_filter != NULL
1242 && !filter_is_common (options.model_filter,
1243 new_insn->processors))
1244 {
1245 /* only discard an instruction based in the processor
4e0bf4c4
AC
1246 model when both the instruction and the options are
1247 nonempty */
c906108c
SS
1248 if (options.warn.discard)
1249 notify (new_insn->line,
1250 "Discarding instruction %s (processor-model)\n",
1251 new_insn->name);
1252 }
1253 else
1254 {
1255 insn_entry **last;
1256 /* finish the parsing */
1257 parse_insn_words (new_insn, format);
1258 /* append it */
1259 last = &isa->insns;
1260 while (*last)
1261 last = &(*last)->next;
1262 *last = new_insn;
1263 /* update global isa counters */
4e0bf4c4 1264 isa->nr_insns++;
c906108c
SS
1265 if (isa->max_nr_words < new_insn->nr_words)
1266 isa->max_nr_words = new_insn->nr_words;
1267 filter_add (&isa->flags, new_insn->flags);
1268 filter_add (&isa->options, new_insn->options);
1269 }
1270 break;
1271 }
4e0bf4c4 1272
c906108c
SS
1273 case define_record:
1274 record = parse_macro_record (file, record);
1275 break;
1276
1277 case unknown_record:
1278 case code_record:
1279 error (record->line, "Unknown or unexpected entry\n");
1280
1281
1282 }
1283 }
1284 return isa;
1285}
1286
1287
1288void
4e0bf4c4 1289print_insn_words (lf *file, insn_entry * insn)
c906108c
SS
1290{
1291 insn_word_entry *word = insn->words;
1292 if (word != NULL)
1293 {
1294 while (1)
1295 {
1296 insn_field_entry *field = word->first;
1297 while (1)
1298 {
1299 if (options.insn_specifying_widths)
1300 lf_printf (file, "%d.", field->width);
1301 else
4e0bf4c4
AC
1302 lf_printf (file, "%d.",
1303 i2target (options.hi_bit_nr, field->first));
c906108c
SS
1304 switch (field->type)
1305 {
1306 case insn_field_invalid:
1307 ASSERT (0);
1308 break;
1309 case insn_field_int:
1310 lf_printf (file, "0x%lx", (long) field->val_int);
1311 break;
1312 case insn_field_reserved:
1313 lf_printf (file, "/");
1314 break;
1315 case insn_field_wild:
1316 lf_printf (file, "*");
1317 break;
1318 case insn_field_string:
1319 lf_printf (file, "%s", field->val_string);
1320 break;
1321 }
1322 if (field == word->last)
1323 break;
1324 field = field->next;
1325 lf_printf (file, ",");
1326 }
1327 word = word->next;
1328 if (word == NULL)
1329 break;
1330 lf_printf (file, "+");
1331 }
1332 }
1333}
4e0bf4c4 1334\f
c906108c
SS
1335
1336
c906108c
SS
1337void
1338function_entry_traverse (lf *file,
4e0bf4c4
AC
1339 function_entry * functions,
1340 function_entry_handler * handler, void *data)
c906108c
SS
1341{
1342 function_entry *function;
1343 for (function = functions; function != NULL; function = function->next)
1344 {
1345 handler (file, function, data);
1346 }
1347}
1348
1349void
1350insn_table_traverse_insn (lf *file,
1351 insn_table *isa,
4e0bf4c4 1352 insn_entry_handler * handler, void *data)
c906108c
SS
1353{
1354 insn_entry *insn;
1355 for (insn = isa->insns; insn != NULL; insn = insn->next)
1356 {
1357 handler (file, isa, insn, data);
1358 }
1359}
c906108c 1360\f
4e0bf4c4 1361
c906108c
SS
1362static void
1363dump_function_entry (lf *file,
4e0bf4c4 1364 char *prefix, function_entry * entry, char *suffix)
c906108c
SS
1365{
1366 lf_printf (file, "%s(function_entry *) 0x%lx", prefix, (long) entry);
1367 if (entry != NULL)
1368 {
1369 dump_line_ref (file, "\n(line ", entry->line, ")");
1370 dump_filter (file, "\n(flags ", entry->flags, ")");
1371 lf_printf (file, "\n(type \"%s\")", entry->type);
1372 lf_printf (file, "\n(name \"%s\")", entry->name);
1373 lf_printf (file, "\n(param \"%s\")", entry->param);
1374 dump_table_entry (file, "\n(code ", entry->code, ")");
1375 lf_printf (file, "\n(is_internal %d)", entry->is_internal);
1376 lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1377 }
1378 lf_printf (file, "%s", suffix);
1379}
1380
1381static void
1382dump_function_entries (lf *file,
4e0bf4c4 1383 char *prefix, function_entry * entry, char *suffix)
c906108c
SS
1384{
1385 lf_printf (file, "%s", prefix);
1386 lf_indent (file, +1);
1387 while (entry != NULL)
1388 {
1389 dump_function_entry (file, "\n(", entry, ")");
1390 entry = entry->next;
1391 }
1392 lf_indent (file, -1);
1393 lf_printf (file, "%s", suffix);
1394}
1395
1396static char *
1397cache_entry_type_to_str (cache_entry_type type)
1398{
1399 switch (type)
1400 {
4e0bf4c4
AC
1401 case scratch_value:
1402 return "scratch";
1403 case cache_value:
1404 return "cache";
1405 case compute_value:
1406 return "compute";
c906108c
SS
1407 }
1408 ERROR ("Bad switch");
1409 return 0;
1410}
1411
1412static void
4e0bf4c4 1413dump_cache_entry (lf *file, char *prefix, cache_entry *entry, char *suffix)
c906108c
SS
1414{
1415 lf_printf (file, "%s(cache_entry *) 0x%lx", prefix, (long) entry);
1416 if (entry != NULL)
1417 {
1418 dump_line_ref (file, "\n(line ", entry->line, ")");
1419 dump_filter (file, "\n(flags ", entry->flags, ")");
4e0bf4c4
AC
1420 lf_printf (file, "\n(entry_type \"%s\")",
1421 cache_entry_type_to_str (entry->entry_type));
c906108c
SS
1422 lf_printf (file, "\n(name \"%s\")", entry->name);
1423 dump_filter (file, "\n(original_fields ", entry->original_fields, ")");
1424 lf_printf (file, "\n(type \"%s\")", entry->type);
1425 lf_printf (file, "\n(expression \"%s\")", entry->expression);
1426 lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1427 }
1428 lf_printf (file, "%s", suffix);
1429}
1430
1431void
4e0bf4c4 1432dump_cache_entries (lf *file, char *prefix, cache_entry *entry, char *suffix)
c906108c
SS
1433{
1434 lf_printf (file, "%s", prefix);
1435 lf_indent (file, +1);
1436 while (entry != NULL)
1437 {
1438 dump_cache_entry (file, "\n(", entry, ")");
1439 entry = entry->next;
1440 }
1441 lf_indent (file, -1);
1442 lf_printf (file, "%s", suffix);
1443}
1444
1445static void
4e0bf4c4 1446dump_model_data (lf *file, char *prefix, model_data *entry, char *suffix)
c906108c
SS
1447{
1448 lf_printf (file, "%s(model_data *) 0x%lx", prefix, (long) entry);
1449 if (entry != NULL)
1450 {
1451 lf_indent (file, +1);
1452 dump_line_ref (file, "\n(line ", entry->line, ")");
1453 dump_filter (file, "\n(flags ", entry->flags, ")");
1454 dump_table_entry (file, "\n(entry ", entry->entry, ")");
1455 dump_table_entry (file, "\n(code ", entry->code, ")");
1456 lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1457 lf_indent (file, -1);
1458 }
1459 lf_printf (file, "%s", prefix);
1460}
1461
1462static void
4e0bf4c4 1463dump_model_datas (lf *file, char *prefix, model_data *entry, char *suffix)
c906108c
SS
1464{
1465 lf_printf (file, "%s", prefix);
1466 lf_indent (file, +1);
1467 while (entry != NULL)
1468 {
1469 dump_model_data (file, "\n(", entry, ")");
1470 entry = entry->next;
1471 }
1472 lf_indent (file, -1);
1473 lf_printf (file, "%s", suffix);
1474}
1475
1476static void
4e0bf4c4 1477dump_model_entry (lf *file, char *prefix, model_entry *entry, char *suffix)
c906108c
SS
1478{
1479 lf_printf (file, "%s(model_entry *) 0x%lx", prefix, (long) entry);
1480 if (entry != NULL)
1481 {
1482 lf_indent (file, +1);
1483 dump_line_ref (file, "\n(line ", entry->line, ")");
1484 dump_filter (file, "\n(flags ", entry->flags, ")");
1485 lf_printf (file, "\n(name \"%s\")", entry->name);
1486 lf_printf (file, "\n(full_name \"%s\")", entry->full_name);
1487 lf_printf (file, "\n(unit_data \"%s\")", entry->unit_data);
1488 lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1489 lf_indent (file, -1);
1490 }
1491 lf_printf (file, "%s", prefix);
1492}
1493
1494static void
4e0bf4c4 1495dump_model_entries (lf *file, char *prefix, model_entry *entry, char *suffix)
c906108c
SS
1496{
1497 lf_printf (file, "%s", prefix);
1498 lf_indent (file, +1);
1499 while (entry != NULL)
1500 {
1501 dump_model_entry (file, "\n(", entry, ")");
1502 entry = entry->next;
1503 }
1504 lf_indent (file, -1);
1505 lf_printf (file, "%s", suffix);
1506}
1507
1508
1509static void
4e0bf4c4 1510dump_model_table (lf *file, char *prefix, model_table *entry, char *suffix)
c906108c
SS
1511{
1512 lf_printf (file, "%s(model_table *) 0x%lx", prefix, (long) entry);
1513 if (entry != NULL)
1514 {
1515 lf_indent (file, +1);
1516 dump_filter (file, "\n(processors ", entry->processors, ")");
1517 lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1518 dump_model_entries (file, "\n(models ", entry->models, ")");
1519 dump_model_datas (file, "\n(macros ", entry->macros, ")");
1520 dump_model_datas (file, "\n(data ", entry->data, ")");
1521 dump_function_entries (file, "\n(statics ", entry->statics, ")");
1522 dump_function_entries (file, "\n(internals ", entry->functions, ")");
1523 dump_function_entries (file, "\n(functions ", entry->functions, ")");
1524 lf_indent (file, -1);
1525 }
1526 lf_printf (file, "%s", suffix);
1527}
1528
1529
1530static char *
1531insn_field_type_to_str (insn_field_type type)
1532{
1533 switch (type)
1534 {
4e0bf4c4
AC
1535 case insn_field_invalid:
1536 ASSERT (0);
1537 return "(invalid)";
1538 case insn_field_int:
1539 return "int";
1540 case insn_field_reserved:
1541 return "reserved";
1542 case insn_field_wild:
1543 return "wild";
1544 case insn_field_string:
1545 return "string";
c906108c
SS
1546 }
1547 ERROR ("bad switch");
1548 return 0;
1549}
1550
1551void
1552dump_insn_field (lf *file,
4e0bf4c4 1553 char *prefix, insn_field_entry *field, char *suffix)
c906108c
SS
1554{
1555 char *sep = " ";
1556 lf_printf (file, "%s(insn_field_entry *) 0x%lx", prefix, (long) field);
1557 if (field != NULL)
1558 {
1559 lf_indent (file, +1);
1560 lf_printf (file, "%s(first %d)", sep, field->first);
1561 lf_printf (file, "%s(last %d)", sep, field->last);
1562 lf_printf (file, "%s(width %d)", sep, field->width);
4e0bf4c4
AC
1563 lf_printf (file, "%s(type %s)", sep,
1564 insn_field_type_to_str (field->type));
c906108c
SS
1565 switch (field->type)
1566 {
1567 case insn_field_invalid:
1568 ASSERT (0);
1569 break;
1570 case insn_field_int:
1571 lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int);
1572 break;
1573 case insn_field_reserved:
1574 /* nothing output */
1575 break;
1576 case insn_field_wild:
1577 /* nothing output */
1578 break;
1579 case insn_field_string:
1580 lf_printf (file, "%s(val \"%s\")", sep, field->val_string);
1581 break;
1582 }
1583 lf_printf (file, "%s(next 0x%lx)", sep, (long) field->next);
1584 lf_printf (file, "%s(prev 0x%lx)", sep, (long) field->prev);
1585 lf_indent (file, -1);
1586 }
1587 lf_printf (file, "%s", suffix);
1588}
1589
1590void
1591dump_insn_word_entry (lf *file,
4e0bf4c4 1592 char *prefix, insn_word_entry *word, char *suffix)
c906108c
SS
1593{
1594 lf_printf (file, "%s(insn_word_entry *) 0x%lx", prefix, (long) word);
1595 if (word != NULL)
1596 {
1597 int i;
1598 insn_field_entry *field;
1599 lf_indent (file, +1);
1600 lf_printf (file, "\n(first 0x%lx)", (long) word->first);
1601 lf_printf (file, "\n(last 0x%lx)", (long) word->last);
1602 lf_printf (file, "\n(bit");
1603 for (i = 0; i < options.insn_bit_size; i++)
1604 lf_printf (file, "\n ((value %d) (mask %d) (field 0x%lx))",
4e0bf4c4
AC
1605 word->bit[i]->value, word->bit[i]->mask,
1606 (long) word->bit[i]->field);
c906108c
SS
1607 lf_printf (file, ")");
1608 for (field = word->first; field != NULL; field = field->next)
1609 dump_insn_field (file, "\n(", field, ")");
1610 dump_filter (file, "\n(field_names ", word->field_names, ")");
1611 lf_printf (file, "\n(next 0x%lx)", (long) word->next);
1612 lf_indent (file, -1);
1613 }
1614 lf_printf (file, "%s", suffix);
1615}
1616
1617static void
1618dump_insn_word_entries (lf *file,
4e0bf4c4 1619 char *prefix, insn_word_entry *word, char *suffix)
c906108c
SS
1620{
1621 lf_printf (file, "%s", prefix);
1622 while (word != NULL)
1623 {
1624 dump_insn_word_entry (file, "\n(", word, ")");
1625 word = word->next;
1626 }
1627 lf_printf (file, "%s", suffix);
1628}
1629
1630static void
1631dump_insn_model_entry (lf *file,
4e0bf4c4 1632 char *prefix, insn_model_entry *model, char *suffix)
c906108c
SS
1633{
1634 lf_printf (file, "%s(insn_model_entry *) 0x%lx", prefix, (long) model);
1635 if (model != NULL)
1636 {
1637 lf_indent (file, +1);
1638 dump_line_ref (file, "\n(line ", model->line, ")");
1639 dump_filter (file, "\n(names ", model->names, ")");
1640 lf_printf (file, "\n(full_name \"%s\")", model->full_name);
1641 lf_printf (file, "\n(unit_data \"%s\")", model->unit_data);
1642 lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", (long) model->insn);
1643 lf_printf (file, "\n(next (insn_model_entry *) 0x%lx)",
1644 (long) model->next);
1645 lf_indent (file, -1);
1646 }
1647 lf_printf (file, "%s", suffix);
1648}
1649
1650static void
1651dump_insn_model_entries (lf *file,
4e0bf4c4 1652 char *prefix, insn_model_entry *model, char *suffix)
c906108c
SS
1653{
1654 lf_printf (file, "%s", prefix);
1655 while (model != NULL)
1656 {
1657 dump_insn_model_entry (file, "\n", model, "");
1658 model = model->next;
1659 }
1660 lf_printf (file, "%s", suffix);
1661}
1662
1663
1664static void
1665dump_insn_mnemonic_entry (lf *file,
1666 char *prefix,
4e0bf4c4 1667 insn_mnemonic_entry *mnemonic, char *suffix)
c906108c 1668{
4e0bf4c4
AC
1669 lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix,
1670 (long) mnemonic);
c906108c
SS
1671 if (mnemonic != NULL)
1672 {
1673 lf_indent (file, +1);
1674 dump_line_ref (file, "\n(line ", mnemonic->line, ")");
1675 lf_printf (file, "\n(format \"%s\")", mnemonic->format);
1676 lf_printf (file, "\n(condition \"%s\")", mnemonic->condition);
1677 lf_printf (file, "\n(insn (insn_entry *) 0x%lx)",
1678 (long) mnemonic->insn);
1679 lf_printf (file, "\n(next (insn_mnemonic_entry *) 0x%lx)",
1680 (long) mnemonic->next);
1681 lf_indent (file, -1);
1682 }
1683 lf_printf (file, "%s", suffix);
1684}
1685
1686static void
1687dump_insn_mnemonic_entries (lf *file,
1688 char *prefix,
4e0bf4c4 1689 insn_mnemonic_entry *mnemonic, char *suffix)
c906108c
SS
1690{
1691 lf_printf (file, "%s", prefix);
1692 while (mnemonic != NULL)
1693 {
1694 dump_insn_mnemonic_entry (file, "\n", mnemonic, "");
1695 mnemonic = mnemonic->next;
1696 }
1697 lf_printf (file, "%s", suffix);
1698}
1699
1700void
4e0bf4c4 1701dump_insn_entry (lf *file, char *prefix, insn_entry * entry, char *suffix)
c906108c
SS
1702{
1703 lf_printf (file, "%s(insn_entry *) 0x%lx", prefix, (long) entry);
1704 if (entry != NULL)
1705 {
1706 int i;
1707 lf_indent (file, +1);
1708 dump_line_ref (file, "\n(line ", entry->line, ")");
1709 dump_filter (file, "\n(flags ", entry->flags, ")");
1710 lf_printf (file, "\n(nr_words %d)", entry->nr_words);
1711 dump_insn_word_entries (file, "\n(words ", entry->words, ")");
1712 lf_printf (file, "\n(word");
1713 for (i = 0; i < entry->nr_models; i++)
1714 lf_printf (file, " 0x%lx", (long) entry->word[i]);
1715 lf_printf (file, ")");
1716 dump_filter (file, "\n(field_names ", entry->field_names, ")");
1717 lf_printf (file, "\n(format_name \"%s\")", entry->format_name);
1718 dump_filter (file, "\n(options ", entry->options, ")");
1719 lf_printf (file, "\n(name \"%s\")", entry->name);
1720 lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1721 dump_insn_model_entries (file, "\n(models ", entry->models, ")");
1722 lf_printf (file, "\n(model");
1723 for (i = 0; i < entry->nr_models; i++)
1724 lf_printf (file, " 0x%lx", (long) entry->model[i]);
1725 lf_printf (file, ")");
1726 dump_filter (file, "\n(processors ", entry->processors, ")");
4e0bf4c4
AC
1727 dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics,
1728 ")");
c906108c
SS
1729 dump_table_entry (file, "\n(code ", entry->code, ")");
1730 lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1731 lf_indent (file, -1);
4e0bf4c4 1732 }
c906108c
SS
1733 lf_printf (file, "%s", suffix);
1734}
1735
1736static void
4e0bf4c4 1737dump_insn_entries (lf *file, char *prefix, insn_entry * entry, char *suffix)
c906108c
SS
1738{
1739 lf_printf (file, "%s", prefix);
1740 lf_indent (file, +1);
1741 while (entry != NULL)
1742 {
1743 dump_insn_entry (file, "\n(", entry, ")");
1744 entry = entry->next;
1745 }
1746 lf_indent (file, -1);
1747 lf_printf (file, "%s", suffix);
1748}
1749
1750
1751
1752void
4e0bf4c4 1753dump_insn_table (lf *file, char *prefix, insn_table *isa, char *suffix)
c906108c
SS
1754{
1755 lf_printf (file, "%s(insn_table *) 0x%lx", prefix, (long) isa);
1756 if (isa != NULL)
1757 {
1758 lf_indent (file, +1);
1759 dump_cache_entries (file, "\n(caches ", isa->caches, ")");
1760 lf_printf (file, "\n(nr_insns %d)", isa->nr_insns);
1761 lf_printf (file, "\n(max_nr_words %d)", isa->max_nr_words);
1762 dump_insn_entries (file, "\n(insns ", isa->insns, ")");
1763 dump_function_entries (file, "\n(functions ", isa->functions, ")");
1764 dump_insn_entry (file, "\n(illegal_insn ", isa->illegal_insn, ")");
1765 dump_model_table (file, "\n(model ", isa->model, ")");
1766 dump_filter (file, "\n(flags ", isa->flags, ")");
1767 dump_filter (file, "\n(options ", isa->options, ")");
1768 lf_indent (file, -1);
1769 }
1770 lf_printf (file, "%s", suffix);
1771}
1772
1773#ifdef MAIN
1774
1775igen_options options;
1776
1777int
1778main (int argc, char **argv)
1779{
1780 insn_table *isa;
1781 lf *l;
1782
1783 INIT_OPTIONS (options);
1784
1785 if (argc == 3)
1786 filter_parse (&options.flags_filter, argv[2]);
1787 else if (argc != 2)
1788 error (NULL, "Usage: insn <insn-table> [ <filter-in> ]\n");
1789
1790 isa = load_insn_table (argv[1], NULL);
1791 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1792 dump_insn_table (l, "(isa ", isa, ")\n");
1793
1794 return 0;
1795}
1796
1797#endif