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