Lots of changes
[external/binutils.git] / sim / ppc / igen.c
1 /*  This file is part of the program psim.
2
3     Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  
19     */
20
21 #include <stdio.h>
22 #include <ctype.h>
23 #include <string.h>
24 #include <getopt.h>
25
26 #include "misc.h"
27 #include "lf.h"
28 #include "table.h"
29
30
31 /****************************************************************/
32
33 enum {
34   insn_size = 32,
35 };
36
37 int idecode_expand_semantics = 0;
38 int idecode_cache = 0;
39 int number_lines = 1;
40
41
42 /****************************************************************/
43
44
45 char *cache_idecode_formal = "cpu *processor,\n instruction_word instruction,\n unsigned_word cia,\n idecode_cache *cache_entry";
46 char *cache_idecode_actual = "processor, instruction, cia, cache_entry";
47
48 char *cache_semantic_formal = "cpu *processor,\n idecode_cache *cache_entry,\n unsigned_word cia";
49 char *cache_semantic_actual = "processor, entry, cia";
50
51 char *semantic_formal = "cpu *processor,\n instruction_word instruction,\n unsigned_word cia";
52 char *semantic_actual = "processor, instruction, cia";
53
54 char *semantic_local = "unsigned_word nia = cia + 4;";
55
56
57 /****************************************************************/
58
59
60 typedef struct _filter filter;
61 struct _filter {
62   char *flag;
63   filter *next;
64 };
65 filter *filters = NULL;
66
67
68 /****************************************************************/
69
70
71 typedef struct _cache_rules cache_rules;
72 struct _cache_rules {
73   int valid;
74   char *old_name;
75   char *new_name;
76   char *type;
77   char *expression;
78   cache_rules *next;
79 };
80 cache_rules *cache_table;
81
82
83 enum {
84   ca_valid,
85   ca_old_name,
86   ca_new_name,
87   ca_type,
88   ca_expression,
89   nr_cache_rule_fields,
90 };
91
92 static cache_rules *
93 load_cache_rules(char *file_name)
94 {
95   table *file = table_open(file_name, nr_cache_rule_fields);
96   table_entry *entry;
97   cache_rules *table = NULL;
98   cache_rules **curr_rule = &table;
99   while ((entry = table_entry_read(file)) != NULL) {
100     cache_rules *new_rule = ZALLOC(cache_rules);
101     new_rule->valid = a2i(entry->fields[ca_valid]);
102     new_rule->old_name = entry->fields[ca_old_name];
103     new_rule->new_name = entry->fields[ca_new_name];
104     new_rule->type = (strlen(entry->fields[ca_type])
105                       ? entry->fields[ca_type]
106                       : NULL);
107     new_rule->expression = (strlen(entry->fields[ca_expression]) > 0
108                             ? entry->fields[ca_expression]
109                             : NULL);
110     *curr_rule = new_rule;
111     curr_rule = &new_rule->next;
112   }
113   return table;
114 }
115
116
117
118 static void
119 dump_cache_rule(cache_rules* rule,
120                 int indent)
121 {
122   dumpf(indent, "((cache_rules*)0x%x\n", rule);
123   dumpf(indent, " (valid %d)\n", rule->valid);
124   dumpf(indent, " (old_name \"%s\")\n", rule->old_name);
125   dumpf(indent, " (new_name \"%s\")\n", rule->new_name);
126   dumpf(indent, " (type \"%s\")\n", rule->type);
127   dumpf(indent, " (expression \"%s\")\n", rule->expression);
128   dumpf(indent, " (next 0x%x)\n", rule->next);
129   dumpf(indent, " )\n");
130 }
131
132
133 static void
134 dump_cache_rules(cache_rules* rule, int indent)
135 {
136   while (rule) {
137     dump_cache_rule(rule, indent);
138     rule = rule->next;
139   }
140 }
141
142
143 /****************************************************************/
144
145
146 typedef struct _opcode_rules opcode_rules;
147 struct _opcode_rules {
148   int first;
149   int last;
150   int force_first;
151   int force_last;
152   int force_slash;
153   char *force_expansion;
154   int use_switch;
155   unsigned special_mask;
156   unsigned special_value;
157   unsigned special_rule;
158   opcode_rules *next;
159 };
160 opcode_rules *opcode_table;
161
162
163 enum {
164   op_first,
165   op_last,
166   op_force_first,
167   op_force_last,
168   op_force_slash,
169   op_force_expansion,
170   op_use_switch,
171   op_special_mask,
172   op_special_value,
173   op_special_rule,
174   nr_opcode_fields,
175 };
176
177
178 static opcode_rules *
179 load_opcode_rules(char *file_name)
180 {
181   table *file = table_open(file_name, nr_opcode_fields);
182   table_entry *entry;
183   opcode_rules *table = NULL;
184   opcode_rules **curr_rule = &table;
185   while ((entry = table_entry_read(file)) != NULL) {
186     opcode_rules *new_rule = ZALLOC(opcode_rules);
187     new_rule->first = a2i(entry->fields[op_first]);
188     new_rule->last = a2i(entry->fields[op_last]);
189     new_rule->force_first = a2i(entry->fields[op_force_first]);
190     new_rule->force_last = a2i(entry->fields[op_force_last]);
191     new_rule->force_slash = a2i(entry->fields[op_force_slash]);
192     new_rule->force_expansion = entry->fields[op_force_expansion];
193     new_rule->use_switch = a2i(entry->fields[op_use_switch]);
194     new_rule->special_mask = a2i(entry->fields[op_special_mask]);
195     new_rule->special_value = a2i(entry->fields[op_special_value]);
196     new_rule->special_rule = a2i(entry->fields[op_special_rule]);
197     *curr_rule = new_rule;
198     curr_rule = &new_rule->next;
199   }
200   return table;
201 }
202
203   
204 static void
205 dump_opcode_rule(opcode_rules *rule,
206                  int indent)
207 {
208   dumpf(indent, "((opcode_rules*)%p\n", rule);
209   if (rule) {
210     dumpf(indent, " (first %d)\n", rule->first);
211     dumpf(indent, " (last %d)\n", rule->last);
212     dumpf(indent, " (force_first %d)\n", rule->force_first);
213     dumpf(indent, " (force_last %d)\n", rule->force_last);
214     dumpf(indent, " (force_slash %d)\n", rule->force_slash);
215     dumpf(indent, " (force_expansion \"%s\")\n", rule->force_expansion);
216     dumpf(indent, " (use_switch %d)\n", rule->use_switch);
217     dumpf(indent, " (special_mask 0x%x)\n", rule->special_mask);
218     dumpf(indent, " (special_value 0x%x)\n", rule->special_value);
219     dumpf(indent, " (special_rule 0x%x)\n", rule->special_rule);
220     dumpf(indent, " (next 0x%x)\n", rule->next);
221   }
222   dumpf(indent, " )\n");
223 }
224
225
226 static void
227 dump_opcode_rules(opcode_rules *rule,
228                   int indent)
229 {
230   while (rule) {
231     dump_opcode_rule(rule, indent);
232     rule = rule->next;
233   }
234 }
235
236
237 /****************************************************************/
238
239 typedef struct _insn_field insn_field;
240 struct _insn_field {
241   int first;
242   int last;
243   int width;
244   int is_int;
245   int is_slash;
246   int is_string;
247   int val_int;
248   char *pos_string;
249   char *val_string;
250   insn_field *next;
251   insn_field *prev;
252 };
253
254 typedef struct _insn_fields insn_fields;
255 struct _insn_fields {
256   insn_field *bits[insn_size];
257   insn_field *first;
258   insn_field *last;
259   unsigned value;
260 };
261
262 static insn_fields *
263 parse_insn_format(table_entry *entry,
264                   char *format)
265 {
266   char *chp;
267   insn_fields *fields = ZALLOC(insn_fields);
268
269   /* create a leading sentinal */
270   fields->first = ZALLOC(insn_field);
271   fields->first->first = -1;
272   fields->first->last = -1;
273   fields->first->width = 0;
274
275   /* and a trailing sentinal */
276   fields->last = ZALLOC(insn_field);
277   fields->last->first = insn_size;
278   fields->last->last = insn_size;
279   fields->last->width = 0;
280
281   /* link them together */
282   fields->first->next = fields->last;
283   fields->last->prev = fields->first;
284
285   /* now work through the formats */
286   chp = format;
287
288   while (*chp != '\0') {
289     char *start_pos;
290     char *start_val;
291     int strlen_val;
292     int strlen_pos;
293     insn_field *new_field;
294
295     /* sanity check */
296     if (!isdigit(*chp)) {
297       error("%s:%d: missing position field at `%s'\n",
298             entry->file_name, entry->line_nr, chp);
299     }
300
301     /* break out the bit position */
302     start_pos = chp;
303     while (isdigit(*chp))
304       chp++;
305     strlen_pos = chp - start_pos;
306     if (*chp == '.' && strlen_pos > 0)
307       chp++;
308     else {
309       error("%s:%d: missing field value at %s\n",
310             entry->file_name, entry->line_nr, chp);
311       break;
312     }
313
314     /* break out the value */
315     start_val = chp;
316     while ((*start_val == '/' && *chp == '/')
317            || (isdigit(*start_val) && isdigit(*chp))
318            || (isalpha(*start_val) && (isalnum(*chp) || *chp == '_')))
319       chp++;
320     strlen_val = chp - start_val;
321     if (*chp == ',')
322       chp++;
323     else if (*chp != '\0' || strlen_val == 0) {
324       error("%s:%d: missing field terminator at %s\n",
325             entry->file_name, entry->line_nr, chp);
326       break;
327     }
328
329     /* create a new field and insert it */
330     new_field = ZALLOC(insn_field);
331     new_field->next = fields->last;
332     new_field->prev = fields->last->prev;
333     new_field->next->prev = new_field;
334     new_field->prev->next = new_field;
335
336     /* the value */
337     new_field->val_string = (char*)zalloc(strlen_val+1);
338     strncpy(new_field->val_string, start_val, strlen_val);
339     if (isdigit(*new_field->val_string)) {
340       new_field->val_int = a2i(new_field->val_string);
341       new_field->is_int = 1;
342     }
343     else if (new_field->val_string[0] == '/') {
344       new_field->is_slash = 1;
345     }
346     else {
347       new_field->is_string = 1;
348     }
349     
350     /* the pos */
351     new_field->pos_string = (char*)zalloc(strlen_pos+1);
352     strncpy(new_field->pos_string, start_pos, strlen_pos);
353     new_field->first = a2i(new_field->pos_string);
354     new_field->last = new_field->next->first - 1; /* guess */
355     new_field->width = new_field->last - new_field->first + 1; /* guess */
356     new_field->prev->last = new_field->first-1; /*fix*/
357     new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
358   }
359
360   /* fiddle first/last so that the sentinals `disapear' */
361   ASSERT(fields->first->last < 0);
362   ASSERT(fields->last->first >= insn_size);
363   fields->first = fields->first->next;
364   fields->last = fields->last->prev;
365
366   /* now go over this again, pointing each bit position at a field
367      record */
368   {
369     int i;
370     insn_field *field;
371     field = fields->first;
372     for (i = 0; i < insn_size; i++) {
373       while (field->last < i)
374         field = field->next;
375       fields->bits[i] = field;
376     }
377   }
378
379   /* go over each of the fields, and compute a `value' for the insn */
380   {
381     insn_field *field;
382     fields->value = 0;
383     for (field = fields->first;
384          field->last < insn_size;
385          field = field->next) {
386       fields->value <<= field->width;
387       if (field->is_int)
388         fields->value |= field->val_int;
389     }
390   }
391   return fields;
392 }
393
394
395 typedef enum {
396   field_constant_int = 1,
397   field_constant_slash = 2,
398   field_constant_string = 3
399 } constant_field_types;
400
401
402 static int
403 insn_field_is_constant(insn_field *field,
404                        opcode_rules *rule)
405 {
406   /* field is an integer */
407   if (field->is_int)
408     return field_constant_int;
409   /* field is `/' and treating that as a constant */
410   if (field->is_slash && rule->force_slash)
411     return field_constant_slash;
412   /* field, though variable is on the list */
413   if (field->is_string && rule->force_expansion != NULL) {
414     char *forced_fields = rule->force_expansion;
415     while (*forced_fields != '\0') {
416       int field_len;
417       char *end = strchr(forced_fields, ',');
418       if (end == NULL)
419         field_len = strlen(forced_fields);
420       else
421         field_len = end-forced_fields;
422       if (strncmp(forced_fields, field->val_string, field_len) == 0
423           && field->val_string[field_len] == '\0')
424         return field_constant_string;
425       forced_fields += field_len;
426       if (*forced_fields == ',')
427         forced_fields++;
428     }
429   }
430   return 0;
431 }
432
433
434 static void
435 dump_insn_field(insn_field *field,
436                 int indent)
437 {
438
439   printf("(insn_field*)0x%x\n", (unsigned)field);
440
441   dumpf(indent, "(first %d)\n", field->first);
442
443   dumpf(indent, "(last %d)\n", field->last);
444
445   dumpf(indent, "(width %d)\n", field->width);
446
447   if (field->is_int)
448     dumpf(indent, "(is_int %d)\n", field->val_int);
449
450   if (field->is_slash)
451     dumpf(indent, "(is_slash)\n");
452
453   if (field->is_string)
454     dumpf(indent, "(is_string `%s')\n", field->val_string);
455   
456   dumpf(indent, "(next 0x%x)\n", field->next);
457   
458   dumpf(indent, "(prev 0x%x)\n", field->prev);
459   
460
461 }
462
463 static void
464 dump_insn_fields(insn_fields *fields,
465                  int indent)
466 {
467   int i;
468
469   printf("(insn_fields*)%p\n", fields);
470
471   dumpf(indent, "(first 0x%x)\n", fields->first);
472   dumpf(indent, "(last 0x%x)\n", fields->last);
473
474   dumpf(indent, "(value 0x%x)\n", fields->value);
475
476   for (i = 0; i < insn_size; i++) {
477     dumpf(indent, "(bits[%d] ", i, fields->bits[i]);
478     dump_insn_field(fields->bits[i], indent+1);
479     dumpf(indent, " )\n");
480   }
481
482 }
483
484
485 /****************************************************************/
486
487 typedef struct _opcode_field opcode_field;
488 struct _opcode_field {
489   int first;
490   int last;
491   int is_boolean;
492   opcode_field *parent;
493 };
494
495 static opcode_field *
496 opcode_field_new()
497 {
498   opcode_field *new_field = (opcode_field*)zalloc(sizeof(opcode_field));
499   ASSERT(new_field != NULL);
500   new_field->first = insn_size;
501   new_field->last = -1;
502   return new_field;
503 }
504
505 static void
506 dump_opcode_field(opcode_field *field, int indent, int levels)
507 {
508   printf("(opcode_field*)%p\n", field);
509   if (levels && field != NULL) {
510     dumpf(indent, "(first %d)\n", field->first);
511     dumpf(indent, "(last %d)\n", field->last);
512     dumpf(indent, "(is_boolean %d)\n", field->is_boolean);
513     dumpf(indent, "(parent ");
514     dump_opcode_field(field->parent, indent, levels-1);
515   }
516 }
517
518
519 /****************************************************************/
520
521 typedef struct _insn_bits insn_bits;
522 struct _insn_bits {
523   int is_expanded;
524   int value;
525   insn_field *field;
526   opcode_field *opcode;
527   insn_bits *last;
528 };
529
530
531 static void
532 dump_insn_bits(insn_bits *bits, int indent, int levels)
533 {
534   printf("(insn_bits*)%p\n", bits);
535
536   if (levels && bits != NULL) {
537     dumpf(indent, "(value %d)\n", bits->value);
538     dumpf(indent, "(opcode ");
539     dump_opcode_field(bits->opcode, indent+1, 0);
540     dumpf(indent, " )\n");
541     dumpf(indent, "(field ");
542     dump_insn_field(bits->field, indent+1);
543     dumpf(indent, " )\n");
544     dumpf(indent, "(last ");
545     dump_insn_bits(bits->last, indent+1, levels-1);
546   }
547 }
548
549
550 /****************************************************************/
551
552
553 typedef enum {
554   insn_format,
555   insn_form,
556   insn_flags,
557   insn_nmemonic,
558   insn_name,
559   insn_comment,
560   nr_insn_table_fields,
561 } insn_table_fields;
562 char *insn_field_name[nr_insn_table_fields] = {
563   "format", "form", "flags", "nmemonic", "name", "comments"
564 };
565
566 typedef enum {
567   function_type = insn_format,
568   function_name = insn_name,
569   function_param = insn_comment,
570 } function_table_fields;
571
572
573 typedef struct _insn insn;
574 struct _insn {
575   table_entry *file_entry;
576   insn_fields *fields;
577   insn *next;
578 };
579
580 typedef struct _insn_table insn_table;
581 struct _insn_table {
582   int opcode_nr;
583   insn_bits *expanded_bits;
584   int nr_insn;
585   insn *insns;
586   insn *functions;
587   opcode_rules *opcode_rule;
588   opcode_field *opcode;
589   int nr_entries;
590   insn_table *entries;
591   insn_table *sibling;
592   insn_table *parent;
593 };
594
595
596
597 static void
598 insn_table_insert_function(insn_table *table,
599                            table_entry *file_entry)
600 {
601   insn **ptr_to_cur_function = &table->functions;
602
603   /* create a new function */
604   insn *new_function = ZALLOC(insn);
605   new_function->file_entry = file_entry;
606
607   /* append it to the end of the function list */
608   while (*ptr_to_cur_function != NULL) {
609     ptr_to_cur_function = &(*ptr_to_cur_function)->next;
610   }
611   *ptr_to_cur_function = new_function;
612 }
613
614
615 static void
616 insn_table_insert_insn(insn_table *table,
617                        table_entry *file_entry,
618                        insn_fields *fields)
619 {
620   insn **ptr_to_cur_insn = &table->insns;
621   insn *cur_insn = *ptr_to_cur_insn;
622
623   /* create a new instruction */
624   insn *new_insn = ZALLOC(insn);
625   new_insn->file_entry = file_entry;
626   new_insn->fields = fields;
627
628   /* insert it according to the order of the fields */
629   while (cur_insn != NULL
630          && new_insn->fields->value >= cur_insn->fields->value) {
631     ptr_to_cur_insn = &cur_insn->next;
632     cur_insn = *ptr_to_cur_insn;
633   }
634
635   new_insn->next = cur_insn;
636   *ptr_to_cur_insn = new_insn;
637
638   table->nr_insn++;
639 }
640
641
642 static opcode_field *
643 insn_table_find_opcode_field(insn *insns,
644                              opcode_rules *rule,
645                              int string_only)
646 {
647   opcode_field *curr_opcode = opcode_field_new();
648   insn *entry;
649
650   ASSERT(rule);
651
652   for (entry = insns; entry != NULL; entry = entry->next) {
653     insn_fields *fields = entry->fields;
654     opcode_field new_opcode;
655
656     /* find a start point for the opcode field */
657     new_opcode.first = rule->first;
658     while (new_opcode.first <= rule->last
659            && (!string_only
660                || insn_field_is_constant(fields->bits[new_opcode.first],
661                                          rule) != field_constant_string)
662            && (string_only
663                || !insn_field_is_constant(fields->bits[new_opcode.first],
664                                           rule)))
665       new_opcode.first = fields->bits[new_opcode.first]->last + 1;
666     ASSERT(new_opcode.first > rule->last
667            || (string_only
668                && insn_field_is_constant(fields->bits[new_opcode.first],
669                                          rule) == field_constant_string)
670            || (!string_only
671                && insn_field_is_constant(fields->bits[new_opcode.first],
672                                          rule)));
673   
674     /* find the end point for the opcode field */
675     new_opcode.last = rule->last;
676     while (new_opcode.last >= rule->first
677            && (!string_only
678                || insn_field_is_constant(fields->bits[new_opcode.last],
679                                          rule) != field_constant_string)
680            && (string_only
681                || !insn_field_is_constant(fields->bits[new_opcode.last],
682                                           rule)))
683       new_opcode.last = fields->bits[new_opcode.last]->first - 1;
684     ASSERT(new_opcode.last < rule->first
685            || (string_only
686                && insn_field_is_constant(fields->bits[new_opcode.last],
687                                          rule) == field_constant_string)
688            || (!string_only
689                && insn_field_is_constant(fields->bits[new_opcode.last],
690                                          rule)));
691
692     /* now see if our current opcode needs expanding */
693     if (new_opcode.first <= rule->last
694         && curr_opcode->first > new_opcode.first)
695       curr_opcode->first = new_opcode.first;
696     if (new_opcode.last >= rule->first
697         && curr_opcode->last < new_opcode.last)
698       curr_opcode->last = new_opcode.last;
699     
700   }
701
702   /* was any thing interesting found? */
703   if (curr_opcode->first > rule->last) {
704     ASSERT(curr_opcode->last < rule->first);
705     return NULL;
706   }
707   ASSERT(curr_opcode->last >= rule->first);
708   ASSERT(curr_opcode->first <= rule->last);
709
710   /* if something was found, check it includes the forced field range */
711   if (!string_only
712       && curr_opcode->first > rule->force_first) {
713     curr_opcode->first = rule->force_first;
714   }
715   if (!string_only
716       && curr_opcode->last < rule->force_last) {
717     curr_opcode->last = rule->force_last;
718   }
719   /* handle special case elminating any need to do shift after mask */
720   if (string_only
721       && rule->force_last == insn_size-1) {
722     curr_opcode->last = insn_size-1;
723   }
724
725   /* handle any special cases */
726   switch (rule->special_rule) {
727   case 0: /* let the above apply */
728     break;
729   case 1: /* expand a limited nr of bits, ignoring the rest */
730     curr_opcode->first = rule->force_first;
731     curr_opcode->last = rule->force_last;
732     break;
733   case 2: /* boolean field */
734     curr_opcode->is_boolean = 1;
735     break;
736   }
737
738   return curr_opcode;
739 }
740
741
742 static void
743 insn_table_insert_expanded(insn_table *table,
744                            insn *old_insn,
745                            int new_opcode_nr,
746                            insn_bits *new_bits)
747 {
748   insn_table **ptr_to_cur_entry = &table->entries;
749   insn_table *cur_entry = *ptr_to_cur_entry;
750
751   /* find the new table for this entry */
752   while (cur_entry != NULL
753          && cur_entry->opcode_nr < new_opcode_nr) {
754     ptr_to_cur_entry = &cur_entry->sibling;
755     cur_entry = *ptr_to_cur_entry;
756   }
757
758   if (cur_entry == NULL || cur_entry->opcode_nr != new_opcode_nr) {
759     insn_table *new_entry = ZALLOC(insn_table);
760     new_entry->opcode_nr = new_opcode_nr;
761     new_entry->expanded_bits = new_bits;
762     new_entry->opcode_rule = table->opcode_rule->next;
763     new_entry->sibling = cur_entry;
764     new_entry->parent = table;
765     *ptr_to_cur_entry = new_entry;
766     cur_entry = new_entry;
767     table->nr_entries++;
768   }
769   /* ASSERT new_bits == cur_entry bits */
770   ASSERT(cur_entry != NULL && cur_entry->opcode_nr == new_opcode_nr);
771   insn_table_insert_insn(cur_entry,
772                          old_insn->file_entry,
773                          old_insn->fields);
774 }
775
776 static void
777 insn_table_expand_opcode(insn_table *table,
778                          insn *instruction,
779                          int field_nr,
780                          int opcode_nr,
781                          insn_bits *bits)
782 {
783
784   if (field_nr > table->opcode->last) {
785     insn_table_insert_expanded(table, instruction, opcode_nr, bits);
786   }
787   else {
788     insn_field *field = instruction->fields->bits[field_nr];
789     if (field->is_int || field->is_slash) {
790       ASSERT(field->first >= table->opcode->first
791              && field->last <= table->opcode->last);
792       insn_table_expand_opcode(table, instruction, field->last+1,
793                                ((opcode_nr << field->width) + field->val_int),
794                                bits);
795     }
796     else {
797       int val;
798       int last_pos = ((field->last < table->opcode->last)
799                         ? field->last : table->opcode->last);
800       int first_pos = ((field->first > table->opcode->first)
801                          ? field->first : table->opcode->first);
802       int width = last_pos - first_pos + 1;
803       int last_val = (table->opcode->is_boolean
804                       ? 2 : (1 << width));
805       for (val = 0; val < last_val; val++) {
806         insn_bits *new_bits = ZALLOC(insn_bits);
807         new_bits->field = field;
808         new_bits->value = val;
809         new_bits->last = bits;
810         new_bits->opcode = table->opcode;
811         insn_table_expand_opcode(table, instruction, last_pos+1,
812                                  ((opcode_nr << width) | val),
813                                  new_bits);
814       }
815     }
816   }
817 }
818
819 static void
820 insn_table_insert_expanding(insn_table *table,
821                             insn *entry)
822 {
823   insn_table_expand_opcode(table,
824                            entry,
825                            table->opcode->first,
826                            0,
827                            table->expanded_bits);
828 }
829
830
831 static void
832 insn_table_expand_insns(insn_table *table)
833 {
834
835   ASSERT(table->nr_insn >= 1);
836
837   /* determine a valid opcode */
838   while (table->opcode_rule) {
839     /* specials only for single instructions */
840     if ((table->nr_insn > 1
841          && table->opcode_rule->special_mask == 0
842          && table->opcode_rule->special_rule == 0)
843         || (table->nr_insn == 1
844             && table->opcode_rule->special_mask != 0
845             && ((table->insns->fields->value
846                  & table->opcode_rule->special_mask)
847                 == table->opcode_rule->special_value))
848         || (idecode_expand_semantics
849             && table->opcode_rule->special_mask == 0
850             && table->opcode_rule->special_rule == 0))
851       table->opcode =
852         insn_table_find_opcode_field(table->insns,
853                                      table->opcode_rule,
854                                      table->nr_insn == 1/*string*/
855                                      );
856     if (table->opcode != NULL)
857       break;
858     table->opcode_rule = table->opcode_rule->next;
859   }
860
861   /* did we find anything */
862   if (table->opcode == NULL) {
863     return;
864   }
865   ASSERT(table->opcode != NULL);
866
867   /* back link what we found to its parent */
868   if (table->parent != NULL) {
869     ASSERT(table->parent->opcode != NULL);
870     table->opcode->parent = table->parent->opcode;
871   }
872
873   /* expand the raw instructions according to the opcode */
874   {
875     insn *entry;
876     for (entry = table->insns; entry != NULL; entry = entry->next) {
877       insn_table_insert_expanding(table, entry);
878     }
879   }
880
881   /* and do the same for the sub entries */
882   {
883     insn_table *entry;
884     for (entry = table->entries; entry != NULL; entry =  entry->sibling) {
885       insn_table_expand_insns(entry);
886     }
887   }
888 }
889
890
891
892 static insn_table *
893 insn_table_load_insns(char *file_name)
894 {
895   table *file = table_open(file_name, nr_insn_table_fields);
896   insn_table *table = ZALLOC(insn_table);
897   table_entry *file_entry;
898   table->opcode_rule = opcode_table;
899
900   while ((file_entry = table_entry_read(file)) != NULL) {
901     if (it_is("function", file_entry->fields[insn_flags])
902         || it_is("internal", file_entry->fields[insn_flags])) {
903       insn_table_insert_function(table, file_entry);
904     }
905     else {
906       insn_fields *fields;
907       /* skip instructions that aren't relevant to the mode */
908       filter *filt = filters;
909       while (filt != NULL) {
910         if (it_is(filt->flag, file_entry->fields[insn_flags]))
911           break;
912         filt = filt->next;
913       }
914       if (filt == NULL) {
915         /* create/insert the new instruction */
916         fields = parse_insn_format(file_entry,
917                                    file_entry->fields[insn_format]);
918         insn_table_insert_insn(table, file_entry, fields);
919       }
920     }
921   }
922   return table;
923 }
924
925
926 static void
927 dump_insn(insn *entry, int indent, int levels)
928 {
929   printf("(insn*)%p\n", entry);
930
931   if (levels && entry != NULL) {
932
933     dumpf(indent, "(file_entry ");
934     dump_table_entry(entry->file_entry, indent+1);
935     dumpf(indent, " )\n");
936
937     dumpf(indent, "(fields ");
938     dump_insn_fields(entry->fields, indent+1);
939     dumpf(indent, " )\n");
940
941     dumpf(indent, "(next ");
942     dump_insn(entry->next, indent+1, levels-1);
943     dumpf(indent, " )\n");
944
945   }
946
947 }
948
949
950 static void
951 dump_insn_table(insn_table *table,
952                 int indent, int levels)
953 {
954
955   printf("(insn_table*)%p\n", table);
956
957   if (levels && table != NULL) {
958
959     dumpf(indent, "(opcode_nr %d)\n", table->opcode_nr);
960
961     dumpf(indent, "(expanded_bits ");
962     dump_insn_bits(table->expanded_bits, indent+1, -1);
963     dumpf(indent, " )\n");
964
965     dumpf(indent, "(int nr_insn %d)\n", table->nr_insn);
966
967     dumpf(indent, "(insns ");
968     dump_insn(table->insns, indent+1, table->nr_insn);
969     dumpf(indent, " )\n");
970
971     dumpf(indent, "(opcode_rule ");
972     dump_opcode_rule(table->opcode_rule, indent+1);
973     dumpf(indent, " )\n");
974
975     dumpf(indent, "(opcode ");
976     dump_opcode_field(table->opcode, indent+1, 1);
977     dumpf(indent, " )\n");
978
979     dumpf(indent, "(nr_entries %d)\n", table->entries);
980     dumpf(indent, "(entries ");
981     dump_insn_table(table->entries, indent+1, table->nr_entries);
982     dumpf(indent, " )\n");
983
984     dumpf(indent, "(sibling ", table->sibling);
985     dump_insn_table(table->sibling, indent+1, levels-1);
986     dumpf(indent, " )\n");
987
988     dumpf(indent, "(parent ", table->parent);
989     dump_insn_table(table->parent, indent+1, 0);
990     dumpf(indent, " )\n");
991
992   }
993 }
994
995
996 /****************************************************************/
997
998
999 static void
1000 lf_print_insn_bits(lf *file, insn_bits *bits)
1001 {
1002   if (bits == NULL)
1003     return;
1004   lf_print_insn_bits(file, bits->last);
1005   lf_putchr(file, '_');
1006   lf_putstr(file, bits->field->val_string);
1007   if (!bits->opcode->is_boolean || bits->value == 0) {
1008     if (bits->opcode->last < bits->field->last)
1009       lf_putint(file, bits->value << (bits->field->last - bits->opcode->last));
1010     else
1011       lf_putint(file, bits->value);
1012   }
1013 }
1014
1015 static void
1016 lf_print_opcodes(lf *file,
1017                  insn_table *table)
1018 {
1019   if (table != NULL) {
1020     while (1) {
1021       lf_printf(file, "_%d_%d",
1022                 table->opcode->first,
1023                 table->opcode->last);
1024       if (table->parent == NULL) break;
1025       lf_printf(file, "__%d", table->opcode_nr);
1026       table = table->parent;
1027     }
1028   }
1029 }
1030
1031 static void
1032 lf_print_table_name(lf *file,
1033                     insn_table *table)
1034 {
1035   lf_printf(file, "idecode_table");
1036   lf_print_opcodes(file, table);
1037 }
1038
1039
1040
1041 typedef enum {
1042   function_name_prefix_semantics,
1043   function_name_prefix_idecode,
1044   function_name_prefix_itable,
1045   function_name_prefix_none
1046 } lf_function_name_prefixes;
1047
1048 static void
1049 lf_print_function_name(lf *file,
1050                        char *basename,
1051                        insn_bits *expanded_bits,
1052                        lf_function_name_prefixes prefix)
1053 {
1054
1055   /* the prefix */
1056   switch (prefix) {
1057   case function_name_prefix_semantics:
1058     lf_putstr(file, "semantic_");
1059     break;
1060   case function_name_prefix_idecode:
1061     lf_printf(file, "idecode_");
1062     break;
1063   case function_name_prefix_itable:
1064     lf_putstr(file, "itable_");
1065     break;
1066   default:
1067     break;
1068   }
1069
1070   /* the function name */
1071   {
1072     char *pos;
1073     for (pos = basename;
1074          *pos != '\0';
1075          pos++) {
1076       switch (*pos) {
1077       case '/':
1078       case '-':
1079         break;
1080       case ' ':
1081         lf_putchr(file, '_');
1082         break;
1083       default:
1084         lf_putchr(file, *pos);
1085         break;
1086       }
1087     }
1088   }
1089
1090   /* the suffix */
1091   if (idecode_expand_semantics)
1092     lf_print_insn_bits(file, expanded_bits);
1093 }
1094
1095
1096 static void
1097 lf_print_idecode_table(lf *file,
1098                        insn_table *entry)
1099 {
1100   int can_assume_leaf;
1101   opcode_rules *opcode_rule;
1102
1103   /* have a look at the rule table, if all table rules follow all
1104      switch rules, I can assume that all end points are leaves */
1105   opcode_rule = opcode_table;
1106   while (opcode_rule != NULL
1107          && opcode_rule->use_switch)
1108     opcode_rule = opcode_rule->next;
1109   while (opcode_rule != NULL
1110          && opcode_rule->use_switch
1111          && opcode_rule->special_rule)
1112     opcode_rule = opcode_rule->next;
1113   can_assume_leaf = opcode_rule == NULL;
1114
1115   lf_printf(file, "{\n");
1116   lf_indent(file, +2);
1117   {
1118     lf_printf(file, "idecode_table_entry *table = ");
1119     lf_print_table_name(file, entry);
1120     lf_printf(file, ";\n");
1121     lf_printf(file, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1122               entry->opcode->first, entry->opcode->last);
1123     lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
1124     lf_printf(file, "while (1) {\n");
1125     lf_indent(file, +2);
1126     {
1127       lf_printf(file, "while (table_entry->mask != 0) {\n");
1128       lf_indent(file, +2);
1129       {
1130         lf_printf(file, "table = ((idecode_table_entry*)\n");
1131         lf_printf(file, "         table_entry->function_or_table);\n");
1132         lf_printf(file, "opcode = ((instruction & table_entry->mask)\n");
1133         lf_printf(file, "          >> table_entry->shift);\n");
1134         lf_printf(file, "table_entry = table + opcode;\n");
1135       }
1136       lf_indent(file, -2);
1137       lf_printf(file, "}\n");
1138       if (!idecode_cache && can_assume_leaf) {
1139         lf_printf(file, "return (((idecode_semantic*)\n");
1140         lf_printf(file, "         table_entry->function_or_table)\n");
1141         lf_printf(file, "        (%s));\n", semantic_actual);
1142       }
1143       else if (!idecode_cache && !can_assume_leaf) {
1144         lf_printf(file, "if (table_entry->shift == 0)");
1145         lf_printf(file, "  return (((idecode_semantic*)\n");
1146         lf_printf(file, "           table_entry->function_or_table)\n");
1147         lf_printf(file, "          (%s));\n", semantic_actual);
1148       }
1149       else {
1150         lf_printf(file, "if (table_entry->shift == 0)\n");
1151         lf_printf(file, "  return (((idecode_crack*)\n");
1152         lf_printf(file, "           table_entry->function_or_table)\n");
1153         lf_printf(file, "          (%s));\n", cache_idecode_actual);
1154       }
1155       if (!can_assume_leaf) {
1156         lf_printf(file, "opcode = (instruction & table_entry->shift) != 0;\n");
1157         lf_printf(file, "table = ((idecode_table_entry*)\n");
1158         lf_printf(file, "         table_entry->function_or_table);\n");
1159         lf_printf(file, "table_entry = table + opcode;\n");
1160       }
1161     }
1162     lf_indent(file, -2);
1163     lf_printf(file, "}\n");
1164   }
1165   lf_indent(file, -2);
1166   lf_printf(file, "}\n");
1167 }
1168
1169
1170 static void
1171 lf_print_my_prefix(lf *file,
1172                    table_entry *file_entry,
1173                    int idecode)
1174 {
1175   lf_printf(file, "const char *const my_prefix = \n");
1176   lf_printf(file, "  \"%s:%s:%s:%d\";\n",
1177             filter_filename (file_entry->file_name),
1178             (idecode ? "idecode" : "semantics"),
1179             file_entry->fields[insn_name],
1180             file_entry->line_nr);
1181 }
1182
1183
1184 static void
1185 lf_print_ptrace(lf *file,
1186                 int idecode)
1187 {
1188   lf_printf(file, "\n");
1189   lf_printf(file, "ITRACE(trace_%s, (\"\\n\"));\n",
1190             (idecode ? "idecode" : "semantics"));
1191 }
1192
1193
1194 /****************************************************************/
1195
1196 typedef void leaf_handler
1197 (insn_table *entry,
1198  void *data,
1199  int depth);
1200 typedef void padding_handler
1201 (insn_table *table,
1202  void *data,
1203  int depth,
1204  int opcode_nr);
1205
1206
1207 static void
1208 insn_table_traverse_tree(insn_table *table,
1209                          void *data,
1210                          int depth,
1211                          leaf_handler *start,
1212                          leaf_handler *leaf,
1213                          leaf_handler *end,
1214                          padding_handler *padding)
1215 {
1216   insn_table *entry;
1217   int entry_nr;
1218   
1219   ASSERT(table != NULL
1220          && table->opcode != NULL
1221          && table->nr_entries > 0
1222          && table->entries != 0);
1223
1224   if (start != NULL && depth >= 0)
1225     start(table, data, depth);
1226
1227   for (entry_nr = 0, entry = table->entries;
1228        entry_nr < (table->opcode->is_boolean
1229                    ? 2
1230                    : (1 << (table->opcode->last - table->opcode->first + 1)));
1231        entry_nr ++) {
1232     if (entry == NULL
1233         || (!table->opcode->is_boolean
1234             && entry_nr < entry->opcode_nr)) {
1235       if (padding != NULL && depth >= 0)
1236         padding(table, data, depth, entry_nr);
1237     }
1238     else {
1239       ASSERT(entry != NULL && (entry->opcode_nr == entry_nr
1240                                || table->opcode->is_boolean));
1241       if (entry->opcode != NULL && depth != 0) {
1242         insn_table_traverse_tree(entry, data, depth+1,
1243                                  start, leaf, end, padding);
1244       }
1245       else if (depth >= 0) {
1246         if (leaf != NULL)
1247           leaf(entry, data, depth);
1248       }
1249       entry = entry->sibling;
1250     }
1251   }
1252   if (end != NULL && depth >= 0)
1253     end(table, data, depth);
1254 }
1255
1256
1257 typedef void function_handler
1258 (insn_table *table,
1259  void *data,
1260  table_entry *function);
1261
1262 static void
1263 insn_table_traverse_function(insn_table *table,
1264                              void *data,
1265                              function_handler *leaf)
1266 {
1267   insn *function;
1268   for (function = table->functions;
1269        function != NULL;
1270        function = function->next) {
1271     leaf(table, data, function->file_entry);
1272   }
1273 }
1274
1275
1276 typedef void insn_handler
1277 (insn_table *table,
1278  void *data,
1279  insn *instruction);
1280
1281 static void
1282 insn_table_traverse_insn(insn_table *table,
1283                          void *data,
1284                          insn_handler *leaf)
1285 {
1286   insn *instruction;
1287   for (instruction = table->insns;
1288        instruction != NULL;
1289        instruction = instruction->next) {
1290     leaf(table, data, instruction);
1291   }
1292 }
1293
1294
1295 static void
1296 update_depth(insn_table *entry,
1297              void *data,
1298              int depth)
1299 {
1300   int *max_depth = (int*)data;
1301   if (*max_depth < depth)
1302     *max_depth = depth;
1303 }
1304
1305
1306 static int
1307 insn_table_depth(insn_table *table)
1308 {
1309   int depth = 0;
1310   insn_table_traverse_tree(table,
1311                            &depth,
1312                            1,
1313                            NULL, /*start*/
1314                            update_depth,
1315                            NULL, /*end*/
1316                            NULL); /*padding*/
1317   return depth;
1318 }
1319
1320
1321 /****************************************************************/
1322
1323 static void
1324 dump_traverse_start(insn_table *table,
1325                     void *data,
1326                     int depth)
1327 {
1328   dumpf(depth*2, "(%d\n", table->opcode_nr);
1329 }
1330
1331 static void
1332 dump_traverse_leaf(insn_table *entry,
1333                    void *data,
1334                    int depth)
1335 {
1336   ASSERT(entry->nr_entries == 0
1337          && entry->nr_insn == 1
1338          && entry->opcode == NULL);
1339   dumpf(depth*2, ".%d %s\n", entry->opcode_nr,
1340         entry->insns->file_entry->fields[insn_format]);
1341 }
1342
1343 static void
1344 dump_traverse_end(insn_table *table,
1345                   void *data,
1346                   int depth)
1347 {
1348   dumpf(depth*2, ")\n");
1349 }
1350
1351 static void
1352 dump_traverse_padding(insn_table *table,
1353                       void *data,
1354                       int depth,
1355                       int opcode_nr)
1356 {
1357   dumpf(depth*2, ".<%d>\n", opcode_nr);
1358 }
1359
1360
1361 static void
1362 dump_traverse(insn_table *table)
1363 {
1364   insn_table_traverse_tree(table, NULL, 1,
1365                            dump_traverse_start,
1366                            dump_traverse_leaf,
1367                            dump_traverse_end,
1368                            dump_traverse_padding);
1369 }
1370
1371
1372 /****************************************************************/
1373
1374
1375 static void
1376 semantics_h_print_function(lf *file,
1377                            char *basename,
1378                            insn_bits *expanded_bits)
1379 {
1380   lf_printf(file, "\n");
1381   lf_printf(file, "INLINE_SEMANTICS unsigned_word ");
1382   lf_print_function_name(file,
1383                          basename,
1384                          expanded_bits,
1385                          function_name_prefix_semantics);
1386   lf_printf(file, "\n(%s);\n", 
1387             (idecode_cache ? cache_semantic_formal : semantic_formal));
1388 }
1389
1390
1391 static void
1392 semantics_h_leaf(insn_table *entry,
1393                  void *data,
1394                  int depth)
1395 {
1396   lf *file = (lf*)data;
1397   ASSERT(entry->nr_insn == 1);
1398   semantics_h_print_function(file,
1399                              entry->insns->file_entry->fields[insn_name],
1400                              entry->expanded_bits);
1401 }
1402
1403 static void
1404 semantics_h_insn(insn_table *entry,
1405                  void *data,
1406                  insn *instruction)
1407 {
1408   lf *file = (lf*)data;
1409   semantics_h_print_function(file,
1410                              instruction->file_entry->fields[insn_name],
1411                              NULL);
1412 }
1413
1414 static void
1415 semantics_h_function(insn_table *entry,
1416                      void *data,
1417                      table_entry *function)
1418 {
1419   lf *file = (lf*)data;
1420   if (function->fields[function_type] == NULL
1421       || function->fields[function_type][0] == '\0') {
1422     semantics_h_print_function(file,
1423                                function->fields[function_name],
1424                                NULL);
1425   }
1426   else {
1427     lf_printf(file, "\n");
1428     lf_printf(file, "INLINE_SEMANTICS %s %s\n(%s);\n",
1429               function->fields[function_type],
1430               function->fields[function_name],
1431               function->fields[function_param]);
1432   }
1433 }
1434
1435
1436 static void 
1437 gen_semantics_h(insn_table *table, lf *file)
1438 {
1439
1440   lf_print_copyleft(file);
1441   lf_printf(file, "\n");
1442   lf_printf(file, "#ifndef _SEMANTICS_H_\n");
1443   lf_printf(file, "#define _SEMANTICS_H_\n");
1444   lf_printf(file, "\n");
1445   lf_printf(file, "#ifndef INLINE_SEMANTICS\n");
1446   lf_printf(file, "#define INLINE_SEMANTICS\n");
1447   lf_printf(file, "#endif\n");
1448   lf_printf(file, "\n");
1449   lf_printf(file, "\n");
1450
1451   /* output a declaration for all functions */
1452   insn_table_traverse_function(table,
1453                                file,
1454                                semantics_h_function);
1455
1456   /* output a declaration for all instructions */
1457   if (idecode_expand_semantics)
1458     insn_table_traverse_tree(table,
1459                              file,
1460                              1,
1461                              NULL, /* start */
1462                              semantics_h_leaf, /* leaf */
1463                              NULL, /* end */
1464                              NULL); /* padding */
1465   else
1466     insn_table_traverse_insn(table,
1467                              file,
1468                              semantics_h_insn);
1469
1470   lf_printf(file, "\n");
1471   lf_printf(file, "#endif /* _SEMANTICS_H_ */\n");
1472
1473 }
1474
1475 /****************************************************************/
1476
1477 typedef struct _icache_tree icache_tree;
1478 struct _icache_tree {
1479   char *name;
1480   icache_tree *next;
1481   icache_tree *children;
1482 };
1483
1484 static icache_tree *
1485 icache_tree_insert(icache_tree *tree,
1486                    char *name)
1487 {
1488   icache_tree *new_tree;
1489   /* find it */
1490   icache_tree **ptr_to_cur_tree = &tree->children;
1491   icache_tree *cur_tree = *ptr_to_cur_tree;
1492   while (cur_tree != NULL
1493          && strcmp(cur_tree->name, name) < 0) {
1494     ptr_to_cur_tree = &cur_tree->next;
1495     cur_tree = *ptr_to_cur_tree;
1496   }
1497   ASSERT(cur_tree == NULL
1498          || strcmp(cur_tree->name, name) >= 0);
1499   /* already in the tree */
1500   if (cur_tree != NULL
1501       && strcmp(cur_tree->name, name) == 0)
1502     return cur_tree;
1503   /* missing, insert it */
1504   ASSERT(cur_tree == NULL
1505          || strcmp(cur_tree->name, name) > 0);
1506   new_tree = ZALLOC(icache_tree);
1507   new_tree->name = name;
1508   new_tree->next = cur_tree;
1509   *ptr_to_cur_tree = new_tree;
1510   return new_tree;
1511 }
1512
1513
1514 static icache_tree *
1515 insn_table_cache_fields(insn_table *table)
1516 {
1517   icache_tree *tree = ZALLOC(icache_tree);
1518   insn *instruction;
1519   for (instruction = table->insns;
1520        instruction != NULL;
1521        instruction = instruction->next) {
1522     insn_field *field;
1523     icache_tree *form =
1524       icache_tree_insert(tree,
1525                          instruction->file_entry->fields[insn_form]);
1526     for (field = instruction->fields->first;
1527          field != NULL;
1528          field = field->next) {
1529       if (field->is_string)
1530         icache_tree_insert(form, field->val_string);
1531     }
1532   }
1533   return tree;
1534 }
1535
1536
1537
1538 static void
1539 gen_icache_h(icache_tree *tree,
1540              lf *file)
1541 {
1542   lf_print_copyleft(file);
1543   lf_printf(file, "\n");
1544   lf_printf(file, "#ifndef _ICACHE_H_\n");
1545   lf_printf(file, "#define _ICACHE_H_\n");
1546   lf_printf(file, "\n");
1547   lf_printf(file, "#ifndef INLINE_ICACHE\n");
1548   lf_printf(file, "#define INLINE_ICACHE\n");
1549   lf_printf(file, "#endif\n");
1550   lf_printf(file, "\n");
1551
1552   lf_printf(file, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1553             idecode_cache);
1554   lf_printf(file, "\n");
1555
1556   /* create an instruction cache if being used */
1557   if (idecode_cache) {
1558     icache_tree *form;
1559     lf_printf(file, "typedef struct _idecode_cache {\n");
1560     lf_printf(file, "  unsigned_word address;\n");
1561     lf_printf(file, "  void *semantic;\n");
1562     lf_printf(file, "  union {\n");
1563     for (form = tree->children;
1564          form != NULL;
1565          form = form->next) {
1566       icache_tree *field;
1567       lf_printf(file, "    struct {\n");
1568       for (field = form->children;
1569            field != NULL;
1570            field = field->next) {
1571         cache_rules *cache_rule;
1572         int found_rule = 0;
1573         for (cache_rule = cache_table;
1574              cache_rule != NULL;
1575              cache_rule = cache_rule->next) {
1576           if (strcmp(field->name, cache_rule->old_name) == 0) {
1577             found_rule = 1;
1578             if (cache_rule->new_name != NULL)
1579               lf_printf(file, "      %s %s; /* %s */\n",
1580                         (cache_rule->type == NULL
1581                          ? "unsigned" 
1582                          : cache_rule->type),
1583                         cache_rule->new_name,
1584                         cache_rule->old_name);
1585           }
1586         }
1587         if (!found_rule)
1588           lf_printf(file, "      unsigned %s;\n", field->name);
1589       }
1590       lf_printf(file, "    } %s;\n", form->name);
1591     }
1592     lf_printf(file, "  } crack;\n");
1593     lf_printf(file, "} idecode_cache;\n");
1594   }
1595   else {
1596     /* alernativly, since no cache, #define the fields to be
1597        extractions from the instruction variable */
1598     cache_rules *cache_rule;
1599     lf_printf(file, "\n");
1600     for (cache_rule = cache_table;
1601          cache_rule != NULL;
1602          cache_rule = cache_rule->next) {
1603       if (cache_rule->expression != NULL
1604           && strlen(cache_rule->expression) > 0)
1605         lf_printf(file, "#define %s %s\n",
1606                   cache_rule->new_name, cache_rule->expression);
1607     }
1608   }
1609
1610   lf_printf(file, "\n");
1611   lf_printf(file, "#endif /* _ICACHE_H_ */\n");
1612 }
1613
1614
1615
1616
1617 /****************************************************************/
1618
1619
1620 static void
1621 lf_print_c_extraction(lf *file,
1622                       insn *instruction,
1623                       char *field_name,
1624                       char *field_type,
1625                       char *field_expression,
1626                       insn_field *cur_field,
1627                       insn_bits *bits,
1628                       int get_value_from_cache,
1629                       int put_value_in_cache)
1630 {
1631   ASSERT(field_name != NULL);
1632   if (bits != NULL
1633       && (!bits->opcode->is_boolean || bits->value == 0)
1634       && strcmp(field_name, cur_field->val_string) == 0) {
1635     ASSERT(bits->field == cur_field);
1636     ASSERT(field_type == NULL);
1637     table_entry_lf_c_line_nr(file, instruction->file_entry);
1638     lf_printf(file, "const unsigned %s = ",
1639               field_name);
1640     if (bits->opcode->last < bits->field->last)
1641       lf_printf(file, "%d;\n",
1642                 bits->value << (bits->field->last - bits->opcode->last));
1643     else
1644       lf_printf(file, "%d;\n", bits->value);
1645   }
1646   else {
1647     /* put the field in the local variable */
1648     table_entry_lf_c_line_nr(file, instruction->file_entry);
1649     lf_printf(file, "%s const %s = ",
1650               field_type == NULL ? "unsigned" : field_type,
1651               field_name);
1652     /* getting it from the cache */
1653     if (get_value_from_cache || put_value_in_cache) {
1654       lf_printf(file, "cache_entry->crack.%s.%s",
1655                 instruction->file_entry->fields[insn_form],
1656                 field_name);
1657       if (put_value_in_cache) /* also put it in the cache? */
1658         lf_printf(file, " = ");
1659     }
1660     if (!get_value_from_cache) {
1661       if (strcmp(field_name, cur_field->val_string) == 0)
1662         lf_printf(file, "EXTRACTED32(instruction, %d, %d)",
1663                   cur_field->first, cur_field->last);
1664       else if (field_expression != NULL)
1665         lf_printf(file, "%s", field_expression);
1666       else
1667         lf_printf(file, "eval_%s", field_name);
1668     }
1669     lf_printf(file, ";\n");
1670   }
1671 }
1672
1673
1674 static void
1675 lf_print_c_extractions(lf *file,
1676                        insn *instruction,
1677                        insn_bits *expanded_bits,
1678                        int get_value_from_cache,
1679                        int put_value_in_cache)
1680 {
1681   insn_field *cur_field;
1682
1683   /* extract instruction fields */
1684   lf_printf(file, "/* extraction: %s */\n",
1685             instruction->file_entry->fields[insn_format]);
1686
1687   for (cur_field = instruction->fields->first;
1688        cur_field->first < insn_size;
1689        cur_field = cur_field->next) {
1690     if (cur_field->is_string) {
1691       insn_bits *bits;
1692       int found_rule = 0;
1693       /* find any corresponding value */
1694       for (bits = expanded_bits;
1695            bits != NULL;
1696            bits = bits->last) {
1697         if (bits->field == cur_field)
1698           break;
1699       }
1700       /* try the cache rule table for what to do */
1701       if (get_value_from_cache || put_value_in_cache) {      
1702         cache_rules *cache_rule;
1703         for (cache_rule = cache_table;
1704              cache_rule != NULL;
1705              cache_rule = cache_rule->next) {
1706           if (strcmp(cur_field->val_string, cache_rule->old_name) == 0) {
1707             found_rule = 1;
1708             if (cache_rule->valid > 1 && put_value_in_cache)
1709               lf_print_c_extraction(file,
1710                                     instruction,
1711                                     cache_rule->new_name,
1712                                     cache_rule->type,
1713                                     cache_rule->expression,
1714                                     cur_field,
1715                                     bits,
1716                                     0,
1717                                     0);
1718             else if (cache_rule->valid == 1)
1719               lf_print_c_extraction(file,
1720                                     instruction,
1721                                     cache_rule->new_name,
1722                                     cache_rule->type,
1723                                     cache_rule->expression,
1724                                     cur_field,
1725                                     bits,
1726                                     get_value_from_cache,
1727                                     put_value_in_cache);
1728           }
1729         }
1730       }
1731       if (found_rule == 0)
1732         lf_print_c_extraction(file,
1733                               instruction,
1734                               cur_field->val_string,
1735                               0,
1736                               0,
1737                               cur_field,
1738                               bits,
1739                               get_value_from_cache,
1740                               put_value_in_cache);
1741       /* if any (XXX == 0), output a corresponding test */
1742       if (instruction->file_entry->annex != NULL) {
1743         char *field_name = cur_field->val_string;
1744         char *is_0_ptr = instruction->file_entry->annex;
1745         int field_len = strlen(field_name);
1746         if (strlen(is_0_ptr) >= (strlen("_is_0") + field_len)) {
1747           is_0_ptr += field_len;
1748           while ((is_0_ptr = strstr(is_0_ptr, "_is_0")) != NULL) {
1749             if (strncmp(is_0_ptr - field_len, field_name, field_len) == 0
1750                 && !isalpha(is_0_ptr[ - field_len - 1])) {
1751               table_entry_lf_c_line_nr(file, instruction->file_entry);
1752               lf_printf(file, "const unsigned %s_is_0 = (", field_name);
1753               if (bits != NULL)
1754                 lf_printf(file, "%d", bits->value);
1755               else
1756                 lf_printf(file, "%s", field_name);
1757               lf_printf(file, " == 0);\n");
1758               break;
1759             }
1760             is_0_ptr += strlen("_is_0");
1761           }
1762         }
1763       }
1764       /* any thing else ... */
1765     }
1766   }
1767   lf_print_lf_c_line_nr(file);
1768 }
1769
1770
1771 static void
1772 lf_print_idecode_illegal(lf *file)
1773 {
1774   if (idecode_cache)
1775     lf_printf(file, "return idecode_illegal(%s);\n", cache_idecode_actual);
1776   else
1777     lf_printf(file, "return semantic_illegal(%s);\n", semantic_actual);
1778 }
1779
1780
1781 static void
1782 lf_print_idecode_floating_point_unavailable(lf *file)
1783 {
1784   if (idecode_cache)
1785     lf_printf(file, "return idecode_floating_point_unavailable(%s);\n",
1786               cache_idecode_actual);
1787   else
1788     lf_printf(file, "return semantic_floating_point_unavailable(%s);\n",
1789               semantic_actual);
1790 }
1791
1792
1793 /* Output code to do any final checks on the decoded instruction.
1794    This includes things like verifying any on decoded fields have the
1795    correct value and checking that (for floating point) floating point
1796    hardware isn't disabled */
1797
1798 static void
1799 lf_print_c_validate(lf *file,
1800                     insn *instruction,
1801                     opcode_field *opcodes)
1802 {
1803   /* Validate: unchecked instruction fields
1804
1805      If any constant fields in the instruction were not checked by the
1806      idecode tables, output code to check that they have the correct
1807      value here */
1808   { 
1809     unsigned check_mask = 0;
1810     unsigned check_val = 0;
1811     insn_field *field;
1812     opcode_field *opcode;
1813
1814     /* form check_mask/check_val containing what needs to be checked
1815        in the instruction */
1816     for (field = instruction->fields->first;
1817          field->first < insn_size;
1818          field = field->next) {
1819
1820       check_mask <<= field->width;
1821       check_val <<= field->width;
1822
1823       /* is it a constant that could need validating? */
1824       if (!field->is_int && !field->is_slash)
1825         continue;
1826
1827       /* has it been checked by a table? */
1828       for (opcode = opcodes; opcode != NULL; opcode = opcode->parent) {
1829         if (field->first >= opcode->first
1830             && field->last <= opcode->last)
1831           break;
1832       }
1833       if (opcode != NULL)
1834         continue;
1835
1836       check_mask |= (1 << field->width)-1;
1837       check_val |= field->val_int;
1838     }
1839
1840     /* if any bits not checked by opcode tables, output code to check them */
1841     if (check_mask) {
1842       lf_printf(file, "\n");
1843       lf_printf(file, "/* validate: %s */\n",
1844                 instruction->file_entry->fields[insn_format]);
1845       lf_printf(file, "if ((instruction & 0x%x) != 0x%x)\n",
1846                 check_mask, check_val);
1847       lf_indent(file, +2);
1848       lf_print_idecode_illegal(file);
1849       lf_indent(file, -2);
1850     }
1851   }
1852
1853   /* Validate floating point hardware
1854
1855      If the simulator is being built with out floating point hardware
1856      (different to it being disabled in the MSR) then floating point
1857      instructions are invalid */
1858   {
1859     if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1860       lf_printf(file, "\n");
1861       lf_printf(file, "/* Validate: FP hardware exists */\n");
1862       lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1863       lf_indent(file, +2);
1864       lf_print_idecode_illegal(file);
1865       lf_indent(file, -2);
1866     }
1867   }
1868
1869   /* Validate: Floating Point available
1870
1871      If floating point is not available, we enter a floating point
1872      unavailable interrupt into the cache instead of the instruction
1873      proper.
1874
1875      The PowerPC spec requires a CSI after MSR[FP] is changed and when
1876      ever a CSI occures we flush the instruction cache. */
1877
1878   {
1879     if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1880       lf_printf(file, "\n");
1881       lf_printf(file, "/* Validate: FP available according to MSR[FP] */\n");
1882       lf_printf(file, "if (!IS_FP_AVAILABLE(processor))\n");
1883       lf_indent(file, +2);
1884       lf_print_idecode_floating_point_unavailable(file);
1885       lf_indent(file, -2);
1886     }
1887   }
1888 }
1889
1890
1891 static void
1892 lf_print_c_cracker(lf *file,
1893                    insn *instruction,
1894                    insn_bits *expanded_bits,
1895                    opcode_field *opcodes)
1896 {
1897
1898   /* function header */
1899   lf_printf(file, "{\n");
1900   lf_indent(file, +2);
1901
1902   lf_print_my_prefix(file,
1903                      instruction->file_entry,
1904                      1/*putting-value-in-cache*/);
1905
1906   lf_print_ptrace(file,
1907                   1/*putting-value-in-cache*/);
1908
1909   lf_print_c_validate(file, instruction, opcodes);
1910
1911   lf_printf(file, "\n");
1912   lf_printf(file, "{\n");
1913   lf_indent(file, +2);
1914   lf_print_c_extractions(file,
1915                          instruction,
1916                          expanded_bits,
1917                          0/*get_value_from_cache*/,
1918                          1/*put_value_in_cache*/);
1919   lf_indent(file, -2);
1920   lf_printf(file, "}\n");
1921
1922   /* return the function propper (main sorts this one out) */
1923   lf_printf(file, "\n");
1924   lf_printf(file, "/* semantic routine */\n");
1925   table_entry_lf_c_line_nr(file, instruction->file_entry);
1926   lf_printf(file, "return ");
1927   lf_print_function_name(file,
1928                          instruction->file_entry->fields[insn_name],
1929                          expanded_bits,
1930                          function_name_prefix_semantics);
1931   lf_printf(file, ";\n");
1932
1933   lf_print_lf_c_line_nr(file);
1934   lf_indent(file, -2);
1935   lf_printf(file, "}\n");
1936 }
1937
1938
1939 static void
1940 lf_print_c_semantic(lf *file,
1941                     insn *instruction,
1942                     insn_bits *expanded_bits,
1943                     opcode_field *opcodes)
1944 {
1945
1946   lf_printf(file, "{\n");
1947   lf_indent(file, +2);
1948
1949   lf_print_my_prefix(file,
1950                      instruction->file_entry,
1951                      0/*not putting value in cache*/);
1952   lf_putstr(file, semantic_local);
1953   lf_printf(file, "\n");
1954
1955   lf_printf(file, "\n");
1956   lf_print_c_extractions(file,
1957                          instruction,
1958                          expanded_bits,
1959                          idecode_cache/*get_value_from_cache*/,
1960                          0/*put_value_in_cache*/);
1961
1962   lf_print_ptrace(file,
1963                   0/*put_value_in_cache*/);
1964
1965   /* validate the instruction, if a cache this has already been done */
1966   if (!idecode_cache)
1967     lf_print_c_validate(file, instruction, opcodes);
1968
1969   /* generate the profileing call - this is delayed until after the
1970      instruction has been verified */
1971   lf_printf(file, "\n");
1972   lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
1973   lf_printf(file, "  mon_issue(");
1974   lf_print_function_name(file,
1975                          instruction->file_entry->fields[insn_name],
1976                          NULL,
1977                          function_name_prefix_itable);
1978   lf_printf(file, ", processor, cia);\n");
1979
1980   /* generate the code (or at least something */
1981   if (instruction->file_entry->annex != NULL) {
1982     /* true code */
1983     lf_printf(file, "\n");
1984     table_entry_lf_c_line_nr(file, instruction->file_entry);
1985     lf_printf(file, "{\n");
1986     lf_indent(file, +2);
1987     lf_print_c_code(file, instruction->file_entry->annex);
1988     lf_indent(file, -2);
1989     lf_printf(file, "}\n");
1990     lf_print_lf_c_line_nr(file);
1991   }
1992   else if (it_is("nop", instruction->file_entry->fields[insn_flags])) {
1993     lf_print_lf_c_line_nr(file);
1994   }
1995   else if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1996     /* unimplemented floating point instruction - call for assistance */
1997     lf_printf(file, "\n");
1998     lf_printf(file, "/* unimplemented floating point instruction - call for assistance */\n");
1999     table_entry_lf_c_line_nr(file, instruction->file_entry);
2000     lf_putstr(file, "floating_point_assist_interrupt(processor, cia);\n");
2001     lf_print_lf_c_line_nr(file);
2002   }
2003   else {
2004     /* abort so it is implemented now */
2005     table_entry_lf_c_line_nr(file, instruction->file_entry);
2006     lf_putstr(file, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2007     lf_print_lf_c_line_nr(file);
2008     lf_printf(file, "\n");
2009   }
2010
2011   /* the function footer */
2012   lf_printf(file, "return nia;\n");
2013   lf_indent(file, -2);
2014   lf_printf(file, "}\n");
2015 }
2016
2017 static void
2018 lf_print_c_semantic_function_header(lf *file,
2019                                     char *basename,
2020                                     insn_bits *expanded_bits)
2021 {
2022   lf_printf(file, "\n");
2023   lf_printf(file, "INLINE_SEMANTICS unsigned_word\n");
2024   lf_print_function_name(file,
2025                          basename,
2026                          expanded_bits,
2027                          function_name_prefix_semantics);
2028   lf_printf(file, "\n(%s)\n",
2029             (idecode_cache ? cache_semantic_formal : semantic_formal));
2030 }
2031
2032 static void
2033 lf_print_c_semantic_function(lf *file,
2034                              insn *instruction,
2035                              insn_bits *expanded_bits,
2036                              opcode_field *opcodes)
2037 {
2038
2039   /* build the semantic routine to execute the instruction */
2040   lf_print_c_semantic_function_header(file,
2041                                       instruction->file_entry->fields[insn_name],
2042                                       expanded_bits);
2043   lf_print_c_semantic(file,
2044                       instruction,
2045                       expanded_bits,
2046                       opcodes);
2047 }
2048
2049
2050 static void
2051 semantics_c_leaf(insn_table *entry,
2052                  void *data,
2053                  int depth)
2054 {
2055   lf *file = (lf*)data;
2056   ASSERT(entry->nr_insn == 1
2057          && entry->opcode == NULL
2058          && entry->parent != NULL
2059          && entry->parent->opcode != NULL);
2060   lf_print_c_semantic_function(file,
2061                                entry->insns,
2062                                entry->expanded_bits,
2063                                entry->parent->opcode);
2064 }
2065
2066 static void
2067 semantics_c_insn(insn_table *table,
2068                  void *data,
2069                  insn *instruction)
2070 {
2071   lf *file = (lf*)data;
2072   lf_print_c_semantic_function(file, instruction,
2073                                NULL, NULL);
2074 }
2075
2076 static void
2077 semantics_c_function(insn_table *table,
2078                      void *data,
2079                      table_entry *function)
2080 {
2081   lf *file = (lf*)data;
2082   if (function->fields[function_type] == NULL
2083       || function->fields[function_type][0] == '\0') {
2084     lf_print_c_semantic_function_header(file,
2085                                         function->fields[function_name],
2086                                         NULL);
2087   }
2088   else {
2089     lf_printf(file, "\n");
2090     lf_printf(file, "INLINE_SEMANTICS %s\n%s(%s)\n",
2091               function->fields[function_type],
2092               function->fields[function_name],
2093               function->fields[function_param]);
2094   }
2095   table_entry_lf_c_line_nr(file, function);
2096   lf_printf(file, "{\n");
2097   lf_indent(file, +2);
2098   lf_print_c_code(file, function->annex);
2099   lf_indent(file, -2);
2100   lf_printf(file, "}\n");
2101   lf_print_lf_c_line_nr(file);
2102 }
2103
2104
2105
2106 static void 
2107 gen_semantics_c(insn_table *table, lf *file)
2108 {
2109   lf_print_copyleft(file);
2110   lf_printf(file, "\n");
2111   lf_printf(file, "#ifndef _SEMANTICS_C_\n");
2112   lf_printf(file, "#define _SEMANTICS_C_\n");
2113   lf_printf(file, "\n");
2114   lf_printf(file, "#ifndef STATIC_INLINE_SEMANTICS\n");
2115   lf_printf(file, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2116   lf_printf(file, "#endif\n");
2117   lf_printf(file, "\n");
2118   lf_printf(file, "#include \"cpu.h\"\n");
2119   lf_printf(file, "#include \"idecode.h\"\n");
2120   lf_printf(file, "#include \"semantics.h\"\n");
2121   lf_printf(file, "\n");
2122
2123   /* output a definition (c-code) for all functions */
2124   insn_table_traverse_function(table,
2125                                file,
2126                                semantics_c_function);
2127
2128   /* output a definition (c-code) for all instructions */
2129   if (idecode_expand_semantics)
2130     insn_table_traverse_tree(table,
2131                              file,
2132                              1,
2133                              NULL, /* start */
2134                              semantics_c_leaf,
2135                              NULL, /* end */
2136                              NULL); /* padding */
2137   else
2138     insn_table_traverse_insn(table,
2139                              file,
2140                              semantics_c_insn);
2141
2142   lf_printf(file, "\n");
2143   lf_printf(file, "#endif /* _SEMANTICS_C_ */\n");
2144 }
2145
2146
2147 /****************************************************************/
2148
2149 static void
2150 gen_idecode_h(insn_table *table, lf *file)
2151 {
2152   lf_print_copyleft(file);
2153   lf_printf(file, "\n");
2154   lf_printf(file, "#ifndef _IDECODE_H_\n");
2155   lf_printf(file, "#define _IDECODE_H_\n");
2156   lf_printf(file, "\n");
2157   lf_printf(file, "#ifndef INLINE_IDECODE\n");
2158   lf_printf(file, "#define INLINE_IDECODE\n");
2159   lf_printf(file, "#endif\n");
2160   lf_printf(file, "\n");
2161   lf_printf(file, "#include \"idecode_expression.h\"\n");
2162   lf_printf(file, "#include \"idecode_fields.h\"\n");
2163   lf_printf(file, "#include \"idecode_branch.h\"\n");
2164   lf_printf(file, "\n");
2165   lf_printf(file, "#include \"icache.h\"\n");
2166   lf_printf(file, "\n");
2167   lf_printf(file, "typedef unsigned_word idecode_semantic\n(%s);\n",
2168             (idecode_cache ? cache_semantic_formal : semantic_formal));
2169   lf_printf(file, "\n");
2170   if (idecode_cache)
2171     lf_printf(file, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2172               cache_idecode_formal);
2173   else
2174     lf_printf(file, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2175               semantic_formal);
2176   lf_printf(file, "\n");
2177   lf_printf(file, "#endif /* _IDECODE_H_ */\n");
2178 }
2179
2180
2181 /****************************************************************/
2182
2183
2184 static void
2185 idecode_table_start(insn_table *table,
2186                     void *data,
2187                     int depth)
2188 {
2189   lf *file = (lf*)data;
2190   ASSERT(depth == 0);
2191   /* start of the table */
2192   if (!table->opcode_rule->use_switch) {
2193     lf_printf(file, "\n");
2194     lf_printf(file, "static idecode_table_entry ");
2195     lf_print_table_name(file, table);
2196     lf_printf(file, "[] = {\n");
2197   }
2198 }
2199
2200 static void
2201 idecode_table_leaf(insn_table *entry,
2202                    void *data,
2203                    int depth)
2204 {
2205   lf *file = (lf*)data;
2206   ASSERT(entry->parent != NULL);
2207   ASSERT(depth == 0);
2208
2209   /* add an entry to the table */
2210   if (!entry->parent->opcode_rule->use_switch) {
2211     if (entry->opcode == NULL) {
2212       /* table leaf entry */
2213       lf_printf(file, "  /*%d*/ { 0, 0, ", entry->opcode_nr);
2214       lf_print_function_name(file,
2215                              entry->insns->file_entry->fields[insn_name],
2216                              entry->expanded_bits,
2217                              (idecode_cache
2218                               ? function_name_prefix_idecode
2219                               : function_name_prefix_semantics));
2220       lf_printf(file, " },\n");
2221     }
2222     else if (entry->opcode_rule->use_switch) {
2223       /* table calling switch statement */
2224       lf_printf(file, "  /*%d*/ { -1, 0, ",
2225                 entry->opcode_nr);
2226       lf_print_table_name(file, entry);
2227       lf_printf(file, " },\n");
2228     }
2229     else {
2230       /* table `calling' another table */
2231       lf_printf(file, "  /*%d*/ { ", entry->opcode_nr);
2232       if (entry->opcode->is_boolean)
2233         lf_printf(file, "MASK32(%d,%d), 0, ",
2234                   entry->opcode->first, entry->opcode->last);
2235       else
2236         lf_printf(file, "%d, MASK32(%d,%d), ",
2237                   insn_size - entry->opcode->last - 1,
2238                   entry->opcode->first, entry->opcode->last);
2239       lf_print_table_name(file, entry);
2240       lf_printf(file, " },\n");
2241     }
2242   }
2243 }
2244
2245 static void
2246 idecode_table_end(insn_table *table,
2247                   void *data,
2248                   int depth)
2249 {
2250   lf *file = (lf*)data;
2251   ASSERT(depth == 0);
2252
2253   if (!table->opcode_rule->use_switch) {
2254     lf_printf(file, "};\n");
2255   }
2256 }
2257
2258 static void
2259 idecode_table_padding(insn_table *table,
2260                       void *data,
2261                       int depth,
2262                       int opcode_nr)
2263 {
2264   lf *file = (lf*)data;
2265   ASSERT(depth == 0);
2266
2267   if (!table->opcode_rule->use_switch) {
2268     lf_printf(file, "  /*%d*/ { 0, 0, %s_illegal },\n",
2269               opcode_nr, (idecode_cache ? "idecode" : "semantic"));
2270   }
2271 }
2272
2273
2274 /****************************************************************/
2275
2276
2277 void lf_print_idecode_switch
2278 (lf *file, 
2279  insn_table *table);
2280
2281
2282 static void
2283 idecode_switch_start(insn_table *table,
2284                 void *data,
2285                 int depth)
2286 {
2287   lf *file = (lf*)data;
2288   ASSERT(depth == 0);
2289   ASSERT(table->opcode_rule->use_switch);
2290
2291   lf_printf(file, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2292             table->opcode->first, table->opcode->last);
2293 }
2294
2295
2296 static void
2297 idecode_switch_leaf(insn_table *entry,
2298                     void *data,
2299                     int depth)
2300 {
2301   lf *file = (lf*)data;
2302   ASSERT(entry->parent != NULL);
2303   ASSERT(depth == 0);
2304   ASSERT(entry->parent->opcode_rule->use_switch);
2305
2306   lf_printf(file, "case %d:\n", entry->opcode_nr);
2307   lf_indent(file, +2);
2308   {
2309     if (entry->opcode == NULL) {
2310       /* switch calling leaf */
2311       lf_printf(file, "return ");
2312       lf_print_function_name(file,
2313                              entry->insns->file_entry->fields[insn_name],
2314                              entry->expanded_bits,
2315                              (idecode_cache
2316                               ? function_name_prefix_idecode
2317                               : function_name_prefix_semantics));
2318       if (idecode_cache)
2319         lf_printf(file, "(%s);\n", cache_idecode_actual);
2320       else
2321         lf_printf(file, "(%s);\n", semantic_actual);
2322     }
2323     else if (entry->opcode_rule->use_switch) {
2324       /* switch calling switch */
2325       lf_print_idecode_switch(file, entry);
2326     }
2327     else {
2328       /* switch calling table */
2329       lf_printf(file, "return ");
2330       lf_print_idecode_table(file, entry);
2331     }
2332     lf_printf(file, "break;\n");
2333   }
2334   lf_indent(file, -2);
2335 }
2336
2337
2338 static void
2339 lf_print_idecode_switch_illegal(lf *file)
2340 {
2341   lf_indent(file, +2);
2342   lf_print_idecode_illegal(file);
2343   lf_printf(file, "break;\n");
2344   lf_indent(file, -2);
2345 }
2346
2347 static void
2348 idecode_switch_end(insn_table *table,
2349                    void *data,
2350                    int depth)
2351 {
2352   lf *file = (lf*)data;
2353   ASSERT(depth == 0);
2354   ASSERT(table->opcode_rule->use_switch);
2355
2356   if (table->opcode_rule->use_switch == 1) {
2357     lf_printf(file, "default:\n");
2358     lf_print_idecode_switch_illegal(file);
2359   }
2360   lf_printf(file, "}\n");
2361 }
2362
2363 static void
2364 idecode_switch_padding(insn_table *table,
2365                        void *data,
2366                        int depth,
2367                        int opcode_nr)
2368 {
2369   lf *file = (lf*)data;
2370
2371   ASSERT(depth == 0);
2372   ASSERT(table->opcode_rule->use_switch);
2373
2374   if (table->opcode_rule->use_switch > 1) {
2375     lf_printf(file, "case %d:\n", opcode_nr);
2376     lf_print_idecode_switch_illegal(file);
2377   }
2378 }
2379
2380
2381 void
2382 lf_print_idecode_switch(lf *file, 
2383                         insn_table *table)
2384 {
2385   insn_table_traverse_tree(table,
2386                            file,
2387                            0,
2388                            idecode_switch_start,
2389                            idecode_switch_leaf,
2390                            idecode_switch_end,
2391                            idecode_switch_padding);
2392 }
2393
2394
2395 static void
2396 idecode_expand_if_switch(insn_table *table,
2397                          void *data,
2398                          int depth)
2399 {
2400   lf *file = (lf*)data;
2401
2402   if (table->opcode_rule->use_switch
2403       && table->parent != NULL /* don't expand the top one yet */
2404       && !table->parent->opcode_rule->use_switch) {
2405     lf_printf(file, "\n");
2406     lf_printf(file, "STATIC_INLINE_IDECODE void\n");
2407     lf_print_table_name(file, table);
2408     lf_printf(file, "\n(%s)\n",
2409               (idecode_cache ? cache_idecode_formal : semantic_formal));
2410     lf_printf(file, "{\n");
2411     {
2412       lf_indent(file, +2);
2413       lf_print_idecode_switch(file, table);
2414       lf_indent(file, -2);
2415     }
2416     lf_printf(file, "}\n");
2417   }
2418 }
2419
2420
2421 static void
2422 lf_print_c_cracker_function(lf *file,
2423                             insn *instruction,
2424                             insn_bits *expanded_bits,
2425                             opcode_field *opcodes)
2426 {
2427   /* if needed, generate code to enter this routine into a cache */
2428   lf_printf(file, "\n");
2429   lf_printf(file, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2430   lf_print_function_name(file,
2431                          instruction->file_entry->fields[insn_name],
2432                          expanded_bits,
2433                          function_name_prefix_idecode);
2434   lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2435
2436   lf_print_c_cracker(file,
2437                      instruction,
2438                      expanded_bits,
2439                      opcodes);
2440 }
2441
2442 static void
2443 idecode_crack_leaf(insn_table *entry,
2444                    void *data,
2445                    int depth)
2446 {
2447   lf *file = (lf*)data;
2448   ASSERT(entry->nr_insn == 1
2449          && entry->opcode == NULL
2450          && entry->parent != NULL
2451          && entry->parent->opcode != NULL);
2452   lf_print_c_cracker_function(file,
2453                               entry->insns,
2454                               entry->expanded_bits,
2455                               entry->opcode);
2456 }
2457
2458 static void
2459 idecode_crack_insn(insn_table *entry,
2460                    void *data,
2461                    insn *instruction)
2462 {
2463   lf *file = (lf*)data;
2464   lf_print_c_cracker_function(file,
2465                               instruction,
2466                               NULL,
2467                               NULL);
2468 }
2469
2470 static void
2471 idecode_c_internal_function(insn_table *table,
2472                             void *data,
2473                             table_entry *function)
2474 {
2475   lf *file = (lf*)data;
2476   ASSERT(idecode_cache != 0);
2477   if (it_is("internal", function->fields[insn_flags])) {
2478     lf_printf(file, "\n");
2479     lf_printf(file, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2480     lf_print_function_name(file,
2481                            function->fields[insn_name],
2482                            NULL,
2483                            function_name_prefix_idecode);
2484     lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2485     lf_printf(file, "{\n");
2486     lf_indent(file, +2);
2487     lf_printf(file, "/* semantic routine */\n");
2488     table_entry_lf_c_line_nr(file, function);
2489     lf_printf(file, "return ");
2490     lf_print_function_name(file,
2491                            function->fields[insn_name],
2492                            NULL,
2493                            function_name_prefix_semantics);
2494     lf_printf(file, ";\n");
2495
2496     lf_print_lf_c_line_nr(file);
2497     lf_indent(file, -2);
2498     lf_printf(file, "}\n");
2499   }
2500 }
2501
2502
2503 /****************************************************************/
2504
2505 static void
2506 gen_idecode_c(insn_table *table, lf *file)
2507 {
2508   int depth;
2509
2510   /* the intro */
2511   lf_print_copyleft(file);
2512   lf_printf(file, "\n");
2513   lf_printf(file, "\n");
2514   lf_printf(file, "#ifndef _IDECODE_C_\n");
2515   lf_printf(file, "#define _IDECODE_C_\n");
2516   lf_printf(file, "\n");
2517   lf_printf(file, "#ifndef STATIC_INLINE_IDECODE\n");
2518   lf_printf(file, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2519   lf_printf(file, "#endif\n");
2520   lf_printf(file, "\n");
2521   lf_printf(file, "#include \"cpu.h\"\n");
2522   lf_printf(file, "#include \"idecode.h\"\n");
2523   lf_printf(file, "#include \"semantics.h\"\n");
2524   lf_printf(file, "\n");
2525   lf_printf(file, "\n");
2526   lf_printf(file, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2527             (idecode_cache ? cache_idecode_formal : semantic_formal));
2528   lf_printf(file, "\n");
2529   lf_printf(file, "typedef struct _idecode_table_entry {\n");
2530   lf_printf(file, "  unsigned shift;\n");
2531   lf_printf(file, "  unsigned mask;\n");
2532   lf_printf(file, "  void *function_or_table;\n");
2533   lf_printf(file, "} idecode_table_entry;\n");
2534   lf_printf(file, "\n");
2535   lf_printf(file, "\n");
2536
2537   /* output `internal' invalid/floating-point unavailable functions
2538      where needed */
2539   if (idecode_cache) {
2540     insn_table_traverse_function(table,
2541                                  file,
2542                                  idecode_c_internal_function);
2543   }
2544
2545   /* output cracking functions where needed */
2546   if (idecode_cache) {
2547     if (idecode_expand_semantics)
2548       insn_table_traverse_tree(table,
2549                                file,
2550                                1,
2551                                NULL,
2552                                idecode_crack_leaf,
2553                                NULL,
2554                                NULL);
2555     else
2556       insn_table_traverse_insn(table,
2557                                file,
2558                                idecode_crack_insn);
2559   }
2560
2561
2562   /* output tables where needed */
2563   for (depth = insn_table_depth(table);
2564        depth > 0;
2565        depth--) {
2566     insn_table_traverse_tree(table,
2567                              file,
2568                              1-depth,
2569                              idecode_table_start,
2570                              idecode_table_leaf,
2571                              idecode_table_end,
2572                              idecode_table_padding);
2573   }
2574
2575   /* output switch functions where needed */
2576   insn_table_traverse_tree(table,
2577                            file,
2578                            1,
2579                            idecode_expand_if_switch, /* START */
2580                            NULL, NULL, NULL);
2581
2582   /* output the main idecode routine */
2583   lf_printf(file, "\n");
2584   if (idecode_cache)
2585     lf_printf(file, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2586               cache_idecode_formal);
2587   else
2588     lf_printf(file, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2589               semantic_formal);
2590   lf_printf(file, "{\n");
2591   lf_indent(file, +2);
2592   if (table->opcode_rule->use_switch)
2593     lf_print_idecode_switch(file, table);
2594   else
2595     lf_print_idecode_table(file, table);
2596   lf_indent(file, -2);
2597   lf_printf(file, "}\n");
2598   lf_printf(file, "\n");
2599   lf_printf(file, "#endif\n");
2600 }
2601
2602
2603 /****************************************************************/
2604
2605 static void
2606 itable_h_insn(insn_table *entry,
2607               void *data,
2608               insn *instruction)
2609 {
2610   lf *file = (lf*)data;
2611   lf_printf(file, "  ");
2612   lf_print_function_name(file,
2613                          instruction->file_entry->fields[insn_name],
2614                          NULL,
2615                          function_name_prefix_itable);
2616   lf_printf(file, ",\n");
2617 }
2618
2619
2620 static void 
2621 gen_itable_h(insn_table *table, lf *file)
2622 {
2623
2624   lf_print_copyleft(file);
2625   lf_printf(file, "\n");
2626   lf_printf(file, "#ifndef _ITABLE_H_\n");
2627   lf_printf(file, "#define _ITABLE_H_\n");
2628   lf_printf(file, "\n");
2629   lf_printf(file, "#ifndef INLINE_ITABLE\n");
2630   lf_printf(file, "#define INLINE_ITABLE\n");
2631   lf_printf(file, "#endif\n");
2632   lf_printf(file, "\n");
2633   lf_printf(file, "\n");
2634
2635   /* output an enumerated type for each instruction */
2636   lf_printf(file, "typedef enum {\n");
2637   insn_table_traverse_insn(table,
2638                            file,
2639                            itable_h_insn);
2640   lf_printf(file, "  nr_itable_entries,\n");
2641   lf_printf(file, "} itable_index;\n");
2642   lf_printf(file, "\n");
2643
2644   /* output the table that contains the actual instruction info */
2645   lf_printf(file, "typedef struct _itable_instruction_info {\n");
2646   lf_printf(file, "  itable_index nr;\n");
2647   lf_printf(file, "  char *format;\n");
2648   lf_printf(file, "  char *form;\n");
2649   lf_printf(file, "  char *flags;\n");
2650   lf_printf(file, "  char *nmemonic;\n");
2651   lf_printf(file, "  char *name;\n");
2652   lf_printf(file, "} itable_info;\n");
2653   lf_printf(file, "\n");
2654   lf_printf(file, "extern itable_info itable[nr_itable_entries];\n");
2655
2656   lf_printf(file, "\n");
2657   lf_printf(file, "#endif /* _ITABLE_C_ */\n");
2658
2659 }
2660
2661 /****************************************************************/
2662
2663 static void
2664 itable_c_insn(insn_table *entry,
2665               void *data,
2666               insn *instruction)
2667 {
2668   lf *file = (lf*)data;
2669   char **fields = instruction->file_entry->fields;
2670   lf_printf(file, "  { ");
2671   lf_print_function_name(file,
2672                          instruction->file_entry->fields[insn_name],
2673                          NULL,
2674                          function_name_prefix_itable);
2675   lf_printf(file, ",\n");
2676   lf_printf(file, "    \"%s\",\n", fields[insn_format]);
2677   lf_printf(file, "    \"%s\",\n", fields[insn_form]);
2678   lf_printf(file, "    \"%s\",\n", fields[insn_flags]);
2679   lf_printf(file, "    \"%s\",\n", fields[insn_nmemonic]);
2680   lf_printf(file, "    \"%s\",\n", fields[insn_name]);
2681   lf_printf(file, "    },\n");
2682 }
2683
2684
2685 static void 
2686 gen_itable_c(insn_table *table, lf *file)
2687 {
2688
2689   lf_print_copyleft(file);
2690   lf_printf(file, "\n");
2691   lf_printf(file, "#ifndef _ITABLE_C_\n");
2692   lf_printf(file, "#define _ITABLE_C_\n");
2693   lf_printf(file, "\n");
2694   lf_printf(file, "#ifndef STATIC_INLINE_ITABLE\n");
2695   lf_printf(file, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
2696   lf_printf(file, "#endif\n");
2697   lf_printf(file, "\n");
2698   lf_printf(file, "#include \"itable.h\"\n");
2699   lf_printf(file, "\n");
2700
2701   /* output the table that contains the actual instruction info */
2702   lf_printf(file, "itable_info itable[nr_itable_entries] = {\n");
2703   insn_table_traverse_insn(table,
2704                            file,
2705                            itable_c_insn);
2706   lf_printf(file, "};\n");
2707   lf_printf(file, "\n");
2708
2709   lf_printf(file, "\n");
2710   lf_printf(file, "#endif /* _ITABLE_C_ */\n");
2711
2712 }
2713
2714 /****************************************************************/
2715
2716
2717 int
2718 main(int argc,
2719      char **argv,
2720      char **envp)
2721 {
2722   insn_table *instructions = NULL;
2723   icache_tree *cache_fields = NULL;
2724   char *real_file_name = NULL;
2725   int ch;
2726
2727   if (argc == 1) {
2728     printf("Usage:\n");
2729     printf("-f <filter-out-flag>  eg -f 64 to skip 64bit instructions\n");
2730     printf("-[Ii] <instruction-table>  -I to dump internal table\n");
2731     printf("-[Oo] <opcode-rules>\n");
2732     printf("-[Kk] <cache-rules>\n");
2733     printf("-[Ss] <schematic>  output schematic.h(S) schematic.c(s)\n");
2734     printf("-[Dd] <schematic>  output idecode.h(S) idecode.c(s)\n");
2735     printf("-[Tt] <table>      output itable.h(t) itable.c(t)\n");
2736     printf("-[Cc] <schematic>  output icache.h(S) invalid(s)\n");
2737     printf("-e  Expand (duplicate) semantic functions\n");
2738     printf("-r <size>  Generate a cracking cache of <size>\n");
2739     printf("-l  Supress includsion of CPP line numbering in output files\n");
2740   }
2741
2742   while ((ch = getopt(argc, argv,
2743                       "ler:f:I:i:O:o:K:k:n:S:s:D:d:T:t:C:")) != -1) {
2744     fprintf(stderr, "\t-%c %s\n", ch, (optarg ? optarg : ""));
2745     switch(ch) {
2746     case 'l':
2747       number_lines = 0;
2748       break;
2749     case 'e':
2750       idecode_expand_semantics = 1;
2751       break;
2752     case 'r':
2753       idecode_cache = a2i(optarg);
2754       break;
2755     case 'f':
2756       {
2757         filter *new_filter = ZALLOC(filter);
2758         new_filter->flag = strdup(optarg);
2759         new_filter->next = filters;
2760         filters = new_filter;
2761         break;
2762       }
2763     case 'I':
2764     case 'i':
2765       ASSERT(opcode_table != NULL);
2766       ASSERT(cache_table != NULL);
2767       instructions = insn_table_load_insns(optarg);
2768       fprintf(stderr, "\texpanding ...\n");
2769       insn_table_expand_insns(instructions);
2770       fprintf(stderr, "\tcache fields ...\n");
2771       cache_fields = insn_table_cache_fields(instructions);
2772       if (ch == 'I') {
2773         dump_traverse(instructions);
2774         dump_insn_table(instructions, 0, 1);
2775       }
2776       break;
2777     case 'O':
2778     case 'o':
2779       opcode_table = load_opcode_rules(optarg);
2780       if (ch == 'O')
2781         dump_opcode_rules(opcode_table, 0);
2782       break;
2783     case 'K':
2784     case 'k':
2785       cache_table = load_cache_rules(optarg);
2786       if (ch == 'K')
2787         dump_cache_rules(cache_table, 0);
2788       break;
2789     case 'n':
2790       real_file_name = strdup(optarg);
2791       break;
2792     case 'S':
2793     case 's':
2794     case 'D':
2795     case 'd':
2796     case 'T':
2797     case 't':
2798     case 'C':
2799       {
2800         lf *file = lf_open(optarg, real_file_name, number_lines);
2801         ASSERT(instructions != NULL);
2802         switch (ch) {
2803         case 'S':
2804           gen_semantics_h(instructions, file);
2805           break;
2806         case 's':
2807           gen_semantics_c(instructions, file);
2808           break;
2809         case 'D':
2810           gen_idecode_h(instructions, file);
2811           break;
2812         case 'd':
2813           gen_idecode_c(instructions, file);
2814           break;
2815         case 'T':
2816           gen_itable_h(instructions, file);
2817           break;
2818         case 't':
2819           gen_itable_c(instructions, file);
2820           break;
2821         case 'C':
2822           gen_icache_h(cache_fields, file);
2823           break;
2824         }
2825         lf_close(file);
2826       }
2827       real_file_name = NULL;
2828       break;
2829     default:
2830       error("unknown option\n");
2831     }
2832   }
2833   return 0;
2834 }