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
sub_val(insn_uint val,int val_last_pos,int first_pos,int last_pos)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
update_depth(lf * file,const gen_entry * entry,int depth,void * data)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
gen_entry_depth(const gen_entry * table)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
print_gen_entry_path(const line_ref * line,const gen_entry * table,error_func * print)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
print_gen_entry_insns(const gen_entry * table,error_func * print,const char * first_message,const char * next_message)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
insn_field_cmp(const insn_word_entry * l,const insn_word_entry * r)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
insn_word_cmp(const insn_word_entry * l,const insn_word_entry * r)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
opcode_bit_cmp(const opcode_bits * l,const opcode_bits * r)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
opcode_bits_cmp(const opcode_bits * l,const opcode_bits * r)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 *
new_opcode_bits(opcode_bits * old_bits,int value,int first,int last,insn_field_entry * field,opcode_field * opcode)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
name_cmp(const char * l,const char * r)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 *
insn_list_insert(insn_list ** cur_insn_ptr,int * nr_insns,insn_entry * insn,opcode_bits * expanded_bits,opcode_field * opcodes,int nr_prefetched_words,duplicate_insn_actions duplicate_action)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
gen_entry_traverse_tree(lf * file,const gen_entry * table,int depth,gen_entry_handler * start,gen_entry_handler * leaf,gen_entry_handler * end,void * data)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 *
make_table(const insn_table * isa,const decode_table * rules,const model_entry * model)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 *
make_gen_tables(const insn_table * isa,const decode_table * rules)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
insns_bit_useless(const insn_list * insns,const decode_table * rule,int bit_nr)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 *
gen_entry_find_opcode_field(insn_list * insns,const decode_table * rule,int string_only)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
gen_entry_insert_insn(gen_entry * table,insn_entry * old_insn,int new_word_nr,int new_nr_prefetched_words,int new_opcode_nr,opcode_bits * new_bits)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
gen_entry_expand_opcode(gen_entry * table,insn_entry * instruction,int bit_nr,int opcode_nr,opcode_bits * bits)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
gen_entry_insert_expanding(gen_entry * table,insn_entry * instruction)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
insns_match_format_names(insn_list * insns,filter * format_names)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
table_matches_path(gen_entry * table,decode_path_list * paths)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
insns_match_conditions(insn_list * insns,decode_cond * conditions)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
insns_match_nr_words(const insn_list * insns,int nr_words)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
insn_list_cmp(const insn_list * l,const insn_list * r)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
gen_entry_expand_insns(gen_entry * table)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
gen_tables_expand_insns(gen_table * gen)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
make_gen_semantics_list(lf * file,const gen_entry * entry,int depth,void * data)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
gen_tables_expand_semantics(gen_table * gen)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
dump_opcode_field(lf * file,char * prefix,opcode_field * field,char * suffix,int levels)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
dump_opcode_bits(lf * file,char * prefix,opcode_bits * bits,char * suffix,int levels)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
dump_insn_list(lf * file,char * prefix,insn_list * entry,char * suffix)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
dump_insn_word_entry_list_entries(lf * file,char * prefix,insn_list * entry,char * suffix)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
dump_gen_entry(lf * file,char * prefix,gen_entry * table,char * suffix,int levels)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
dump_gen_list(lf * file,char * prefix,gen_list * entry,char * suffix,int levels)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
dump_gen_table(lf * file,char * prefix,gen_table * gen,char * suffix,int levels)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
main(int argc,char ** argv)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