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