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