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