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