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