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