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