Remove all #if 0'd code.
[deliverable/binutils-gdb.git] / sim / igen / gen.c
CommitLineData
feaee4bd 1/* The IGEN simulator generator for GDB, the GNU Debugger.
c906108c 2
7b6bb8da 3 Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
c906108c 4
feaee4bd 5 Contributed by Andrew Cagney.
c906108c 6
feaee4bd
AC
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
4744ac1b 11 the Free Software Foundation; either version 3 of the License, or
feaee4bd
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
4744ac1b 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22
23#include "misc.h"
24#include "lf.h"
25#include "table.h"
26#include "filter.h"
27
28#include "igen.h"
29#include "ld-insn.h"
30#include "ld-decode.h"
31#include "gen.h"
32
33static insn_uint
4e0bf4c4 34sub_val (insn_uint val, int val_last_pos, int first_pos, int last_pos)
c906108c
SS
35{
36 return ((val >> (val_last_pos - last_pos))
4e0bf4c4 37 & (((insn_uint) 1 << (last_pos - first_pos + 1)) - 1));
c906108c
SS
38}
39
40static void
4e0bf4c4 41update_depth (lf *file, gen_entry *entry, int depth, void *data)
c906108c 42{
4e0bf4c4 43 int *max_depth = (int *) data;
c906108c
SS
44 if (*max_depth < depth)
45 *max_depth = depth;
46}
47
48
49int
50gen_entry_depth (gen_entry *table)
51{
52 int depth = 0;
4e0bf4c4
AC
53 gen_entry_traverse_tree (NULL, table, 1, NULL, /*start */
54 update_depth, NULL, /*end */
55 &depth); /* data */
c906108c
SS
56 return depth;
57}
58
59
60static void
4e0bf4c4 61print_gen_entry_path (line_ref *line, gen_entry *table, error_func *print)
c906108c
SS
62{
63 if (table->parent == NULL)
64 {
65 if (table->top->model != NULL)
66 print (line, "%s", table->top->model->name);
67 else
68 print (line, "");
69 }
70 else
71 {
72 print_gen_entry_path (line, table->parent, print);
73 print (NULL, ".%d", table->opcode_nr);
74 }
75}
76
77static void
78print_gen_entry_insns (gen_entry *table,
79 error_func *print,
4e0bf4c4 80 char *first_message, char *next_message)
c906108c
SS
81{
82 insn_list *i;
83 char *message;
84 message = first_message;
85 for (i = table->insns; i != NULL; i = i->next)
86 {
87 insn_entry *insn = i->insn;
88 print_gen_entry_path (insn->line, table, print);
4e0bf4c4 89 print (NULL, ": %s.%s %s\n", insn->format_name, insn->name, message);
c906108c
SS
90 if (next_message != NULL)
91 message = next_message;
92 }
93}
94
95/* same as strcmp */
96static int
97insn_field_cmp (insn_word_entry *l, insn_word_entry *r)
98{
99 while (1)
100 {
101 int bit_nr;
102 if (l == NULL && r == NULL)
4e0bf4c4 103 return 0; /* all previous fields the same */
c906108c 104 if (l == NULL)
4e0bf4c4 105 return -1; /* left shorter than right */
c906108c 106 if (r == NULL)
4e0bf4c4
AC
107 return +1; /* left longer than right */
108 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
c906108c
SS
109 {
110 if (l->bit[bit_nr]->field->type != insn_field_string)
111 continue;
112 if (r->bit[bit_nr]->field->type != insn_field_string)
113 continue;
114 if (l->bit[bit_nr]->field->conditions == NULL)
115 continue;
116 if (r->bit[bit_nr]->field->conditions == NULL)
117 continue;
118 if (0)
119 printf ("%s%s%s VS %s%s%s\n",
120 l->bit[bit_nr]->field->val_string,
4e0bf4c4
AC
121 l->bit[bit_nr]->field->conditions->test ==
122 insn_field_cond_eq ? "=" : "!",
123 l->bit[bit_nr]->field->conditions->string,
c906108c 124 r->bit[bit_nr]->field->val_string,
4e0bf4c4
AC
125 r->bit[bit_nr]->field->conditions->test ==
126 insn_field_cond_eq ? "=" : "!",
c906108c
SS
127 r->bit[bit_nr]->field->conditions->string);
128 if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq
4e0bf4c4
AC
129 && r->bit[bit_nr]->field->conditions->test ==
130 insn_field_cond_eq)
c906108c 131 {
4e0bf4c4
AC
132 if (l->bit[bit_nr]->field->conditions->type ==
133 insn_field_cond_field
134 && r->bit[bit_nr]->field->conditions->type ==
135 insn_field_cond_field)
c906108c
SS
136 /* somewhat arbitrary */
137 {
138 int cmp = strcmp (l->bit[bit_nr]->field->conditions->string,
4e0bf4c4
AC
139 r->bit[bit_nr]->field->conditions->
140 string);
c906108c
SS
141 if (cmp != 0)
142 return cmp;
143 else
144 continue;
145 }
4e0bf4c4
AC
146 if (l->bit[bit_nr]->field->conditions->type ==
147 insn_field_cond_field)
c906108c 148 return +1;
4e0bf4c4
AC
149 if (r->bit[bit_nr]->field->conditions->type ==
150 insn_field_cond_field)
c906108c
SS
151 return -1;
152 /* The case of both fields having constant values should have
4e0bf4c4
AC
153 already have been handled because such fields are converted
154 into normal constant fields. */
c906108c
SS
155 continue;
156 }
157 if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
4e0bf4c4 158 return +1; /* left = only */
c906108c 159 if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
4e0bf4c4 160 return -1; /* right = only */
c906108c
SS
161 /* FIXME: Need to some what arbitrarily order conditional lists */
162 continue;
163 }
164 l = l->next;
165 r = r->next;
166 }
167}
168
169/* same as strcmp */
170static int
171insn_word_cmp (insn_word_entry *l, insn_word_entry *r)
172{
173 while (1)
174 {
175 int bit_nr;
176 if (l == NULL && r == NULL)
4e0bf4c4 177 return 0; /* all previous fields the same */
c906108c 178 if (l == NULL)
4e0bf4c4 179 return -1; /* left shorter than right */
c906108c 180 if (r == NULL)
4e0bf4c4
AC
181 return +1; /* left longer than right */
182 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
c906108c
SS
183 {
184 if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask)
185 return -1;
186 if (l->bit[bit_nr]->mask > r->bit[bit_nr]->mask)
187 return 1;
188 if (l->bit[bit_nr]->value < r->bit[bit_nr]->value)
189 return -1;
190 if (l->bit[bit_nr]->value > r->bit[bit_nr]->value)
191 return 1;
192 }
193 l = l->next;
194 r = r->next;
195 }
196}
197
198/* same as strcmp */
199static int
4e0bf4c4 200opcode_bit_cmp (opcode_bits *l, opcode_bits *r)
c906108c
SS
201{
202 if (l == NULL && r == NULL)
4e0bf4c4 203 return 0; /* all previous bits the same */
c906108c 204 if (l == NULL)
4e0bf4c4 205 return -1; /* left shorter than right */
c906108c 206 if (r == NULL)
4e0bf4c4 207 return +1; /* left longer than right */
c906108c
SS
208 /* most significant word */
209 if (l->field->word_nr < r->field->word_nr)
4e0bf4c4 210 return +1; /* left has more significant word */
c906108c 211 if (l->field->word_nr > r->field->word_nr)
4e0bf4c4 212 return -1; /* right has more significant word */
c906108c
SS
213 /* most significant bit? */
214 if (l->first < r->first)
4e0bf4c4 215 return +1; /* left as more significant bit */
c906108c 216 if (l->first > r->first)
4e0bf4c4 217 return -1; /* right as more significant bit */
c906108c
SS
218 /* nr bits? */
219 if (l->last < r->last)
4e0bf4c4 220 return +1; /* left as less bits */
c906108c 221 if (l->last > r->last)
4e0bf4c4 222 return -1; /* right as less bits */
c906108c
SS
223 /* value? */
224 if (l->value < r->value)
225 return -1;
226 if (l->value > r->value)
227 return 1;
228 return 0;
229}
230
231
232/* same as strcmp */
233static int
4e0bf4c4 234opcode_bits_cmp (opcode_bits *l, opcode_bits *r)
c906108c
SS
235{
236 while (1)
237 {
238 int cmp;
239 if (l == NULL && r == NULL)
4e0bf4c4 240 return 0; /* all previous bits the same */
c906108c
SS
241 cmp = opcode_bit_cmp (l, r);
242 if (cmp != 0)
243 return cmp;
244 l = l->next;
245 r = r->next;
246 }
247}
248
249/* same as strcmp */
250static opcode_bits *
251new_opcode_bits (opcode_bits *old_bits,
252 int value,
253 int first,
4e0bf4c4 254 int last, insn_field_entry *field, opcode_field *opcode)
c906108c
SS
255{
256 opcode_bits *new_bits = ZALLOC (opcode_bits);
257 new_bits->field = field;
258 new_bits->value = value;
259 new_bits->first = first;
260 new_bits->last = last;
261 new_bits->opcode = opcode;
4e0bf4c4 262
c906108c
SS
263 if (old_bits != NULL)
264 {
265 opcode_bits *new_list;
266 opcode_bits **last = &new_list;
267 new_list = new_opcode_bits (old_bits->next,
268 old_bits->value,
269 old_bits->first,
270 old_bits->last,
4e0bf4c4 271 old_bits->field, old_bits->opcode);
c906108c
SS
272 while (*last != NULL)
273 {
274 int cmp = opcode_bit_cmp (new_bits, *last);
4e0bf4c4 275 if (cmp < 0) /* new < new_list */
c906108c
SS
276 {
277 break;
278 }
279 if (cmp == 0)
280 {
281 ERROR ("Duplicated insn bits in list");
282 }
283 last = &(*last)->next;
284 }
285 new_bits->next = *last;
286 *last = new_bits;
287 return new_list;
288 }
289 else
290 {
291 return new_bits;
292 }
293}
294
e7b564aa
AC
295/* Same as strcmp(). */
296static int
1fdb3c68 297name_cmp (const char *l, const char *r)
e7b564aa
AC
298{
299 if (l == NULL && r == NULL)
300 return 0;
301 if (l != NULL && r == NULL)
302 return -1;
303 if (l == NULL && r != NULL)
304 return +1;
305 return strcmp (l, r);
306}
c906108c
SS
307
308
4e0bf4c4
AC
309typedef enum
310{
c906108c
SS
311 merge_duplicate_insns,
312 report_duplicate_insns,
4e0bf4c4
AC
313}
314duplicate_insn_actions;
c906108c
SS
315
316static insn_list *
317insn_list_insert (insn_list **cur_insn_ptr,
318 int *nr_insns,
4e0bf4c4 319 insn_entry * insn,
c906108c
SS
320 opcode_bits *expanded_bits,
321 opcode_field *opcodes,
322 int nr_prefetched_words,
323 duplicate_insn_actions duplicate_action)
324{
325 /* insert it according to the order of the fields & bits */
326 for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next)
327 {
328 int cmp;
329
330 /* key#1 sort according to the constant fields of each instruction */
331 cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words);
332 if (cmp < 0)
333 break;
334 else if (cmp > 0)
335 continue;
336
337 /* key#2 sort according to the expanded bits of each instruction */
338 cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits);
339 if (cmp < 0)
340 break;
341 else if (cmp > 0)
342 continue;
343
344 /* key#3 sort according to the non-constant fields of each instruction */
345 cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words);
346 if (cmp < 0)
347 break;
348 else if (cmp > 0)
349 continue;
350
1fdb3c68
AC
351 if (duplicate_action == merge_duplicate_insns)
352 {
353 /* key#4: If we're going to merge duplicates, also sort
354 according to the format_name. Two instructions with
355 identical decode patterns, but different names, are
356 considered different when merging. Duplicates are only
357 important when creating a decode table (implied by
358 report_duplicate_insns) as such a table only has the
359 instruction's bit code as a way of differentiating
360 between instructions. */
361 int cmp = name_cmp (insn->format_name,
362 (*cur_insn_ptr)->insn->format_name);
363 if (cmp < 0)
364 break;
365 else if (cmp > 0)
366 continue;
367 }
368
369 if (duplicate_action == merge_duplicate_insns)
370 {
371 /* key#5: If we're going to merge duplicates, also sort
372 according to the name. See comment above for
373 format_name. */
374 int cmp = name_cmp (insn->name, (*cur_insn_ptr)->insn->name);
375 if (cmp < 0)
376 break;
377 else if (cmp > 0)
378 continue;
379 }
e7b564aa 380
c906108c
SS
381 /* duplicate keys, report problem */
382 switch (duplicate_action)
383 {
384 case report_duplicate_insns:
385 /* It would appear that we have two instructions with the
386 same constant field values across all words and bits.
387 This error can also occure when insn_field_cmp() is
388 failing to differentiate between two instructions that
389 differ only in their conditional fields. */
390 warning (insn->line,
391 "Two instructions with identical constant fields\n");
392 error ((*cur_insn_ptr)->insn->line,
393 "Location of duplicate instruction\n");
394 case merge_duplicate_insns:
395 /* Add the opcode path to the instructions list */
1fdb3c68
AC
396 if (options.trace.insn_insertion)
397 {
398 notify ((*cur_insn_ptr)->insn->line,
399 "%s.%s: insert merge %s.%s\n",
400 (*cur_insn_ptr)->insn->format_name,
401 (*cur_insn_ptr)->insn->name,
402 insn->format_name,
403 insn->name);
404 }
c906108c
SS
405 if (opcodes != NULL)
406 {
407 insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
408 while (*last != NULL)
409 {
410 last = &(*last)->next;
411 }
412 (*last) = ZALLOC (insn_opcodes);
413 (*last)->opcode = opcodes;
414 }
415 /* Use the larger nr_prefetched_words */
416 if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words)
417 (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words;
418 return (*cur_insn_ptr);
419 }
420
421 }
4e0bf4c4 422
c906108c
SS
423 /* create a new list entry and insert it */
424 {
425 insn_list *new_insn = ZALLOC (insn_list);
1fdb3c68
AC
426 if (options.trace.insn_insertion)
427 {
428 notify (insn->line,
429 "%s.%s: insert new\n",
430 insn->format_name,
431 insn->name);
432 }
c906108c
SS
433 new_insn->insn = insn;
434 new_insn->expanded_bits = expanded_bits;
435 new_insn->next = (*cur_insn_ptr);
436 new_insn->nr_prefetched_words = nr_prefetched_words;
437 if (opcodes != NULL)
438 {
439 new_insn->opcodes = ZALLOC (insn_opcodes);
440 new_insn->opcodes->opcode = opcodes;
441 }
442 (*cur_insn_ptr) = new_insn;
443 }
4e0bf4c4 444
c906108c
SS
445 *nr_insns += 1;
446
447 return (*cur_insn_ptr);
448}
449
450
451extern void
452gen_entry_traverse_tree (lf *file,
453 gen_entry *table,
454 int depth,
4e0bf4c4
AC
455 gen_entry_handler * start,
456 gen_entry_handler * leaf,
457 gen_entry_handler * end, void *data)
c906108c
SS
458{
459 gen_entry *entry;
4e0bf4c4
AC
460
461 ASSERT (table !=NULL);
c906108c
SS
462 ASSERT (table->opcode != NULL);
463 ASSERT (table->nr_entries > 0);
464 ASSERT (table->entries != 0);
4e0bf4c4 465
c906108c
SS
466 /* prefix */
467 if (start != NULL && depth >= 0)
468 {
469 start (file, table, depth, data);
470 }
471 /* infix leaves */
4e0bf4c4 472 for (entry = table->entries; entry != NULL; entry = entry->sibling)
c906108c
SS
473 {
474 if (entry->entries != NULL && depth != 0)
475 {
476 gen_entry_traverse_tree (file, entry, depth + 1,
477 start, leaf, end, data);
478 }
479 else if (depth >= 0)
480 {
481 if (leaf != NULL)
482 {
483 leaf (file, entry, depth, data);
484 }
485 }
486 }
487 /* postfix */
488 if (end != NULL && depth >= 0)
489 {
490 end (file, table, depth, data);
491 }
492}
493
494
495
496/* create a list element containing a single gen_table entry */
497
498static gen_list *
4e0bf4c4 499make_table (insn_table *isa, decode_table *rules, model_entry *model)
c906108c
SS
500{
501 insn_entry *insn;
502 gen_list *entry = ZALLOC (gen_list);
503 entry->table = ZALLOC (gen_entry);
504 entry->table->top = entry;
505 entry->model = model;
506 entry->isa = isa;
507 for (insn = isa->insns; insn != NULL; insn = insn->next)
508 {
509 if (model == NULL
510 || insn->processors == NULL
511 || filter_is_member (insn->processors, model->name))
512 {
4e0bf4c4
AC
513 insn_list_insert (&entry->table->insns, &entry->table->nr_insns, insn, NULL, /* expanded_bits - none yet */
514 NULL, /* opcodes - none yet */
515 0, /* nr_prefetched_words - none yet */
c906108c
SS
516 report_duplicate_insns);
517 }
518 }
519 entry->table->opcode_rule = rules;
520 return entry;
521}
522
523
524gen_table *
4e0bf4c4 525make_gen_tables (insn_table *isa, decode_table *rules)
c906108c
SS
526{
527 gen_table *gen = ZALLOC (gen_table);
528 gen->isa = isa;
529 gen->rules = rules;
530 if (options.gen.multi_sim)
531 {
532 gen_list **last = &gen->tables;
533 model_entry *model;
534 filter *processors;
535 if (options.model_filter != NULL)
536 processors = options.model_filter;
537 else
538 processors = isa->model->processors;
4e0bf4c4 539 for (model = isa->model->models; model != NULL; model = model->next)
c906108c
SS
540 {
541 if (filter_is_member (processors, model->name))
542 {
543 *last = make_table (isa, rules, model);
544 last = &(*last)->next;
545 }
546 }
547 }
548 else
549 {
550 gen->tables = make_table (isa, rules, NULL);
551 }
552 return gen;
553}
4e0bf4c4
AC
554
555
c906108c
SS
556/****************************************************************/
557
c906108c
SS
558/* Is the bit, according to the decode rule, identical across all the
559 instructions? */
560static int
4e0bf4c4 561insns_bit_useless (insn_list *insns, decode_table *rule, int bit_nr)
c906108c
SS
562{
563 insn_list *entry;
564 int value = -1;
4e0bf4c4 565 int is_useless = 1; /* cleared if something actually found */
c906108c
SS
566
567 /* check the instructions for some constant value in at least one of
568 the bit fields */
569 for (entry = insns; entry != NULL; entry = entry->next)
570 {
571 insn_word_entry *word = entry->insn->word[rule->word_nr];
572 insn_bit_entry *bit = word->bit[bit_nr];
573 switch (bit->field->type)
574 {
575 case insn_field_invalid:
576 ASSERT (0);
577 break;
578 case insn_field_wild:
579 case insn_field_reserved:
580 /* neither useless or useful - ignore */
581 break;
582 case insn_field_int:
583 switch (rule->search)
584 {
585 case decode_find_strings:
586 /* an integer isn't a string */
587 return 1;
588 case decode_find_constants:
589 case decode_find_mixed:
590 /* an integer is useful if its value isn't the same
4e0bf4c4
AC
591 between all instructions. The first time through the
592 value is saved, the second time through (if the
593 values differ) it is marked as useful. */
c906108c
SS
594 if (value < 0)
595 value = bit->value;
596 else if (value != bit->value)
597 is_useless = 0;
598 break;
599 }
600 break;
601 case insn_field_string:
602 switch (rule->search)
603 {
604 case decode_find_strings:
605 /* at least one string, keep checking */
606 is_useless = 0;
607 break;
608 case decode_find_constants:
609 case decode_find_mixed:
610 if (filter_is_member (rule->constant_field_names,
611 bit->field->val_string))
612 /* a string field forced to constant? */
613 is_useless = 0;
614 else if (rule->search == decode_find_constants)
615 /* the string field isn't constant */
616 return 1;
617 break;
618 }
619 }
620 }
621
622 /* Given only one constant value has been found, check through all
623 the instructions to see if at least one conditional makes it
624 usefull */
625 if (value >= 0 && is_useless)
626 {
627 for (entry = insns; entry != NULL; entry = entry->next)
628 {
629 insn_word_entry *word = entry->insn->word[rule->word_nr];
630 insn_bit_entry *bit = word->bit[bit_nr];
631 switch (bit->field->type)
632 {
633 case insn_field_invalid:
634 ASSERT (0);
635 break;
636 case insn_field_wild:
637 case insn_field_reserved:
638 case insn_field_int:
639 /* already processed */
640 break;
641 case insn_field_string:
642 switch (rule->search)
643 {
644 case decode_find_strings:
645 case decode_find_constants:
646 /* already processed */
647 break;
648 case decode_find_mixed:
649 /* string field with conditions. If this condition
4e0bf4c4 650 eliminates the value then the compare is useful */
c906108c
SS
651 if (bit->field->conditions != NULL)
652 {
653 insn_field_cond *condition;
654 int shift = bit->field->last - bit_nr;
655 for (condition = bit->field->conditions;
4e0bf4c4 656 condition != NULL; condition = condition->next)
c906108c
SS
657 {
658 switch (condition->type)
659 {
660 case insn_field_cond_value:
661 switch (condition->test)
662 {
663 case insn_field_cond_ne:
664 if (((condition->value >> shift) & 1)
665 == (unsigned) value)
666 /* conditional field excludes the
4e0bf4c4 667 current value */
c906108c
SS
668 is_useless = 0;
669 break;
670 case insn_field_cond_eq:
671 if (((condition->value >> shift) & 1)
672 != (unsigned) value)
673 /* conditional field requires the
4e0bf4c4 674 current value */
c906108c
SS
675 is_useless = 0;
676 break;
677 }
678 break;
679 case insn_field_cond_field:
680 /* are these handled separatly? */
681 break;
682 }
683 }
684 }
685 }
686 }
687 }
688 }
689
690 return is_useless;
691}
692
693
694/* go through a gen-table's list of instruction formats looking for a
695 range of bits that meet the decode table RULEs requirements */
696
697static opcode_field *
698gen_entry_find_opcode_field (insn_list *insns,
4e0bf4c4 699 decode_table *rule, int string_only)
c906108c
SS
700{
701 opcode_field curr_opcode;
702 ASSERT (rule != NULL);
703
704 memset (&curr_opcode, 0, sizeof (curr_opcode));
705 curr_opcode.word_nr = rule->word_nr;
706 curr_opcode.first = rule->first;
707 curr_opcode.last = rule->last;
708
709 /* Try to reduce the size of first..last in accordance with the
710 decode rules */
711
712 while (curr_opcode.first <= rule->last)
713 {
714 if (insns_bit_useless (insns, rule, curr_opcode.first))
4e0bf4c4 715 curr_opcode.first++;
c906108c
SS
716 else
717 break;
718 }
719 while (curr_opcode.last >= rule->first)
720 {
721 if (insns_bit_useless (insns, rule, curr_opcode.last))
4e0bf4c4 722 curr_opcode.last--;
c906108c
SS
723 else
724 break;
725 }
726
c906108c
SS
727 /* did the final opcode field end up being empty? */
728 if (curr_opcode.first > curr_opcode.last)
729 {
730 return NULL;
731 }
732 ASSERT (curr_opcode.last >= rule->first);
733 ASSERT (curr_opcode.first <= rule->last);
734 ASSERT (curr_opcode.first <= curr_opcode.last);
735
736 /* Ensure that, for the non string only case, the opcode includes
737 the range forced_first .. forced_last */
4e0bf4c4 738 if (!string_only && curr_opcode.first > rule->force_first)
c906108c
SS
739 {
740 curr_opcode.first = rule->force_first;
741 }
4e0bf4c4 742 if (!string_only && curr_opcode.last < rule->force_last)
c906108c
SS
743 {
744 curr_opcode.last = rule->force_last;
745 }
746
747 /* For the string only case, force just the lower bound (so that the
748 shift can be eliminated) */
4e0bf4c4 749 if (string_only && rule->force_last == options.insn_bit_size - 1)
c906108c
SS
750 {
751 curr_opcode.last = options.insn_bit_size - 1;
752 }
753
754 /* handle any special cases */
755 switch (rule->type)
756 {
757 case normal_decode_rule:
758 /* let the above apply */
759 curr_opcode.nr_opcodes =
760 (1 << (curr_opcode.last - curr_opcode.first + 1));
761 break;
762 case boolean_rule:
763 curr_opcode.is_boolean = 1;
764 curr_opcode.boolean_constant = rule->constant;
765 curr_opcode.nr_opcodes = 2;
766 break;
767 }
768
769 {
770 opcode_field *new_field = ZALLOC (opcode_field);
771 memcpy (new_field, &curr_opcode, sizeof (opcode_field));
772 return new_field;
773 }
774}
775
776
777static void
778gen_entry_insert_insn (gen_entry *table,
4e0bf4c4 779 insn_entry * old_insn,
c906108c
SS
780 int new_word_nr,
781 int new_nr_prefetched_words,
4e0bf4c4 782 int new_opcode_nr, opcode_bits *new_bits)
c906108c
SS
783{
784 gen_entry **entry = &table->entries;
4e0bf4c4 785
c906108c
SS
786 /* find the new table for this entry */
787 while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr)
788 {
789 entry = &(*entry)->sibling;
790 }
4e0bf4c4 791
c906108c
SS
792 if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr)
793 {
794 /* insert the missing entry */
795 gen_entry *new_entry = ZALLOC (gen_entry);
796 new_entry->sibling = (*entry);
797 (*entry) = new_entry;
798 table->nr_entries++;
799 /* fill it in */
800 new_entry->top = table->top;
801 new_entry->opcode_nr = new_opcode_nr;
802 new_entry->word_nr = new_word_nr;
803 new_entry->expanded_bits = new_bits;
804 new_entry->opcode_rule = table->opcode_rule->next;
805 new_entry->parent = table;
806 new_entry->nr_prefetched_words = new_nr_prefetched_words;
807 }
808 /* ASSERT new_bits == cur_entry bits */
809 ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr);
4e0bf4c4
AC
810 insn_list_insert (&(*entry)->insns, &(*entry)->nr_insns, old_insn, NULL, /* expanded_bits - only in final list */
811 NULL, /* opcodes - only in final list */
812 new_nr_prefetched_words, /* for this table */
c906108c
SS
813 report_duplicate_insns);
814}
815
816
817static void
818gen_entry_expand_opcode (gen_entry *table,
4e0bf4c4
AC
819 insn_entry * instruction,
820 int bit_nr, int opcode_nr, opcode_bits *bits)
c906108c
SS
821{
822 if (bit_nr > table->opcode->last)
823 {
824 /* Only include the hardwired bit information with an entry IF
825 that entry (and hence its functions) are being duplicated. */
826 if (options.trace.insn_expansion)
827 {
828 print_gen_entry_path (table->opcode_rule->line, table, notify);
829 notify (NULL, ": insert %d - %s.%s%s\n",
830 opcode_nr,
831 instruction->format_name,
832 instruction->name,
4e0bf4c4
AC
833 (table->opcode_rule->
834 with_duplicates ? " (duplicated)" : ""));
c906108c
SS
835 }
836 if (table->opcode_rule->with_duplicates)
837 {
838 gen_entry_insert_insn (table, instruction,
839 table->opcode->word_nr,
4e0bf4c4 840 table->nr_prefetched_words, opcode_nr, bits);
c906108c
SS
841 }
842 else
843 {
844 gen_entry_insert_insn (table, instruction,
845 table->opcode->word_nr,
4e0bf4c4 846 table->nr_prefetched_words, opcode_nr, NULL);
c906108c
SS
847 }
848 }
849 else
850 {
851 insn_word_entry *word = instruction->word[table->opcode->word_nr];
852 insn_field_entry *field = word->bit[bit_nr]->field;
853 int last_pos = ((field->last < table->opcode->last)
4e0bf4c4 854 ? field->last : table->opcode->last);
c906108c 855 int first_pos = ((field->first > table->opcode->first)
4e0bf4c4 856 ? field->first : table->opcode->first);
c906108c
SS
857 int width = last_pos - first_pos + 1;
858 switch (field->type)
859 {
860 case insn_field_int:
861 {
862 int val;
4e0bf4c4 863 val = sub_val (field->val_int, field->last, first_pos, last_pos);
c906108c
SS
864 gen_entry_expand_opcode (table, instruction,
865 last_pos + 1,
4e0bf4c4 866 ((opcode_nr << width) | val), bits);
c906108c
SS
867 break;
868 }
869 default:
870 {
871 if (field->type == insn_field_reserved)
872 gen_entry_expand_opcode (table, instruction,
873 last_pos + 1,
4e0bf4c4 874 ((opcode_nr << width)), bits);
c906108c
SS
875 else
876 {
877 int val;
4e0bf4c4 878 int last_val = (table->opcode->is_boolean ? 2 : (1 << width));
c906108c
SS
879 for (val = 0; val < last_val; val++)
880 {
881 /* check to see if the value has been precluded
4e0bf4c4 882 (by a conditional) in some way */
c906108c
SS
883 int is_precluded;
884 insn_field_cond *condition;
885 for (condition = field->conditions, is_precluded = 0;
886 condition != NULL && !is_precluded;
887 condition = condition->next)
888 {
889 switch (condition->type)
890 {
891 case insn_field_cond_value:
892 {
4e0bf4c4
AC
893 int value =
894 sub_val (condition->value, field->last,
895 first_pos, last_pos);
c906108c
SS
896 switch (condition->test)
897 {
898 case insn_field_cond_ne:
899 if (value == val)
900 is_precluded = 1;
901 break;
902 case insn_field_cond_eq:
903 if (value != val)
904 is_precluded = 1;
905 break;
906 }
907 break;
908 }
909 case insn_field_cond_field:
910 {
78e731cd 911 int value = -1;
c906108c 912 opcode_bits *bit;
78e731cd 913 gen_entry *t = NULL;
c906108c 914 /* Try to find a value for the
4e0bf4c4
AC
915 conditional by looking back through
916 the previously defined bits for one
917 that covers the designated
918 conditional field */
919 for (bit = bits; bit != NULL; bit = bit->next)
c906108c 920 {
4e0bf4c4
AC
921 if (bit->field->word_nr ==
922 condition->field->word_nr
c906108c
SS
923 && bit->first <= condition->field->first
924 && bit->last >= condition->field->last)
925 {
926 /* the bit field fully specified
4e0bf4c4 927 the conditional field's value */
c906108c 928 value = sub_val (bit->value, bit->last,
4e0bf4c4
AC
929 condition->field->
930 first,
931 condition->field->
932 last);
c906108c
SS
933 }
934 }
935 /* Try to find a value by looking
4e0bf4c4 936 through this and previous tables */
c906108c
SS
937 if (bit == NULL)
938 {
939 for (t = table;
4e0bf4c4 940 t->parent != NULL; t = t->parent)
c906108c 941 {
4e0bf4c4
AC
942 if (t->parent->opcode->word_nr ==
943 condition->field->word_nr
944 && t->parent->opcode->first <=
945 condition->field->first
946 && t->parent->opcode->last >=
947 condition->field->last)
c906108c
SS
948 {
949 /* the table entry fully
4e0bf4c4
AC
950 specified the condition
951 field's value */
c906108c 952 /* extract the field's value
4e0bf4c4
AC
953 from the opcode */
954 value =
955 sub_val (t->opcode_nr,
956 t->parent->opcode->last,
957 condition->field->first,
958 condition->field->last);
c906108c 959 /* this is a requirement of
4e0bf4c4
AC
960 a conditonal field
961 refering to another field */
962 ASSERT ((condition->field->first -
963 condition->field->last) ==
964 (first_pos - last_pos));
965 printf
966 ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n",
967 value, t->opcode_nr,
968 t->parent->opcode->last,
969 condition->field->first,
970 condition->field->last);
c906108c
SS
971 }
972 }
973 }
974 if (bit == NULL && t == NULL)
975 error (instruction->line,
976 "Conditional `%s' of field `%s' isn't expanded",
977 condition->string, field->val_string);
978 switch (condition->test)
979 {
980 case insn_field_cond_ne:
981 if (value == val)
982 is_precluded = 1;
983 break;
984 case insn_field_cond_eq:
985 if (value != val)
986 is_precluded = 1;
987 break;
988 }
989 break;
990 }
991 }
992 }
993 if (!is_precluded)
994 {
995 /* Only add additional hardwired bit
4e0bf4c4
AC
996 information if the entry is not going to
997 later be combined */
c906108c
SS
998 if (table->opcode_rule->with_combine)
999 {
1000 gen_entry_expand_opcode (table, instruction,
1001 last_pos + 1,
4e0bf4c4
AC
1002 ((opcode_nr << width) |
1003 val), bits);
c906108c
SS
1004 }
1005 else
1006 {
4e0bf4c4
AC
1007 opcode_bits *new_bits =
1008 new_opcode_bits (bits, val,
1009 first_pos, last_pos,
1010 field,
1011 table->opcode);
c906108c
SS
1012 gen_entry_expand_opcode (table, instruction,
1013 last_pos + 1,
4e0bf4c4
AC
1014 ((opcode_nr << width) |
1015 val), new_bits);
c906108c
SS
1016 }
1017 }
1018 }
1019 }
1020 }
1021 }
1022 }
1023}
1024
1025static void
4e0bf4c4 1026gen_entry_insert_expanding (gen_entry *table, insn_entry * instruction)
c906108c
SS
1027{
1028 gen_entry_expand_opcode (table,
1029 instruction,
4e0bf4c4 1030 table->opcode->first, 0, table->expanded_bits);
c906108c
SS
1031}
1032
1033
1034static int
4e0bf4c4 1035insns_match_format_names (insn_list *insns, filter *format_names)
c906108c
SS
1036{
1037 if (format_names != NULL)
1038 {
1039 insn_list *i;
1040 for (i = insns; i != NULL; i = i->next)
1041 {
4e0bf4c4
AC
1042 if (i->insn->format_name != NULL
1043 && !filter_is_member (format_names, i->insn->format_name))
c906108c
SS
1044 return 0;
1045 }
1046 }
1047 return 1;
1048}
1049
1050static int
4e0bf4c4 1051table_matches_path (gen_entry *table, decode_path_list *paths)
c906108c
SS
1052{
1053 if (paths == NULL)
1054 return 1;
1055 while (paths != NULL)
1056 {
1057 gen_entry *entry = table;
1058 decode_path *path = paths->path;
1059 while (1)
1060 {
1061 if (entry == NULL && path == NULL)
1062 return 1;
1063 if (entry == NULL || path == NULL)
1064 break;
1065 if (entry->opcode_nr != path->opcode_nr)
1066 break;
1067 entry = entry->parent;
1068 path = path->parent;
1069 }
1070 paths = paths->next;
1071 }
1072 return 0;
1073}
1074
1075
1076static int
4e0bf4c4 1077insns_match_conditions (insn_list *insns, decode_cond *conditions)
c906108c
SS
1078{
1079 if (conditions != NULL)
1080 {
1081 insn_list *i;
1082 for (i = insns; i != NULL; i = i->next)
1083 {
1084 decode_cond *cond;
1085 for (cond = conditions; cond != NULL; cond = cond->next)
1086 {
1087 int bit_nr;
1088 if (i->insn->nr_words <= cond->word_nr)
1089 return 0;
1090 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
1091 {
1092 if (!cond->mask[bit_nr])
1093 continue;
1094 if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask)
1095 return 0;
1096 if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value
4e0bf4c4 1097 == cond->value[bit_nr]) == !cond->is_equal)
c906108c
SS
1098 return 0;
1099 }
1100 }
1101 }
1102 }
1103 return 1;
1104}
1105
1106static int
4e0bf4c4 1107insns_match_nr_words (insn_list *insns, int nr_words)
c906108c
SS
1108{
1109 insn_list *i;
1110 for (i = insns; i != NULL; i = i->next)
1111 {
1112 if (i->insn->nr_words < nr_words)
1113 return 0;
1114 }
1115 return 1;
1116}
1117
1118static int
4e0bf4c4 1119insn_list_cmp (insn_list *l, insn_list *r)
c906108c
SS
1120{
1121 while (1)
1122 {
1123 insn_entry *insn;
1124 if (l == NULL && r == NULL)
1125 return 0;
1126 if (l == NULL)
1127 return -1;
1128 if (r == NULL)
1129 return 1;
1130 if (l->insn != r->insn)
4e0bf4c4 1131 return -1; /* somewhat arbitrary at present */
c906108c
SS
1132 /* skip this insn */
1133 insn = l->insn;
1134 while (l != NULL && l->insn == insn)
1135 l = l->next;
1136 while (r != NULL && r->insn == insn)
1137 r = r->next;
1138 }
1139}
1140
1141
1142
1143static void
1144gen_entry_expand_insns (gen_entry *table)
1145{
1146 decode_table *opcode_rule;
1147
4e0bf4c4
AC
1148 ASSERT (table->nr_insns >= 1);
1149
c906108c
SS
1150 /* determine a valid opcode */
1151 for (opcode_rule = table->opcode_rule;
4e0bf4c4 1152 opcode_rule != NULL; opcode_rule = opcode_rule->next)
c906108c
SS
1153 {
1154 char *discard_reason;
1155 if (table->top->model != NULL
1156 && opcode_rule->model_names != NULL
1157 && !filter_is_member (opcode_rule->model_names,
1158 table->top->model->name))
1159 {
1160 /* the rule isn't applicable to this processor */
1161 discard_reason = "wrong model";
1162 }
1163 else if (table->nr_insns == 1 && opcode_rule->conditions == NULL)
1164 {
1165 /* for safety, require a pre-codition when attempting to
4e0bf4c4 1166 apply a rule to a single instruction */
c906108c
SS
1167 discard_reason = "need pre-condition when nr-insn == 1";
1168 }
1169 else if (table->nr_insns == 1 && !opcode_rule->with_duplicates)
1170 {
1171 /* Little point in expanding a single instruction when we're
4e0bf4c4
AC
1172 not duplicating the semantic functions that this table
1173 calls */
c906108c
SS
1174 discard_reason = "need duplication with nr-insns == 1";
1175 }
4e0bf4c4
AC
1176 else
1177 if (!insns_match_format_names
1178 (table->insns, opcode_rule->format_names))
c906108c
SS
1179 {
1180 discard_reason = "wrong format name";
1181 }
1182 else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1))
1183 {
1184 discard_reason = "wrong nr words";
1185 }
1186 else if (!table_matches_path (table, opcode_rule->paths))
1187 {
1188 discard_reason = "path failed";
1189 }
4e0bf4c4
AC
1190 else
1191 if (!insns_match_conditions (table->insns, opcode_rule->conditions))
c906108c
SS
1192 {
1193 discard_reason = "condition failed";
1194 }
1195 else
1196 {
1197 discard_reason = "no opcode field";
4e0bf4c4
AC
1198 table->opcode = gen_entry_find_opcode_field (table->insns,
1199 opcode_rule,
1200 table->nr_insns == 1 /*string-only */
1201 );
c906108c
SS
1202 if (table->opcode != NULL)
1203 {
1204 table->opcode_rule = opcode_rule;
1205 break;
1206 }
1207 }
1208
1209 if (options.trace.rule_rejection)
1210 {
1211 print_gen_entry_path (opcode_rule->line, table, notify);
1212 notify (NULL, ": rule discarded - %s\n", discard_reason);
1213 }
1214 }
4e0bf4c4 1215
c906108c
SS
1216 /* did we find anything */
1217 if (opcode_rule == NULL)
1218 {
1219 /* the decode table failed, this set of instructions haven't
1220 been uniquely identified */
1221 if (table->nr_insns > 1)
1222 {
1223 print_gen_entry_insns (table, warning,
1224 "was not uniquely decoded",
1225 "decodes to the same entry");
1226 error (NULL, "");
1227 }
1228 return;
1229 }
1230
1231 /* Determine the number of words that must have been prefetched for
1232 this table to function */
1233 if (table->parent == NULL)
1234 table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
4e0bf4c4
AC
1235 else if (table->opcode_rule->word_nr + 1 >
1236 table->parent->nr_prefetched_words)
c906108c
SS
1237 table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
1238 else
1239 table->nr_prefetched_words = table->parent->nr_prefetched_words;
1240
1241 /* back link what we found to its parent */
1242 if (table->parent != NULL)
1243 {
4e0bf4c4 1244 ASSERT (table->parent->opcode != NULL);
c906108c
SS
1245 table->opcode->parent = table->parent->opcode;
1246 }
1247
1248 /* report the rule being used to expand the instructions */
1249 if (options.trace.rule_selection)
1250 {
1251 print_gen_entry_path (table->opcode_rule->line, table, notify);
1252 notify (NULL,
1253 ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
1254 table->opcode->word_nr,
1255 i2target (options.hi_bit_nr, table->opcode->first),
1256 i2target (options.hi_bit_nr, table->opcode->last),
1257 i2target (options.hi_bit_nr, table->opcode_rule->first),
1258 i2target (options.hi_bit_nr, table->opcode_rule->last),
4e0bf4c4 1259 table->opcode->nr_opcodes, table->nr_entries);
c906108c
SS
1260 }
1261
1262 /* expand the raw instructions according to the opcode */
1263 {
1264 insn_list *entry;
1265 for (entry = table->insns; entry != NULL; entry = entry->next)
1266 {
1267 if (options.trace.insn_expansion)
1268 {
1269 print_gen_entry_path (table->opcode_rule->line, table, notify);
1270 notify (NULL, ": expand - %s.%s\n",
4e0bf4c4 1271 entry->insn->format_name, entry->insn->name);
c906108c
SS
1272 }
1273 gen_entry_insert_expanding (table, entry->insn);
1274 }
1275 }
1276
1277 /* dump the results */
1278 if (options.trace.entries)
1279 {
1280 gen_entry *entry;
1281 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1282 {
1283 insn_list *l;
1284 print_gen_entry_path (table->opcode_rule->line, entry, notify);
1285 notify (NULL, ": %d - entries %d -",
4e0bf4c4 1286 entry->opcode_nr, entry->nr_insns);
c906108c
SS
1287 for (l = entry->insns; l != NULL; l = l->next)
1288 notify (NULL, " %s.%s", l->insn->format_name, l->insn->name);
1289 notify (NULL, "\n");
1290 }
1291 }
4e0bf4c4 1292
c906108c
SS
1293 /* perform a combine pass if needed */
1294 if (table->opcode_rule->with_combine)
1295 {
1296 gen_entry *entry;
1297 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1298 {
1299 if (entry->combined_parent == NULL)
1300 {
1301 gen_entry **last = &entry->combined_next;
1302 gen_entry *alt;
1303 for (alt = entry->sibling; alt != NULL; alt = alt->sibling)
1304 {
1305 if (alt->combined_parent == NULL
1306 && insn_list_cmp (entry->insns, alt->insns) == 0)
1307 {
1308 alt->combined_parent = entry;
1309 *last = alt;
1310 last = &alt->combined_next;
1311 }
1312 }
1313 }
1314 }
1315 if (options.trace.combine)
1316 {
1317 int nr_unique = 0;
1318 gen_entry *entry;
1319 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1320 {
1321 if (entry->combined_parent == NULL)
1322 {
1323 insn_list *l;
1324 gen_entry *duplicate;
1325 nr_unique++;
4e0bf4c4
AC
1326 print_gen_entry_path (table->opcode_rule->line, entry,
1327 notify);
1328 for (duplicate = entry->combined_next; duplicate != NULL;
c906108c
SS
1329 duplicate = duplicate->combined_next)
1330 {
1331 notify (NULL, "+%d", duplicate->opcode_nr);
1332 }
1333 notify (NULL, ": entries %d -", entry->nr_insns);
1334 for (l = entry->insns; l != NULL; l = l->next)
1335 {
1336 notify (NULL, " %s.%s",
4e0bf4c4 1337 l->insn->format_name, l->insn->name);
c906108c
SS
1338 }
1339 notify (NULL, "\n");
1340 }
1341 }
1342 print_gen_entry_path (table->opcode_rule->line, table, notify);
4e0bf4c4
AC
1343 notify (NULL,
1344 ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
1345 table->opcode->word_nr, i2target (options.hi_bit_nr,
1346 table->opcode->first),
c906108c
SS
1347 i2target (options.hi_bit_nr, table->opcode->last),
1348 i2target (options.hi_bit_nr, table->opcode_rule->first),
1349 i2target (options.hi_bit_nr, table->opcode_rule->last),
4e0bf4c4 1350 table->opcode->nr_opcodes, table->nr_entries, nr_unique);
c906108c
SS
1351 }
1352 }
4e0bf4c4 1353
c906108c
SS
1354 /* Check that the rule did more than re-arange the order of the
1355 instructions */
1356 {
4e0bf4c4
AC
1357 gen_entry *entry;
1358 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1359 {
1360 if (entry->combined_parent == NULL)
1361 {
1362 if (insn_list_cmp (table->insns, entry->insns) == 0)
1363 {
1364 print_gen_entry_path (table->opcode_rule->line, table,
1365 warning);
1366 warning (NULL,
1367 ": Applying rule just copied all instructions\n");
1368 print_gen_entry_insns (entry, warning, "Copied", NULL);
1369 error (NULL, "");
1370 }
1371 }
1372 }
c906108c
SS
1373 }
1374
1375 /* if some form of expanded table, fill in the missing dots */
1376 switch (table->opcode_rule->gen)
1377 {
1378 case padded_switch_gen:
1379 case array_gen:
1380 case goto_switch_gen:
1381 if (!table->opcode->is_boolean)
1382 {
1383 gen_entry **entry = &table->entries;
1384 gen_entry *illegals = NULL;
1385 gen_entry **last_illegal = &illegals;
1386 int opcode_nr = 0;
1387 while (opcode_nr < table->opcode->nr_opcodes)
1388 {
1389 if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr)
1390 {
1391 /* missing - insert it under our feet at *entry */
4e0bf4c4 1392 gen_entry_insert_insn (table, table->top->isa->illegal_insn, table->opcode->word_nr, 0, /* nr_prefetched_words == 0 for invalid */
c906108c
SS
1393 opcode_nr, NULL);
1394 ASSERT ((*entry) != NULL);
1395 ASSERT ((*entry)->opcode_nr == opcode_nr);
1396 (*last_illegal) = *entry;
1397 (*last_illegal)->combined_parent = illegals;
1398 last_illegal = &(*last_illegal)->combined_next;
1399 }
1400 entry = &(*entry)->sibling;
1401 opcode_nr++;
1402 }
1403 /* oops, will have pointed the first illegal insn back to
4e0bf4c4 1404 its self. Fix this */
c906108c
SS
1405 if (illegals != NULL)
1406 illegals->combined_parent = NULL;
1407 }
1408 break;
1409 case switch_gen:
1410 case invalid_gen:
1411 /* ignore */
1412 break;
1413 }
1414
1415 /* and do the same for the newly created sub entries but *only*
1416 expand entries that haven't been combined. */
1417 {
1418 gen_entry *entry;
4e0bf4c4 1419 for (entry = table->entries; entry != NULL; entry = entry->sibling)
c906108c
SS
1420 {
1421 if (entry->combined_parent == NULL)
1422 {
1423 gen_entry_expand_insns (entry);
1424 }
1425 }
1426 }
1427}
1428
1429void
1430gen_tables_expand_insns (gen_table *gen)
1431{
1432 gen_list *entry;
1433 for (entry = gen->tables; entry != NULL; entry = entry->next)
1434 {
1435 gen_entry_expand_insns (entry->table);
1436 }
1437}
1438
1439
1440/* create a list of all the semantic functions that need to be
1441 generated. Eliminate any duplicates. Verify that the decode stage
1442 worked. */
1443
1444static void
4e0bf4c4 1445make_gen_semantics_list (lf *file, gen_entry *entry, int depth, void *data)
c906108c 1446{
4e0bf4c4 1447 gen_table *gen = (gen_table *) data;
c906108c
SS
1448 insn_list *insn;
1449 /* Not interested in an entrie that have been combined into some
1450 other entry at the same level */
1451 if (entry->combined_parent != NULL)
1452 return;
1453
1454 /* a leaf should contain exactly one instruction. If not the decode
1455 stage failed. */
1456 ASSERT (entry->nr_insns == 1);
1457
1458 /* Enter this instruction into the list of semantic functions. */
1459 insn = insn_list_insert (&gen->semantics, &gen->nr_semantics,
1460 entry->insns->insn,
1461 entry->expanded_bits,
1462 entry->parent->opcode,
1463 entry->insns->nr_prefetched_words,
1464 merge_duplicate_insns);
1465 /* point the table entry at the real semantic function */
1466 ASSERT (insn != NULL);
1467 entry->insns->semantic = insn;
1468}
1469
1470
1471void
1472gen_tables_expand_semantics (gen_table *gen)
1473{
1474 gen_list *entry;
1475 for (entry = gen->tables; entry != NULL; entry = entry->next)
1476 {
4e0bf4c4
AC
1477 gen_entry_traverse_tree (NULL, entry->table, 1, /* depth */
1478 NULL, /* start-handler */
1479 make_gen_semantics_list, /* leaf-handler */
1480 NULL, /* end-handler */
1481 gen); /* data */
1482 }
c906108c
SS
1483}
1484
1485
1486
1487#ifdef MAIN
1488
1489
1490static void
1491dump_opcode_field (lf *file,
1492 char *prefix,
4e0bf4c4 1493 opcode_field *field, char *suffix, int levels)
c906108c
SS
1494{
1495 lf_printf (file, "%s(opcode_field *) 0x%lx", prefix, (long) field);
4e0bf4c4
AC
1496 if (levels && field != NULL)
1497 {
1498 lf_indent (file, +1);
1499 lf_printf (file, "\n(first %d)", field->first);
1500 lf_printf (file, "\n(last %d)", field->last);
1501 lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);
1502 lf_printf (file, "\n(is_boolean %d)", field->is_boolean);
1503 lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);
1504 dump_opcode_field (file, "\n(parent ", field->parent, ")", levels - 1);
1505 lf_indent (file, -1);
1506 }
c906108c
SS
1507 lf_printf (file, "%s", suffix);
1508}
1509
1510
1511static void
1512dump_opcode_bits (lf *file,
4e0bf4c4 1513 char *prefix, opcode_bits *bits, char *suffix, int levels)
c906108c
SS
1514{
1515 lf_printf (file, "%s(opcode_bits *) 0x%lx", prefix, (long) bits);
4e0bf4c4 1516
c906108c
SS
1517 if (levels && bits != NULL)
1518 {
1519 lf_indent (file, +1);
1520 lf_printf (file, "\n(value %d)", bits->value);
1521 dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0);
1522 dump_insn_field (file, "\n(field ", bits->field, ")");
1523 dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1);
1524 lf_indent (file, -1);
1525 }
1526 lf_printf (file, "%s", suffix);
1527}
1528
1529
1530
1531static void
4e0bf4c4 1532dump_insn_list (lf *file, char *prefix, insn_list *entry, char *suffix)
c906108c
SS
1533{
1534 lf_printf (file, "%s(insn_list *) 0x%lx", prefix, (long) entry);
1535
4e0bf4c4
AC
1536 if (entry != NULL)
1537 {
1538 lf_indent (file, +1);
1539 dump_insn_entry (file, "\n(insn ", entry->insn, ")");
1540 lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1541 lf_indent (file, -1);
1542 }
c906108c
SS
1543 lf_printf (file, "%s", suffix);
1544}
1545
1546
1547static void
1548dump_insn_word_entry_list_entries (lf *file,
4e0bf4c4
AC
1549 char *prefix,
1550 insn_list *entry, char *suffix)
c906108c
SS
1551{
1552 lf_printf (file, "%s", prefix);
1553 while (entry != NULL)
1554 {
1555 dump_insn_list (file, "\n(", entry, ")");
1556 entry = entry->next;
1557 }
1558 lf_printf (file, "%s", suffix);
1559}
1560
1561
1562static void
1563dump_gen_entry (lf *file,
4e0bf4c4 1564 char *prefix, gen_entry *table, char *suffix, int levels)
c906108c
SS
1565{
1566
1567 lf_printf (file, "%s(gen_entry *) 0x%lx", prefix, (long) table);
1568
4e0bf4c4
AC
1569 if (levels && table !=NULL)
1570 {
1571
1572 lf_indent (file, +1);
1573 lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);
1574 lf_printf (file, "\n(word_nr %d)", table->word_nr);
1575 dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")",
1576 -1);
1577 lf_printf (file, "\n(nr_insns %d)", table->nr_insns);
1578 dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns,
1579 ")");
1580 dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");
1581 dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);
1582 lf_printf (file, "\n(nr_entries %d)", table->nr_entries);
1583 dump_gen_entry (file, "\n(entries ", table->entries, ")",
1584 table->nr_entries);
1585 dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);
1586 dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);
1587 lf_indent (file, -1);
1588 }
c906108c
SS
1589 lf_printf (file, "%s", suffix);
1590}
1591
1592static void
1593dump_gen_list (lf *file,
4e0bf4c4 1594 char *prefix, gen_list *entry, char *suffix, int levels)
c906108c
SS
1595{
1596 while (entry != NULL)
1597 {
1598 lf_printf (file, "%s(gen_list *) 0x%lx", prefix, (long) entry);
1599 dump_gen_entry (file, "\n(", entry->table, ")", levels);
1600 lf_printf (file, "\n(next (gen_list *) 0x%lx)", (long) entry->next);
1601 lf_printf (file, "%s", suffix);
1602 }
1603}
1604
1605
1606static void
1607dump_gen_table (lf *file,
4e0bf4c4 1608 char *prefix, gen_table *gen, char *suffix, int levels)
c906108c
SS
1609{
1610 lf_printf (file, "%s(gen_table *) 0x%lx", prefix, (long) gen);
1611 lf_printf (file, "\n(isa (insn_table *) 0x%lx)", (long) gen->isa);
1612 lf_printf (file, "\n(rules (decode_table *) 0x%lx)", (long) gen->rules);
1613 dump_gen_list (file, "\n(", gen->tables, ")", levels);
1614 lf_printf (file, "%s", suffix);
1615}
1616
1617
1618igen_options options;
1619
1620int
4e0bf4c4 1621main (int argc, char **argv)
c906108c
SS
1622{
1623 decode_table *decode_rules;
1624 insn_table *instructions;
1625 gen_table *gen;
1626 lf *l;
1627
1628 if (argc != 7)
4e0bf4c4
AC
1629 error (NULL,
1630 "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
c906108c
SS
1631
1632 INIT_OPTIONS (options);
1633
1634 filter_parse (&options.flags_filter, argv[1]);
1635
4e0bf4c4
AC
1636 options.hi_bit_nr = a2i (argv[2]);
1637 options.insn_bit_size = a2i (argv[3]);
1638 options.insn_specifying_widths = a2i (argv[4]);
1639 ASSERT (options.hi_bit_nr < options.insn_bit_size);
c906108c
SS
1640
1641 instructions = load_insn_table (argv[6], NULL);
1642 decode_rules = load_decode_table (argv[5]);
1643 gen = make_gen_tables (instructions, decode_rules);
1644
1645 gen_tables_expand_insns (gen);
1646
1647 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1648
1649 dump_gen_table (l, "(", gen, ")\n", -1);
1650 return 0;
1651}
1652
1653#endif
This page took 0.587628 seconds and 4 git commands to generate.