checkpoint
[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 <getopt.h>
24
25 #include "misc.h"
26 #include "lf.h"
27 #include "table.h"
28 #include "config.h"
29
30 #ifdef HAVE_STRING_H
31 #include <string.h>
32 #else
33 #ifdef HAVE_STRINGS_H
34 #include <strings.h>
35 #endif
36 #endif
37
38
39
40 /****************************************************************/
41
42 enum {
43   max_insn_size = 32,
44 };
45
46 static int hi_bit_nr = 0;
47 static int insn_size = max_insn_size;
48 static int idecode_expand_semantics = 0;
49 static int idecode_cache = 0;
50 static int number_lines = 1;
51
52
53 /****************************************************************/
54
55
56 static char *cache_idecode_formal  =
57 "cpu *processor,\n\
58  instruction_word instruction,\n\
59  unsigned_word cia,\n\
60  idecode_cache *cache_entry";
61
62 static char *cache_idecode_actual = "processor, instruction, cia, cache_entry";
63
64 static char *cache_semantic_formal =
65 "cpu *processor,\n\
66  idecode_cache *cache_entry,\n\
67  unsigned_word cia";
68
69 static char *semantic_formal = 
70 "cpu *processor,\n\
71  instruction_word instruction,\n\
72  unsigned_word cia";
73
74 static char *semantic_actual = "processor, instruction, cia";
75
76
77
78 /****************************************************************/
79
80
81 typedef struct _filter filter;
82 struct _filter {
83   char *flag;
84   filter *next;
85 };
86 static filter *filters = NULL;
87
88
89 /****************************************************************/
90
91
92 typedef struct _cache_rules cache_rules;
93 struct _cache_rules {
94   int valid;
95   char *old_name;
96   char *new_name;
97   char *type;
98   char *expression;
99   cache_rules *next;
100 };
101 static cache_rules *cache_table;
102
103
104 enum {
105   ca_valid,
106   ca_old_name,
107   ca_new_name,
108   ca_type,
109   ca_expression,
110   nr_cache_rule_fields,
111 };
112
113 static cache_rules *
114 load_cache_rules(char *file_name)
115 {
116   table *file = table_open(file_name, nr_cache_rule_fields, 0);
117   table_entry *entry;
118   cache_rules *table = NULL;
119   cache_rules **curr_rule = &table;
120   while ((entry = table_entry_read(file)) != NULL) {
121     cache_rules *new_rule = ZALLOC(cache_rules);
122     new_rule->valid = target_a2i(hi_bit_nr, entry->fields[ca_valid]);
123     new_rule->old_name = entry->fields[ca_old_name];
124     new_rule->new_name = entry->fields[ca_new_name];
125     new_rule->type = (strlen(entry->fields[ca_type])
126                       ? entry->fields[ca_type]
127                       : NULL);
128     new_rule->expression = (strlen(entry->fields[ca_expression]) > 0
129                             ? entry->fields[ca_expression]
130                             : NULL);
131     *curr_rule = new_rule;
132     curr_rule = &new_rule->next;
133   }
134   return table;
135 }
136
137
138
139 static void
140 dump_cache_rule(cache_rules* rule,
141                 int indent)
142 {
143   dumpf(indent, "((cache_rules*)0x%x\n", rule);
144   dumpf(indent, " (valid %d)\n", rule->valid);
145   dumpf(indent, " (old_name \"%s\")\n", rule->old_name);
146   dumpf(indent, " (new_name \"%s\")\n", rule->new_name);
147   dumpf(indent, " (type \"%s\")\n", rule->type);
148   dumpf(indent, " (expression \"%s\")\n", rule->expression);
149   dumpf(indent, " (next 0x%x)\n", rule->next);
150   dumpf(indent, " )\n");
151 }
152
153
154 static void
155 dump_cache_rules(cache_rules* rule, int indent)
156 {
157   while (rule) {
158     dump_cache_rule(rule, indent);
159     rule = rule->next;
160   }
161 }
162
163
164 /****************************************************************/
165
166
167 typedef struct _opcode_rules opcode_rules;
168 struct _opcode_rules {
169   int first;
170   int last;
171   int force_first;
172   int force_last;
173   int force_slash;
174   char *force_expansion;
175   int use_switch;
176   unsigned special_mask;
177   unsigned special_value;
178   unsigned special_rule;
179   opcode_rules *next;
180 };
181 static opcode_rules *opcode_table;
182
183
184 enum {
185   op_first,
186   op_last,
187   op_force_first,
188   op_force_last,
189   op_force_slash,
190   op_force_expansion,
191   op_use_switch,
192   op_special_mask,
193   op_special_value,
194   op_special_rule,
195   nr_opcode_fields,
196 };
197
198
199 static opcode_rules *
200 load_opcode_rules(char *file_name)
201 {
202   table *file = table_open(file_name, nr_opcode_fields, 0);
203   table_entry *entry;
204   opcode_rules *table = NULL;
205   opcode_rules **curr_rule = &table;
206   while ((entry = table_entry_read(file)) != NULL) {
207     opcode_rules *new_rule = ZALLOC(opcode_rules);
208     new_rule->first = target_a2i(hi_bit_nr, entry->fields[op_first]);
209     new_rule->last = target_a2i(hi_bit_nr, entry->fields[op_last]);
210     new_rule->force_first = target_a2i(hi_bit_nr, entry->fields[op_force_first]);
211     new_rule->force_last = target_a2i(hi_bit_nr, entry->fields[op_force_last]);
212     new_rule->force_slash = a2i(entry->fields[op_force_slash]);
213     new_rule->force_expansion = entry->fields[op_force_expansion];
214     new_rule->use_switch = a2i(entry->fields[op_use_switch]);
215     new_rule->special_mask = a2i(entry->fields[op_special_mask]);
216     new_rule->special_value = a2i(entry->fields[op_special_value]);
217     new_rule->special_rule = a2i(entry->fields[op_special_rule]);
218     *curr_rule = new_rule;
219     curr_rule = &new_rule->next;
220   }
221   return table;
222 }
223
224   
225 static void
226 dump_opcode_rule(opcode_rules *rule,
227                  int indent)
228 {
229   dumpf(indent, "((opcode_rules*)%p\n", rule);
230   if (rule) {
231     dumpf(indent, " (first %d)\n", rule->first);
232     dumpf(indent, " (last %d)\n", rule->last);
233     dumpf(indent, " (force_first %d)\n", rule->force_first);
234     dumpf(indent, " (force_last %d)\n", rule->force_last);
235     dumpf(indent, " (force_slash %d)\n", rule->force_slash);
236     dumpf(indent, " (force_expansion \"%s\")\n", rule->force_expansion);
237     dumpf(indent, " (use_switch %d)\n", rule->use_switch);
238     dumpf(indent, " (special_mask 0x%x)\n", rule->special_mask);
239     dumpf(indent, " (special_value 0x%x)\n", rule->special_value);
240     dumpf(indent, " (special_rule 0x%x)\n", rule->special_rule);
241     dumpf(indent, " (next 0x%x)\n", rule->next);
242   }
243   dumpf(indent, " )\n");
244 }
245
246
247 static void
248 dump_opcode_rules(opcode_rules *rule,
249                   int indent)
250 {
251   while (rule) {
252     dump_opcode_rule(rule, indent);
253     rule = rule->next;
254   }
255 }
256
257
258 /****************************************************************/
259
260 typedef struct _insn_field insn_field;
261 struct _insn_field {
262   int first;
263   int last;
264   int width;
265   int is_int;
266   int is_slash;
267   int is_string;
268   int val_int;
269   char *pos_string;
270   char *val_string;
271   insn_field *next;
272   insn_field *prev;
273 };
274
275 typedef struct _insn_fields insn_fields;
276 struct _insn_fields {
277   insn_field *bits[max_insn_size];
278   insn_field *first;
279   insn_field *last;
280   unsigned value;
281 };
282
283 static insn_fields *
284 parse_insn_format(table_entry *entry,
285                   char *format)
286 {
287   char *chp;
288   insn_fields *fields = ZALLOC(insn_fields);
289
290   /* create a leading sentinal */
291   fields->first = ZALLOC(insn_field);
292   fields->first->first = -1;
293   fields->first->last = -1;
294   fields->first->width = 0;
295
296   /* and a trailing sentinal */
297   fields->last = ZALLOC(insn_field);
298   fields->last->first = insn_size;
299   fields->last->last = insn_size;
300   fields->last->width = 0;
301
302   /* link them together */
303   fields->first->next = fields->last;
304   fields->last->prev = fields->first;
305
306   /* now work through the formats */
307   chp = format;
308
309   while (*chp != '\0') {
310     char *start_pos;
311     char *start_val;
312     int strlen_val;
313     int strlen_pos;
314     insn_field *new_field;
315
316     /* sanity check */
317     if (!isdigit(*chp)) {
318       error("%s:%d: missing position field at `%s'\n",
319             entry->file_name, entry->line_nr, chp);
320     }
321
322     /* break out the bit position */
323     start_pos = chp;
324     while (isdigit(*chp))
325       chp++;
326     strlen_pos = chp - start_pos;
327     if (*chp == '.' && strlen_pos > 0)
328       chp++;
329     else {
330       error("%s:%d: missing field value at %s\n",
331             entry->file_name, entry->line_nr, chp);
332       break;
333     }
334
335     /* break out the value */
336     start_val = chp;
337     while ((*start_val == '/' && *chp == '/')
338            || (isdigit(*start_val) && isdigit(*chp))
339            || (isalpha(*start_val) && (isalnum(*chp) || *chp == '_')))
340       chp++;
341     strlen_val = chp - start_val;
342     if (*chp == ',')
343       chp++;
344     else if (*chp != '\0' || strlen_val == 0) {
345       error("%s:%d: missing field terminator at %s\n",
346             entry->file_name, entry->line_nr, chp);
347       break;
348     }
349
350     /* create a new field and insert it */
351     new_field = ZALLOC(insn_field);
352     new_field->next = fields->last;
353     new_field->prev = fields->last->prev;
354     new_field->next->prev = new_field;
355     new_field->prev->next = new_field;
356
357     /* the value */
358     new_field->val_string = (char*)zalloc(strlen_val+1);
359     strncpy(new_field->val_string, start_val, strlen_val);
360     if (isdigit(*new_field->val_string)) {
361       new_field->val_int = a2i(new_field->val_string);
362       new_field->is_int = 1;
363     }
364     else if (new_field->val_string[0] == '/') {
365       new_field->is_slash = 1;
366     }
367     else {
368       new_field->is_string = 1;
369     }
370     
371     /* the pos */
372     new_field->pos_string = (char*)zalloc(strlen_pos+1);
373     strncpy(new_field->pos_string, start_pos, strlen_pos);
374     new_field->first = target_a2i(hi_bit_nr, new_field->pos_string);
375     new_field->last = new_field->next->first - 1; /* guess */
376     new_field->width = new_field->last - new_field->first + 1; /* guess */
377     new_field->prev->last = new_field->first-1; /*fix*/
378     new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
379   }
380
381   /* fiddle first/last so that the sentinals `disapear' */
382   ASSERT(fields->first->last < 0);
383   ASSERT(fields->last->first >= insn_size);
384   fields->first = fields->first->next;
385   fields->last = fields->last->prev;
386
387   /* now go over this again, pointing each bit position at a field
388      record */
389   {
390     int i;
391     insn_field *field;
392     field = fields->first;
393     for (i = 0; i < insn_size; i++) {
394       while (field->last < i)
395         field = field->next;
396       fields->bits[i] = field;
397     }
398   }
399
400   /* go over each of the fields, and compute a `value' for the insn */
401   {
402     insn_field *field;
403     fields->value = 0;
404     for (field = fields->first;
405          field->last < insn_size;
406          field = field->next) {
407       fields->value <<= field->width;
408       if (field->is_int)
409         fields->value |= field->val_int;
410     }
411   }
412   return fields;
413 }
414
415
416 typedef enum {
417   field_constant_int = 1,
418   field_constant_slash = 2,
419   field_constant_string = 3
420 } constant_field_types;
421
422
423 static int
424 insn_field_is_constant(insn_field *field,
425                        opcode_rules *rule)
426 {
427   /* field is an integer */
428   if (field->is_int)
429     return field_constant_int;
430   /* field is `/' and treating that as a constant */
431   if (field->is_slash && rule->force_slash)
432     return field_constant_slash;
433   /* field, though variable is on the list */
434   if (field->is_string && rule->force_expansion != NULL) {
435     char *forced_fields = rule->force_expansion;
436     while (*forced_fields != '\0') {
437       int field_len;
438       char *end = strchr(forced_fields, ',');
439       if (end == NULL)
440         field_len = strlen(forced_fields);
441       else
442         field_len = end-forced_fields;
443       if (strncmp(forced_fields, field->val_string, field_len) == 0
444           && field->val_string[field_len] == '\0')
445         return field_constant_string;
446       forced_fields += field_len;
447       if (*forced_fields == ',')
448         forced_fields++;
449     }
450   }
451   return 0;
452 }
453
454
455 static void
456 dump_insn_field(insn_field *field,
457                 int indent)
458 {
459
460   printf("(insn_field*)0x%x\n", (unsigned)field);
461
462   dumpf(indent, "(first %d)\n", field->first);
463
464   dumpf(indent, "(last %d)\n", field->last);
465
466   dumpf(indent, "(width %d)\n", field->width);
467
468   if (field->is_int)
469     dumpf(indent, "(is_int %d)\n", field->val_int);
470
471   if (field->is_slash)
472     dumpf(indent, "(is_slash)\n");
473
474   if (field->is_string)
475     dumpf(indent, "(is_string `%s')\n", field->val_string);
476   
477   dumpf(indent, "(next 0x%x)\n", field->next);
478   
479   dumpf(indent, "(prev 0x%x)\n", field->prev);
480   
481
482 }
483
484 static void
485 dump_insn_fields(insn_fields *fields,
486                  int indent)
487 {
488   int i;
489
490   printf("(insn_fields*)%p\n", fields);
491
492   dumpf(indent, "(first 0x%x)\n", fields->first);
493   dumpf(indent, "(last 0x%x)\n", fields->last);
494
495   dumpf(indent, "(value 0x%x)\n", fields->value);
496
497   for (i = 0; i < insn_size; i++) {
498     dumpf(indent, "(bits[%d] ", i, fields->bits[i]);
499     dump_insn_field(fields->bits[i], indent+1);
500     dumpf(indent, " )\n");
501   }
502
503 }
504
505
506 /****************************************************************/
507
508 typedef struct _opcode_field opcode_field;
509 struct _opcode_field {
510   int first;
511   int last;
512   int is_boolean;
513   opcode_field *parent;
514 };
515
516 static void
517 dump_opcode_field(opcode_field *field, int indent, int levels)
518 {
519   printf("(opcode_field*)%p\n", field);
520   if (levels && field != NULL) {
521     dumpf(indent, "(first %d)\n", field->first);
522     dumpf(indent, "(last %d)\n", field->last);
523     dumpf(indent, "(is_boolean %d)\n", field->is_boolean);
524     dumpf(indent, "(parent ");
525     dump_opcode_field(field->parent, indent, levels-1);
526   }
527 }
528
529
530 /****************************************************************/
531
532 typedef struct _insn_bits insn_bits;
533 struct _insn_bits {
534   int is_expanded;
535   int value;
536   insn_field *field;
537   opcode_field *opcode;
538   insn_bits *last;
539 };
540
541
542 static void
543 dump_insn_bits(insn_bits *bits, int indent, int levels)
544 {
545   printf("(insn_bits*)%p\n", bits);
546
547   if (levels && bits != NULL) {
548     dumpf(indent, "(value %d)\n", bits->value);
549     dumpf(indent, "(opcode ");
550     dump_opcode_field(bits->opcode, indent+1, 0);
551     dumpf(indent, " )\n");
552     dumpf(indent, "(field ");
553     dump_insn_field(bits->field, indent+1);
554     dumpf(indent, " )\n");
555     dumpf(indent, "(last ");
556     dump_insn_bits(bits->last, indent+1, levels-1);
557   }
558 }
559
560
561 /****************************************************************/
562
563
564 typedef enum {
565   insn_format,
566   insn_form,
567   insn_flags,
568   insn_mnemonic,
569   insn_name,
570   insn_comment,
571   nr_insn_table_fields
572 } insn_table_fields;
573
574 typedef enum {
575   function_type = insn_format,
576   function_name = insn_name,
577   function_param = insn_comment
578 } function_table_fields;
579
580 typedef enum {
581   model_default = insn_form,
582   model_name = insn_mnemonic,
583   model_identifer = insn_name,
584   model_func = insn_comment,
585 } model_table_fields;
586
587 typedef struct _insn insn;
588 struct _insn {
589   table_entry *file_entry;
590   insn_fields *fields;
591   insn *next;
592 };
593
594 typedef struct _model_func_unit model_func_unit;
595 struct _model_func_unit {
596   model_func_unit *next;
597   char *name;
598   char *comment;
599   int number;
600   unsigned mask;
601 };
602
603 typedef struct _model model;
604 struct _model {
605   model *next;
606   char *name;
607   char *printable_name;
608   model_func_unit *func_unit_start;
609   model_func_unit *func_unit_end;
610 };
611   
612 typedef struct _insn_table insn_table;
613 struct _insn_table {
614   int opcode_nr;
615   insn_bits *expanded_bits;
616   int nr_insn;
617   insn *insns;
618   insn *functions;
619   insn *last_function;
620   int max_func_unit_name_len;
621   unsigned max_func_unit_mask;
622   opcode_rules *opcode_rule;
623   opcode_field *opcode;
624   int nr_entries;
625   insn_table *entries;
626   insn_table *sibling;
627   insn_table *parent;
628 };
629
630 typedef enum {
631   insn_model_name,
632   insn_model_unit,
633   insn_model_issue,
634   insn_model_done,
635   insn_model_flags,
636   nr_insn_model_table_fields
637 } insn_model_table_fields;
638
639 static model *models;
640 static model *last_model;
641
642 static insn *model_macros;
643 static insn *last_model_macro;
644
645 static insn *model_functions;
646 static insn *last_model_function;
647
648 static insn *model_internal;
649 static insn *last_model_internal;
650
651 static insn *model_data;
652 static insn *last_model_data;
653
654 static void
655 insn_table_insert_function(insn_table *table,
656                            table_entry *file_entry)
657 {
658   /* create a new function */
659   insn *new_function = ZALLOC(insn);
660   new_function->file_entry = file_entry;
661
662   /* append it to the end of the function list */
663   if (table->last_function)
664     table->last_function->next = new_function;
665   else
666     table->functions = new_function;
667   table->last_function = new_function;
668 }
669
670 static void
671 insn_table_insert_insn(insn_table *table,
672                        table_entry *file_entry,
673                        insn_fields *fields)
674 {
675   insn **ptr_to_cur_insn = &table->insns;
676   insn *cur_insn = *ptr_to_cur_insn;
677   table_model_entry *insn_model_ptr;
678   model *model_ptr;
679
680   /* create a new instruction */
681   insn *new_insn = ZALLOC(insn);
682   new_insn->file_entry = file_entry;
683   new_insn->fields = fields;
684
685   /* Check out any model information returned to make sure the model
686      is correct.  */
687   for(insn_model_ptr = file_entry->model_first; insn_model_ptr; insn_model_ptr = insn_model_ptr->next) {
688     char *name = insn_model_ptr->fields[insn_model_name];
689
690     for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
691       if (strcmp(name, model_ptr->name) == 0) {
692
693         /* Replace the name field with that of the global model, so that when we
694            want to print it out, we can just compare pointers.  */
695         insn_model_ptr->fields[insn_model_name] = model_ptr->name;
696         break;
697       }
698     }
699
700     if (!model_ptr)
701       error("%s:%d: machine model `%s' was not known about\n",
702             file_entry->file_name, file_entry->line_nr, name);
703   }
704
705   /* insert it according to the order of the fields */
706   while (cur_insn != NULL
707          && new_insn->fields->value >= cur_insn->fields->value) {
708     ptr_to_cur_insn = &cur_insn->next;
709     cur_insn = *ptr_to_cur_insn;
710   }
711
712   new_insn->next = cur_insn;
713   *ptr_to_cur_insn = new_insn;
714
715   table->nr_insn++;
716 }
717
718
719 static opcode_field *
720 insn_table_find_opcode_field(insn *insns,
721                              opcode_rules *rule,
722                              int string_only)
723 {
724   opcode_field *curr_opcode = ZALLOC(opcode_field);
725   insn *entry;
726   ASSERT(rule);
727
728   curr_opcode->first = insn_size;
729   curr_opcode->last = -1;
730   for (entry = insns; entry != NULL; entry = entry->next) {
731     insn_fields *fields = entry->fields;
732     opcode_field new_opcode;
733
734     /* find a start point for the opcode field */
735     new_opcode.first = rule->first;
736     while (new_opcode.first <= rule->last
737            && (!string_only
738                || insn_field_is_constant(fields->bits[new_opcode.first],
739                                          rule) != field_constant_string)
740            && (string_only
741                || !insn_field_is_constant(fields->bits[new_opcode.first],
742                                           rule)))
743       new_opcode.first = fields->bits[new_opcode.first]->last + 1;
744     ASSERT(new_opcode.first > rule->last
745            || (string_only
746                && insn_field_is_constant(fields->bits[new_opcode.first],
747                                          rule) == field_constant_string)
748            || (!string_only
749                && insn_field_is_constant(fields->bits[new_opcode.first],
750                                          rule)));
751   
752     /* find the end point for the opcode field */
753     new_opcode.last = rule->last;
754     while (new_opcode.last >= rule->first
755            && (!string_only
756                || insn_field_is_constant(fields->bits[new_opcode.last],
757                                          rule) != field_constant_string)
758            && (string_only
759                || !insn_field_is_constant(fields->bits[new_opcode.last],
760                                           rule)))
761       new_opcode.last = fields->bits[new_opcode.last]->first - 1;
762     ASSERT(new_opcode.last < rule->first
763            || (string_only
764                && insn_field_is_constant(fields->bits[new_opcode.last],
765                                          rule) == field_constant_string)
766            || (!string_only
767                && insn_field_is_constant(fields->bits[new_opcode.last],
768                                          rule)));
769
770     /* now see if our current opcode needs expanding */
771     if (new_opcode.first <= rule->last
772         && curr_opcode->first > new_opcode.first)
773       curr_opcode->first = new_opcode.first;
774     if (new_opcode.last >= rule->first
775         && curr_opcode->last < new_opcode.last)
776       curr_opcode->last = new_opcode.last;
777     
778   }
779
780   /* was any thing interesting found? */
781   if (curr_opcode->first > rule->last) {
782     ASSERT(curr_opcode->last < rule->first);
783     return NULL;
784   }
785   ASSERT(curr_opcode->last >= rule->first);
786   ASSERT(curr_opcode->first <= rule->last);
787
788   /* if something was found, check it includes the forced field range */
789   if (!string_only
790       && curr_opcode->first > rule->force_first) {
791     curr_opcode->first = rule->force_first;
792   }
793   if (!string_only
794       && curr_opcode->last < rule->force_last) {
795     curr_opcode->last = rule->force_last;
796   }
797   /* handle special case elminating any need to do shift after mask */
798   if (string_only
799       && rule->force_last == insn_size-1) {
800     curr_opcode->last = insn_size-1;
801   }
802
803   /* handle any special cases */
804   switch (rule->special_rule) {
805   case 0: /* let the above apply */
806     break;
807   case 1: /* expand a limited nr of bits, ignoring the rest */
808     curr_opcode->first = rule->force_first;
809     curr_opcode->last = rule->force_last;
810     break;
811   case 2: /* boolean field */
812     curr_opcode->is_boolean = 1;
813     break;
814   }
815
816   return curr_opcode;
817 }
818
819
820 static void
821 insn_table_insert_expanded(insn_table *table,
822                            insn *old_insn,
823                            int new_opcode_nr,
824                            insn_bits *new_bits)
825 {
826   insn_table **ptr_to_cur_entry = &table->entries;
827   insn_table *cur_entry = *ptr_to_cur_entry;
828
829   /* find the new table for this entry */
830   while (cur_entry != NULL
831          && cur_entry->opcode_nr < new_opcode_nr) {
832     ptr_to_cur_entry = &cur_entry->sibling;
833     cur_entry = *ptr_to_cur_entry;
834   }
835
836   if (cur_entry == NULL || cur_entry->opcode_nr != new_opcode_nr) {
837     insn_table *new_entry = ZALLOC(insn_table);
838     new_entry->opcode_nr = new_opcode_nr;
839     new_entry->expanded_bits = new_bits;
840     new_entry->opcode_rule = table->opcode_rule->next;
841     new_entry->sibling = cur_entry;
842     new_entry->parent = table;
843     *ptr_to_cur_entry = new_entry;
844     cur_entry = new_entry;
845     table->nr_entries++;
846   }
847   /* ASSERT new_bits == cur_entry bits */
848   ASSERT(cur_entry != NULL && cur_entry->opcode_nr == new_opcode_nr);
849   insn_table_insert_insn(cur_entry,
850                          old_insn->file_entry,
851                          old_insn->fields);
852 }
853
854 static void
855 insn_table_expand_opcode(insn_table *table,
856                          insn *instruction,
857                          int field_nr,
858                          int opcode_nr,
859                          insn_bits *bits)
860 {
861
862   if (field_nr > table->opcode->last) {
863     insn_table_insert_expanded(table, instruction, opcode_nr, bits);
864   }
865   else {
866     insn_field *field = instruction->fields->bits[field_nr];
867     if (field->is_int || field->is_slash) {
868       ASSERT(field->first >= table->opcode->first
869              && field->last <= table->opcode->last);
870       insn_table_expand_opcode(table, instruction, field->last+1,
871                                ((opcode_nr << field->width) + field->val_int),
872                                bits);
873     }
874     else {
875       int val;
876       int last_pos = ((field->last < table->opcode->last)
877                         ? field->last : table->opcode->last);
878       int first_pos = ((field->first > table->opcode->first)
879                          ? field->first : table->opcode->first);
880       int width = last_pos - first_pos + 1;
881       int last_val = (table->opcode->is_boolean
882                       ? 2 : (1 << width));
883       for (val = 0; val < last_val; val++) {
884         insn_bits *new_bits = ZALLOC(insn_bits);
885         new_bits->field = field;
886         new_bits->value = val;
887         new_bits->last = bits;
888         new_bits->opcode = table->opcode;
889         insn_table_expand_opcode(table, instruction, last_pos+1,
890                                  ((opcode_nr << width) | val),
891                                  new_bits);
892       }
893     }
894   }
895 }
896
897 static void
898 insn_table_insert_expanding(insn_table *table,
899                             insn *entry)
900 {
901   insn_table_expand_opcode(table,
902                            entry,
903                            table->opcode->first,
904                            0,
905                            table->expanded_bits);
906 }
907
908
909 static void
910 insn_table_expand_insns(insn_table *table)
911 {
912
913   ASSERT(table->nr_insn >= 1);
914
915   /* determine a valid opcode */
916   while (table->opcode_rule) {
917     /* specials only for single instructions */
918     if ((table->nr_insn > 1
919          && table->opcode_rule->special_mask == 0
920          && table->opcode_rule->special_rule == 0)
921         || (table->nr_insn == 1
922             && table->opcode_rule->special_mask != 0
923             && ((table->insns->fields->value
924                  & table->opcode_rule->special_mask)
925                 == table->opcode_rule->special_value))
926         || (idecode_expand_semantics
927             && table->opcode_rule->special_mask == 0
928             && table->opcode_rule->special_rule == 0))
929       table->opcode =
930         insn_table_find_opcode_field(table->insns,
931                                      table->opcode_rule,
932                                      table->nr_insn == 1/*string*/
933                                      );
934     if (table->opcode != NULL)
935       break;
936     table->opcode_rule = table->opcode_rule->next;
937   }
938
939   /* did we find anything */
940   if (table->opcode == NULL) {
941     return;
942   }
943   ASSERT(table->opcode != NULL);
944
945   /* back link what we found to its parent */
946   if (table->parent != NULL) {
947     ASSERT(table->parent->opcode != NULL);
948     table->opcode->parent = table->parent->opcode;
949   }
950
951   /* expand the raw instructions according to the opcode */
952   {
953     insn *entry;
954     for (entry = table->insns; entry != NULL; entry = entry->next) {
955       insn_table_insert_expanding(table, entry);
956     }
957   }
958
959   /* and do the same for the sub entries */
960   {
961     insn_table *entry;
962     for (entry = table->entries; entry != NULL; entry =  entry->sibling) {
963       insn_table_expand_insns(entry);
964     }
965   }
966 }
967
968
969 static void
970 model_table_insert(insn_table *table,
971                    table_entry *file_entry)
972 {
973   /* create a new model */
974   model *new_model = ZALLOC(model);
975   model_func_unit *func_unit;
976   char *ptr, *end, *end_name, *comment, *name;
977   int ch;
978   int name_len;
979   int func_name_len;
980   unsigned unit, mask;
981   int number;
982
983   new_model->name = file_entry->fields[model_identifer];
984   new_model->printable_name = file_entry->fields[model_name];
985   name_len = strlen(new_model->name);
986
987   /* append it to the end of the model list */
988   if (last_model)
989     last_model->next = new_model;
990   else
991     models = new_model;
992   last_model = new_model;
993
994   /* Parse the function units separated by commas */
995   unit = 1;
996   for (ptr = file_entry->fields[model_func];
997        ((ch = *ptr) != '\0') && (ch != '\n');
998        ptr = (*end == ',') ? end+1 : end) {
999
1000     while (ch == ' ' || ch == '\t')
1001       ch = *++ptr;
1002
1003     if (!ch || ch == '\n')
1004       break;
1005
1006     /* Search for comma or newline ending field */
1007     end = ptr;
1008     end_name = (char *)0;
1009
1010     if (ch == ',')
1011       continue;
1012
1013     while (ch != '\0' && ch != ',' && ch != '\n') {
1014       if (end_name == (char *)0 && (ch == '=' || isspace(ch)))
1015         end_name = end;
1016
1017       ch = *++end;
1018     }
1019     if (!end_name)
1020       end_name = end;
1021
1022     func_unit = ZALLOC(model_func_unit);
1023     if (new_model->func_unit_end)
1024       new_model->func_unit_end->next = func_unit;
1025     else
1026       new_model->func_unit_start = func_unit;
1027
1028     new_model->func_unit_end = func_unit;
1029
1030     /* Record function unit name as model name _ unit name */
1031     func_name_len = name_len + end_name - ptr + 2;
1032     if (table->max_func_unit_name_len < func_name_len)
1033       table->max_func_unit_name_len = func_name_len;
1034
1035     func_unit->name = name = (char *)zalloc(func_name_len);
1036     memcpy(name, new_model->name, name_len);
1037     name[name_len] = '_';
1038     memcpy(name + name_len + 1, ptr, end_name - ptr);
1039
1040     /* See if there are multiple functional units */
1041     if (*end_name == '=') {
1042       number = 0;
1043       for(end_name++; end_name < end && isdigit(*end_name); end_name++)
1044         number = number * 10 + (*end_name - '0');
1045     } else {
1046       number = 1;
1047     }
1048
1049     /* Now figure out the mask for these unit(s) */
1050     func_unit->number = number;
1051     mask = 0;
1052     while (number--) {
1053       ASSERT(unit != 0);
1054       mask |= unit;
1055       unit <<= 1;
1056     }
1057     func_unit->mask = mask;
1058     table->max_func_unit_mask |= mask;
1059
1060     /* Now figure out comments */
1061     for (comment = end_name; comment < end && ((ch = *comment) == ' ' || ch == '\t'); comment++)
1062       ;
1063
1064     if (comment < end) {
1065       func_unit->comment = (char *)zalloc(end - comment + 1);
1066       memcpy(func_unit->comment, comment, end - comment);
1067     }
1068   }
1069
1070   /* Add an 'sentinel' function unit at the end to simpify the loop */
1071   func_unit = ZALLOC(model_func_unit);
1072   if (new_model->func_unit_end)
1073     new_model->func_unit_end->next = func_unit;
1074   else
1075     new_model->func_unit_start = func_unit;
1076
1077   new_model->func_unit_end = func_unit;
1078
1079   /* Record function unit name as model name _ unit name */
1080   func_name_len = name_len + sizeof("_SENTINEL");
1081   if (table->max_func_unit_name_len < func_name_len)
1082     table->max_func_unit_name_len = func_name_len;
1083
1084   func_unit->name = name = (char *)zalloc(func_name_len);
1085   func_unit->number = 0;
1086   func_unit->mask = unit;
1087   func_unit->comment = "dummy";
1088   table->max_func_unit_mask |= unit;
1089
1090   memcpy(name, new_model->name, name_len);
1091   strcpy(name + name_len, "_SENTINEL");
1092 }
1093
1094 static void
1095 model_table_insert_specific(insn_table *table,
1096                             table_entry *file_entry,
1097                             insn **start_ptr,
1098                             insn **end_ptr)
1099 {
1100   insn *ptr = ZALLOC(insn);
1101   ptr->file_entry = file_entry;
1102   if (*end_ptr)
1103     (*end_ptr)->next = ptr;
1104   else
1105     (*start_ptr) = ptr;
1106   (*end_ptr) = ptr;
1107 }
1108
1109
1110
1111 static insn_table *
1112 insn_table_load_insns(char *file_name)
1113 {
1114   table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);
1115   insn_table *table = ZALLOC(insn_table);
1116   table_entry *file_entry;
1117   table->opcode_rule = opcode_table;
1118
1119   while ((file_entry = table_entry_read(file)) != NULL) {
1120     if (it_is("function", file_entry->fields[insn_flags])
1121         || it_is("internal", file_entry->fields[insn_flags])) {
1122       insn_table_insert_function(table, file_entry);
1123     }
1124     else if (it_is("model", file_entry->fields[insn_flags])) {
1125       model_table_insert(table, file_entry);
1126     }
1127     else if (it_is("model-macro", file_entry->fields[insn_flags])) {
1128       model_table_insert_specific(table, file_entry, &model_macros, &last_model_macro);
1129     }
1130     else if (it_is("model-function", file_entry->fields[insn_flags])) {
1131       model_table_insert_specific(table, file_entry, &model_functions, &last_model_function);
1132     }
1133     else if (it_is("model-internal", file_entry->fields[insn_flags])) {
1134       model_table_insert_specific(table, file_entry, &model_internal, &last_model_internal);
1135     }
1136     else if (it_is("model-data", file_entry->fields[insn_flags])) {
1137       model_table_insert_specific(table, file_entry, &model_data, &last_model_data);
1138     }
1139     else {
1140       insn_fields *fields;
1141       /* skip instructions that aren't relevant to the mode */
1142       filter *filt = filters;
1143       while (filt != NULL) {
1144         if (it_is(filt->flag, file_entry->fields[insn_flags]))
1145           break;
1146         filt = filt->next;
1147       }
1148       if (filt == NULL) {
1149         /* create/insert the new instruction */
1150         fields = parse_insn_format(file_entry,
1151                                    file_entry->fields[insn_format]);
1152         insn_table_insert_insn(table, file_entry, fields);
1153       }
1154     }
1155   }
1156   return table;
1157 }
1158
1159
1160 static void
1161 dump_insn(insn *entry, int indent, int levels)
1162 {
1163   printf("(insn*)%p\n", entry);
1164
1165   if (levels && entry != NULL) {
1166
1167     dumpf(indent, "(file_entry ");
1168     dump_table_entry(entry->file_entry, indent+1);
1169     dumpf(indent, " )\n");
1170
1171     dumpf(indent, "(fields ");
1172     dump_insn_fields(entry->fields, indent+1);
1173     dumpf(indent, " )\n");
1174
1175     dumpf(indent, "(next ");
1176     dump_insn(entry->next, indent+1, levels-1);
1177     dumpf(indent, " )\n");
1178
1179   }
1180
1181 }
1182
1183
1184 static void
1185 dump_insn_table(insn_table *table,
1186                 int indent, int levels)
1187 {
1188
1189   printf("(insn_table*)%p\n", table);
1190
1191   if (levels && table != NULL) {
1192
1193     dumpf(indent, "(opcode_nr %d)\n", table->opcode_nr);
1194
1195     dumpf(indent, "(expanded_bits ");
1196     dump_insn_bits(table->expanded_bits, indent+1, -1);
1197     dumpf(indent, " )\n");
1198
1199     dumpf(indent, "(int nr_insn %d)\n", table->nr_insn);
1200
1201     dumpf(indent, "(insns ");
1202     dump_insn(table->insns, indent+1, table->nr_insn);
1203     dumpf(indent, " )\n");
1204
1205     dumpf(indent, "(opcode_rule ");
1206     dump_opcode_rule(table->opcode_rule, indent+1);
1207     dumpf(indent, " )\n");
1208
1209     dumpf(indent, "(opcode ");
1210     dump_opcode_field(table->opcode, indent+1, 1);
1211     dumpf(indent, " )\n");
1212
1213     dumpf(indent, "(nr_entries %d)\n", table->entries);
1214     dumpf(indent, "(entries ");
1215     dump_insn_table(table->entries, indent+1, table->nr_entries);
1216     dumpf(indent, " )\n");
1217
1218     dumpf(indent, "(sibling ", table->sibling);
1219     dump_insn_table(table->sibling, indent+1, levels-1);
1220     dumpf(indent, " )\n");
1221
1222     dumpf(indent, "(parent ", table->parent);
1223     dump_insn_table(table->parent, indent+1, 0);
1224     dumpf(indent, " )\n");
1225
1226   }
1227 }
1228
1229
1230 /****************************************************************/
1231
1232
1233 static void
1234 lf_print_insn_bits(lf *file, insn_bits *bits)
1235 {
1236   if (bits == NULL)
1237     return;
1238   lf_print_insn_bits(file, bits->last);
1239   lf_putchr(file, '_');
1240   lf_putstr(file, bits->field->val_string);
1241   if (!bits->opcode->is_boolean || bits->value == 0) {
1242     if (bits->opcode->last < bits->field->last)
1243       lf_putint(file, bits->value << (bits->field->last - bits->opcode->last));
1244     else
1245       lf_putint(file, bits->value);
1246   }
1247 }
1248
1249 static void
1250 lf_print_opcodes(lf *file,
1251                  insn_table *table)
1252 {
1253   if (table != NULL) {
1254     while (1) {
1255       lf_printf(file, "_%d_%d",
1256                 table->opcode->first,
1257                 table->opcode->last);
1258       if (table->parent == NULL) break;
1259       lf_printf(file, "__%d", table->opcode_nr);
1260       table = table->parent;
1261     }
1262   }
1263 }
1264
1265 static void
1266 lf_print_table_name(lf *file,
1267                     insn_table *table)
1268 {
1269   lf_printf(file, "idecode_table");
1270   lf_print_opcodes(file, table);
1271 }
1272
1273
1274
1275 typedef enum {
1276   function_name_prefix_semantics,
1277   function_name_prefix_idecode,
1278   function_name_prefix_itable,
1279   function_name_prefix_none
1280 } lf_function_name_prefixes;
1281
1282 static void
1283 lf_print_function_name(lf *file,
1284                        char *basename,
1285                        insn_bits *expanded_bits,
1286                        lf_function_name_prefixes prefix)
1287 {
1288
1289   /* the prefix */
1290   switch (prefix) {
1291   case function_name_prefix_semantics:
1292     lf_putstr(file, "semantic_");
1293     break;
1294   case function_name_prefix_idecode:
1295     lf_printf(file, "idecode_");
1296     break;
1297   case function_name_prefix_itable:
1298     lf_putstr(file, "itable_");
1299     break;
1300   default:
1301     break;
1302   }
1303
1304   /* the function name */
1305   {
1306     char *pos;
1307     for (pos = basename;
1308          *pos != '\0';
1309          pos++) {
1310       switch (*pos) {
1311       case '/':
1312       case '-':
1313         break;
1314       case ' ':
1315         lf_putchr(file, '_');
1316         break;
1317       default:
1318         lf_putchr(file, *pos);
1319         break;
1320       }
1321     }
1322   }
1323
1324   /* the suffix */
1325   if (idecode_expand_semantics)
1326     lf_print_insn_bits(file, expanded_bits);
1327 }
1328
1329
1330 static void
1331 lf_print_idecode_table(lf *file,
1332                        insn_table *entry)
1333 {
1334   int can_assume_leaf;
1335   opcode_rules *opcode_rule;
1336
1337   /* have a look at the rule table, if all table rules follow all
1338      switch rules, I can assume that all end points are leaves */
1339   opcode_rule = opcode_table;
1340   while (opcode_rule != NULL
1341          && opcode_rule->use_switch)
1342     opcode_rule = opcode_rule->next;
1343   while (opcode_rule != NULL
1344          && opcode_rule->use_switch
1345          && opcode_rule->special_rule)
1346     opcode_rule = opcode_rule->next;
1347   can_assume_leaf = opcode_rule == NULL;
1348
1349   lf_printf(file, "{\n");
1350   lf_indent(file, +2);
1351   {
1352     lf_printf(file, "idecode_table_entry *table = ");
1353     lf_print_table_name(file, entry);
1354     lf_printf(file, ";\n");
1355     lf_printf(file, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1356               i2target(hi_bit_nr, entry->opcode->first),
1357               i2target(hi_bit_nr, entry->opcode->last));
1358     lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
1359     lf_printf(file, "while (1) {\n");
1360     lf_indent(file, +2);
1361     {
1362       lf_printf(file, "/* nonzero mask -> another table */\n");
1363       lf_printf(file, "while (table_entry->mask != 0) {\n");
1364       lf_indent(file, +2);
1365       {
1366         lf_printf(file, "table = ((idecode_table_entry*)\n");
1367         lf_printf(file, "         table_entry->function_or_table);\n");
1368         lf_printf(file, "opcode = ((instruction & table_entry->mask)\n");
1369         lf_printf(file, "          >> table_entry->shift);\n");
1370         lf_printf(file, "table_entry = table + opcode;\n");
1371       }
1372       lf_indent(file, -2);
1373       lf_printf(file, "}\n");
1374       lf_printf(file, "ASSERT(table_entry->mask == 0);\n");
1375       if (can_assume_leaf)
1376         lf_printf(file, "ASSERT(table_entry->shift == 0);\n");
1377       else {
1378         lf_printf(file, "if (table_entry->shift == 0)\n");
1379         lf_indent(file, +2);
1380       }
1381       if (idecode_cache) {
1382         lf_printf(file, "return (((idecode_crack*)\n");
1383         lf_printf(file, "         table_entry->function_or_table)\n");
1384         lf_printf(file, "        (%s));\n", cache_idecode_actual);
1385       }
1386       else {
1387         lf_printf(file, "return (((idecode_semantic*)\n");
1388         lf_printf(file, "         table_entry->function_or_table)\n");
1389         lf_printf(file, "        (%s));\n", semantic_actual);
1390       }
1391       if (!can_assume_leaf) {
1392         lf_indent(file, -2);
1393         lf_printf(file, "/* must be a boolean */\n");
1394         lf_printf(file, "opcode = (instruction & table_entry->shift) != 0;\n");
1395         lf_printf(file, "table = ((idecode_table_entry*)\n");
1396         lf_printf(file, "         table_entry->function_or_table);\n");
1397         lf_printf(file, "table_entry = table + opcode;\n");
1398       }
1399     }
1400     lf_indent(file, -2);
1401     lf_printf(file, "}\n");
1402   }
1403   lf_indent(file, -2);
1404   lf_printf(file, "}\n");
1405 }
1406
1407
1408 static void
1409 lf_print_my_prefix(lf *file,
1410                    table_entry *file_entry,
1411                    int idecode)
1412 {
1413   lf_printf(file, "const char *const my_prefix = \n");
1414   lf_printf(file, "  \"%s:%s:%s:%d\";\n",
1415             filter_filename (file_entry->file_name),
1416             (idecode ? "idecode" : "semantics"),
1417             file_entry->fields[insn_name],
1418             file_entry->line_nr);
1419 }
1420
1421
1422 static void
1423 lf_print_ptrace(lf *file,
1424                 int idecode)
1425 {
1426   lf_printf(file, "\n");
1427   lf_printf(file, "ITRACE(trace_%s, (\"\\n\"));\n",
1428             (idecode ? "idecode" : "semantics"));
1429 }
1430
1431
1432 /****************************************************************/
1433
1434 typedef void leaf_handler
1435 (insn_table *entry,
1436  void *data,
1437  int depth);
1438 typedef void padding_handler
1439 (insn_table *table,
1440  void *data,
1441  int depth,
1442  int opcode_nr);
1443
1444
1445 static void
1446 insn_table_traverse_tree(insn_table *table,
1447                          void *data,
1448                          int depth,
1449                          leaf_handler *start,
1450                          leaf_handler *leaf,
1451                          leaf_handler *end,
1452                          padding_handler *padding)
1453 {
1454   insn_table *entry;
1455   int entry_nr;
1456   
1457   ASSERT(table != NULL
1458          && table->opcode != NULL
1459          && table->nr_entries > 0
1460          && table->entries != 0);
1461
1462   if (start != NULL && depth >= 0)
1463     start(table, data, depth);
1464
1465   for (entry_nr = 0, entry = table->entries;
1466        entry_nr < (table->opcode->is_boolean
1467                    ? 2
1468                    : (1 << (table->opcode->last - table->opcode->first + 1)));
1469        entry_nr ++) {
1470     if (entry == NULL
1471         || (!table->opcode->is_boolean
1472             && entry_nr < entry->opcode_nr)) {
1473       if (padding != NULL && depth >= 0)
1474         padding(table, data, depth, entry_nr);
1475     }
1476     else {
1477       ASSERT(entry != NULL && (entry->opcode_nr == entry_nr
1478                                || table->opcode->is_boolean));
1479       if (entry->opcode != NULL && depth != 0) {
1480         insn_table_traverse_tree(entry, data, depth+1,
1481                                  start, leaf, end, padding);
1482       }
1483       else if (depth >= 0) {
1484         if (leaf != NULL)
1485           leaf(entry, data, depth);
1486       }
1487       entry = entry->sibling;
1488     }
1489   }
1490   if (end != NULL && depth >= 0)
1491     end(table, data, depth);
1492 }
1493
1494
1495 typedef void function_handler
1496 (insn_table *table,
1497  void *data,
1498  table_entry *function);
1499
1500 static void
1501 insn_table_traverse_function(insn_table *table,
1502                              void *data,
1503                              function_handler *leaf)
1504 {
1505   insn *function;
1506   for (function = table->functions;
1507        function != NULL;
1508        function = function->next) {
1509     leaf(table, data, function->file_entry);
1510   }
1511 }
1512
1513
1514 typedef void insn_handler
1515 (insn_table *table,
1516  void *data,
1517  insn *instruction);
1518
1519 static void
1520 insn_table_traverse_insn(insn_table *table,
1521                          void *data,
1522                          insn_handler *leaf)
1523 {
1524   insn *instruction;
1525   for (instruction = table->insns;
1526        instruction != NULL;
1527        instruction = instruction->next) {
1528     leaf(table, data, instruction);
1529   }
1530 }
1531
1532
1533 static void
1534 update_depth(insn_table *entry,
1535              void *data,
1536              int depth)
1537 {
1538   int *max_depth = (int*)data;
1539   if (*max_depth < depth)
1540     *max_depth = depth;
1541 }
1542
1543
1544 static int
1545 insn_table_depth(insn_table *table)
1546 {
1547   int depth = 0;
1548   insn_table_traverse_tree(table,
1549                            &depth,
1550                            1,
1551                            NULL, /*start*/
1552                            update_depth,
1553                            NULL, /*end*/
1554                            NULL); /*padding*/
1555   return depth;
1556 }
1557
1558
1559 /****************************************************************/
1560
1561 static void
1562 dump_traverse_start(insn_table *table,
1563                     void *data,
1564                     int depth)
1565 {
1566   dumpf(depth*2, "(%d\n", table->opcode_nr);
1567 }
1568
1569 static void
1570 dump_traverse_leaf(insn_table *entry,
1571                    void *data,
1572                    int depth)
1573 {
1574   ASSERT(entry->nr_entries == 0
1575          && entry->nr_insn == 1
1576          && entry->opcode == NULL);
1577   dumpf(depth*2, ".%d %s\n", entry->opcode_nr,
1578         entry->insns->file_entry->fields[insn_format]);
1579 }
1580
1581 static void
1582 dump_traverse_end(insn_table *table,
1583                   void *data,
1584                   int depth)
1585 {
1586   dumpf(depth*2, ")\n");
1587 }
1588
1589 static void
1590 dump_traverse_padding(insn_table *table,
1591                       void *data,
1592                       int depth,
1593                       int opcode_nr)
1594 {
1595   dumpf(depth*2, ".<%d>\n", opcode_nr);
1596 }
1597
1598
1599 static void
1600 dump_traverse(insn_table *table)
1601 {
1602   insn_table_traverse_tree(table, NULL, 1,
1603                            dump_traverse_start,
1604                            dump_traverse_leaf,
1605                            dump_traverse_end,
1606                            dump_traverse_padding);
1607 }
1608
1609
1610 /****************************************************************/
1611
1612
1613 static void
1614 lf_print_semantic_function_header(lf *file,
1615                                   char *basename,
1616                                   insn_bits *expanded_bits,
1617                                   int is_function_definition,
1618                                   int is_inline_function)
1619 {
1620   lf_printf(file, "\n");
1621   lf_printf(file, "STATIC_SEMANTICS unsigned_word ");
1622   lf_print_function_name(file,
1623                          basename,
1624                          expanded_bits,
1625                          function_name_prefix_semantics);
1626   lf_printf(file, "\n(%s)", 
1627             (idecode_cache ? cache_semantic_formal : semantic_formal));
1628   if (!is_function_definition)
1629     lf_printf(file, ";");
1630   lf_printf(file, "\n");
1631 }
1632
1633
1634 static void
1635 semantics_h_leaf(insn_table *entry,
1636                  void *data,
1637                  int depth)
1638 {
1639   lf *file = (lf*)data;
1640   ASSERT(entry->nr_insn == 1);
1641   lf_print_semantic_function_header(file,
1642                                     entry->insns->file_entry->fields[insn_name],
1643                                     entry->expanded_bits,
1644                                     0/* isnt function definition*/,
1645                                     !idecode_cache && entry->parent->opcode_rule->use_switch);
1646 }
1647
1648 static void
1649 semantics_h_insn(insn_table *entry,
1650                  void *data,
1651                  insn *instruction)
1652 {
1653   lf *file = (lf*)data;
1654   lf_print_semantic_function_header(file,
1655                                     instruction->file_entry->fields[insn_name],
1656                                     NULL,
1657                                     0/*isnt function definition*/,
1658                                     0/*isnt inline function*/);
1659 }
1660
1661 static void
1662 semantics_h_function(insn_table *entry,
1663                      void *data,
1664                      table_entry *function)
1665 {
1666   lf *file = (lf*)data;
1667   if (function->fields[function_type] == NULL
1668       || function->fields[function_type][0] == '\0') {
1669     lf_print_semantic_function_header(file,
1670                                       function->fields[function_name],
1671                                       NULL,
1672                                       0/*isnt function definition*/,
1673                                       1/*is inline function*/);
1674   }
1675   else {
1676     lf_printf(file, "\n");
1677     lf_printf(file, "INLINE_SEMANTICS %s %s\n(%s);\n",
1678               function->fields[function_type],
1679               function->fields[function_name],
1680               function->fields[function_param]);
1681   }
1682 }
1683
1684
1685 static void 
1686 gen_semantics_h(insn_table *table, lf *file)
1687 {
1688
1689   lf_print_copyleft(file);
1690   lf_printf(file, "\n");
1691   lf_printf(file, "#ifndef _SEMANTICS_H_\n");
1692   lf_printf(file, "#define _SEMANTICS_H_\n");
1693   lf_printf(file, "\n");
1694   lf_printf(file, "#ifndef INLINE_SEMANTICS\n");
1695   lf_printf(file, "#define INLINE_SEMANTICS\n");
1696   lf_printf(file, "#endif\n");
1697   lf_printf(file, "\n");
1698   lf_printf(file, "#ifndef STATIC_SEMANTICS\n");
1699   lf_printf(file, "#define STATIC_SEMANTICS\n");
1700   lf_printf(file, "#endif\n");
1701   lf_printf(file, "\n");
1702   lf_printf(file, "\n");
1703
1704   /* output a declaration for all functions */
1705   insn_table_traverse_function(table,
1706                                file,
1707                                semantics_h_function);
1708
1709   /* output a declaration for all instructions */
1710   if (idecode_expand_semantics)
1711     insn_table_traverse_tree(table,
1712                              file,
1713                              1,
1714                              NULL, /* start */
1715                              semantics_h_leaf, /* leaf */
1716                              NULL, /* end */
1717                              NULL); /* padding */
1718   else
1719     insn_table_traverse_insn(table,
1720                              file,
1721                              semantics_h_insn);
1722
1723   lf_printf(file, "\n");
1724   lf_printf(file, "#endif /* _SEMANTICS_H_ */\n");
1725
1726 }
1727
1728 /****************************************************************/
1729
1730 typedef struct _icache_tree icache_tree;
1731 struct _icache_tree {
1732   char *name;
1733   icache_tree *next;
1734   icache_tree *children;
1735 };
1736
1737 static icache_tree *
1738 icache_tree_insert(icache_tree *tree,
1739                    char *name)
1740 {
1741   icache_tree *new_tree;
1742   /* find it */
1743   icache_tree **ptr_to_cur_tree = &tree->children;
1744   icache_tree *cur_tree = *ptr_to_cur_tree;
1745   while (cur_tree != NULL
1746          && strcmp(cur_tree->name, name) < 0) {
1747     ptr_to_cur_tree = &cur_tree->next;
1748     cur_tree = *ptr_to_cur_tree;
1749   }
1750   ASSERT(cur_tree == NULL
1751          || strcmp(cur_tree->name, name) >= 0);
1752   /* already in the tree */
1753   if (cur_tree != NULL
1754       && strcmp(cur_tree->name, name) == 0)
1755     return cur_tree;
1756   /* missing, insert it */
1757   ASSERT(cur_tree == NULL
1758          || strcmp(cur_tree->name, name) > 0);
1759   new_tree = ZALLOC(icache_tree);
1760   new_tree->name = name;
1761   new_tree->next = cur_tree;
1762   *ptr_to_cur_tree = new_tree;
1763   return new_tree;
1764 }
1765
1766
1767 static icache_tree *
1768 insn_table_cache_fields(insn_table *table)
1769 {
1770   icache_tree *tree = ZALLOC(icache_tree);
1771   insn *instruction;
1772   for (instruction = table->insns;
1773        instruction != NULL;
1774        instruction = instruction->next) {
1775     insn_field *field;
1776     icache_tree *form =
1777       icache_tree_insert(tree,
1778                          instruction->file_entry->fields[insn_form]);
1779     for (field = instruction->fields->first;
1780          field != NULL;
1781          field = field->next) {
1782       if (field->is_string)
1783         icache_tree_insert(form, field->val_string);
1784     }
1785   }
1786   return tree;
1787 }
1788
1789
1790
1791 static void
1792 gen_icache_h(icache_tree *tree,
1793              lf *file)
1794 {
1795   lf_print_copyleft(file);
1796   lf_printf(file, "\n");
1797   lf_printf(file, "#ifndef _ICACHE_H_\n");
1798   lf_printf(file, "#define _ICACHE_H_\n");
1799   lf_printf(file, "\n");
1800   lf_printf(file, "#ifndef INLINE_ICACHE\n");
1801   lf_printf(file, "#define INLINE_ICACHE\n");
1802   lf_printf(file, "#endif\n");
1803   lf_printf(file, "\n");
1804
1805   lf_printf(file, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1806             idecode_cache);
1807   lf_printf(file, "\n");
1808
1809   /* create an instruction cache if being used */
1810   if (idecode_cache) {
1811     icache_tree *form;
1812     lf_printf(file, "typedef struct _idecode_cache {\n");
1813     lf_printf(file, "  unsigned_word address;\n");
1814     lf_printf(file, "  void *semantic;\n");
1815     lf_printf(file, "  union {\n");
1816     for (form = tree->children;
1817          form != NULL;
1818          form = form->next) {
1819       icache_tree *field;
1820       lf_printf(file, "    struct {\n");
1821       for (field = form->children;
1822            field != NULL;
1823            field = field->next) {
1824         cache_rules *cache_rule;
1825         int found_rule = 0;
1826         for (cache_rule = cache_table;
1827              cache_rule != NULL;
1828              cache_rule = cache_rule->next) {
1829           if (strcmp(field->name, cache_rule->old_name) == 0) {
1830             found_rule = 1;
1831             if (cache_rule->new_name != NULL)
1832               lf_printf(file, "      %s %s; /* %s */\n",
1833                         (cache_rule->type == NULL
1834                          ? "unsigned" 
1835                          : cache_rule->type),
1836                         cache_rule->new_name,
1837                         cache_rule->old_name);
1838           }
1839         }
1840         if (!found_rule)
1841           lf_printf(file, "      unsigned %s;\n", field->name);
1842       }
1843       lf_printf(file, "    } %s;\n", form->name);
1844     }
1845     lf_printf(file, "  } crack;\n");
1846     lf_printf(file, "} idecode_cache;\n");
1847   }
1848   else {
1849     /* alernativly, since no cache, #define the fields to be
1850        extractions from the instruction variable */
1851     cache_rules *cache_rule;
1852     lf_printf(file, "\n");
1853     for (cache_rule = cache_table;
1854          cache_rule != NULL;
1855          cache_rule = cache_rule->next) {
1856       if (cache_rule->expression != NULL
1857           && strlen(cache_rule->expression) > 0)
1858         lf_printf(file, "#define %s %s\n",
1859                   cache_rule->new_name, cache_rule->expression);
1860     }
1861   }
1862
1863   lf_printf(file, "\n");
1864   lf_printf(file, "#endif /* _ICACHE_H_ */\n");
1865 }
1866
1867
1868
1869
1870 /****************************************************************/
1871
1872
1873 static void
1874 lf_print_c_extraction(lf *file,
1875                       insn *instruction,
1876                       char *field_name,
1877                       char *field_type,
1878                       char *field_expression,
1879                       insn_field *cur_field,
1880                       insn_bits *bits,
1881                       int get_value_from_cache,
1882                       int put_value_in_cache)
1883 {
1884   ASSERT(field_name != NULL);
1885   if (bits != NULL
1886       && (!bits->opcode->is_boolean || bits->value == 0)
1887       && strcmp(field_name, cur_field->val_string) == 0) {
1888     ASSERT(bits->field == cur_field);
1889     ASSERT(field_type == NULL);
1890     table_entry_lf_c_line_nr(file, instruction->file_entry);
1891     lf_printf(file, "const unsigned %s = ",
1892               field_name);
1893     if (bits->opcode->last < bits->field->last)
1894       lf_printf(file, "%d;\n",
1895                 bits->value << (bits->field->last - bits->opcode->last));
1896     else
1897       lf_printf(file, "%d;\n", bits->value);
1898   }
1899   else {
1900     /* put the field in the local variable */
1901     table_entry_lf_c_line_nr(file, instruction->file_entry);
1902     lf_printf(file, "%s const %s = ",
1903               field_type == NULL ? "unsigned" : field_type,
1904               field_name);
1905     /* getting it from the cache */
1906     if (get_value_from_cache || put_value_in_cache) {
1907       lf_printf(file, "cache_entry->crack.%s.%s",
1908                 instruction->file_entry->fields[insn_form],
1909                 field_name);
1910       if (put_value_in_cache) /* also put it in the cache? */
1911         lf_printf(file, " = ");
1912     }
1913     if (!get_value_from_cache) {
1914       if (strcmp(field_name, cur_field->val_string) == 0)
1915         lf_printf(file, "EXTRACTED32(instruction, %d, %d)",
1916                   i2target(hi_bit_nr, cur_field->first),
1917                   i2target(hi_bit_nr, cur_field->last));
1918       else if (field_expression != NULL)
1919         lf_printf(file, "%s", field_expression);
1920       else
1921         lf_printf(file, "eval_%s", field_name);
1922     }
1923     lf_printf(file, ";\n");
1924   }
1925 }
1926
1927
1928 static void
1929 lf_print_c_extractions(lf *file,
1930                        insn *instruction,
1931                        insn_bits *expanded_bits,
1932                        int get_value_from_cache,
1933                        int put_value_in_cache)
1934 {
1935   insn_field *cur_field;
1936
1937   /* extract instruction fields */
1938   lf_printf(file, "/* extraction: %s */\n",
1939             instruction->file_entry->fields[insn_format]);
1940
1941   for (cur_field = instruction->fields->first;
1942        cur_field->first < insn_size;
1943        cur_field = cur_field->next) {
1944     if (cur_field->is_string) {
1945       insn_bits *bits;
1946       int found_rule = 0;
1947       /* find any corresponding value */
1948       for (bits = expanded_bits;
1949            bits != NULL;
1950            bits = bits->last) {
1951         if (bits->field == cur_field)
1952           break;
1953       }
1954       /* try the cache rule table for what to do */
1955       if (get_value_from_cache || put_value_in_cache) {      
1956         cache_rules *cache_rule;
1957         for (cache_rule = cache_table;
1958              cache_rule != NULL;
1959              cache_rule = cache_rule->next) {
1960           if (strcmp(cur_field->val_string, cache_rule->old_name) == 0) {
1961             found_rule = 1;
1962             if (cache_rule->valid > 1 && put_value_in_cache)
1963               lf_print_c_extraction(file,
1964                                     instruction,
1965                                     cache_rule->new_name,
1966                                     cache_rule->type,
1967                                     cache_rule->expression,
1968                                     cur_field,
1969                                     bits,
1970                                     0,
1971                                     0);
1972             else if (cache_rule->valid == 1)
1973               lf_print_c_extraction(file,
1974                                     instruction,
1975                                     cache_rule->new_name,
1976                                     cache_rule->type,
1977                                     cache_rule->expression,
1978                                     cur_field,
1979                                     bits,
1980                                     get_value_from_cache,
1981                                     put_value_in_cache);
1982           }
1983         }
1984       }
1985       if (found_rule == 0)
1986         lf_print_c_extraction(file,
1987                               instruction,
1988                               cur_field->val_string,
1989                               0,
1990                               0,
1991                               cur_field,
1992                               bits,
1993                               get_value_from_cache,
1994                               put_value_in_cache);
1995       /* if any (XXX == 0), output a corresponding test */
1996       if (instruction->file_entry->annex != NULL) {
1997         char *field_name = cur_field->val_string;
1998         char *is_0_ptr = instruction->file_entry->annex;
1999         int field_len = strlen(field_name);
2000         if (strlen(is_0_ptr) >= (strlen("_is_0") + field_len)) {
2001           is_0_ptr += field_len;
2002           while ((is_0_ptr = strstr(is_0_ptr, "_is_0")) != NULL) {
2003             if (strncmp(is_0_ptr - field_len, field_name, field_len) == 0
2004                 && !isalpha(is_0_ptr[ - field_len - 1])) {
2005               table_entry_lf_c_line_nr(file, instruction->file_entry);
2006               lf_printf(file, "const unsigned %s_is_0 = (", field_name);
2007               if (bits != NULL)
2008                 lf_printf(file, "%d", bits->value);
2009               else
2010                 lf_printf(file, "%s", field_name);
2011               lf_printf(file, " == 0);\n");
2012               break;
2013             }
2014             is_0_ptr += strlen("_is_0");
2015           }
2016         }
2017       }
2018       /* any thing else ... */
2019     }
2020   }
2021   lf_print_lf_c_line_nr(file);
2022 }
2023
2024
2025 static void
2026 lf_print_idecode_illegal(lf *file)
2027 {
2028   if (idecode_cache)
2029     lf_printf(file, "return idecode_illegal(%s);\n", cache_idecode_actual);
2030   else
2031     lf_printf(file, "return semantic_illegal(%s);\n", semantic_actual);
2032 }
2033
2034
2035 static void
2036 lf_print_idecode_floating_point_unavailable(lf *file)
2037 {
2038   if (idecode_cache)
2039     lf_printf(file, "return idecode_floating_point_unavailable(%s);\n",
2040               cache_idecode_actual);
2041   else
2042     lf_printf(file, "return semantic_floating_point_unavailable(%s);\n",
2043               semantic_actual);
2044 }
2045
2046
2047 /* Output code to do any final checks on the decoded instruction.
2048    This includes things like verifying any on decoded fields have the
2049    correct value and checking that (for floating point) floating point
2050    hardware isn't disabled */
2051
2052 static void
2053 lf_print_c_validate(lf *file,
2054                     insn *instruction,
2055                     opcode_field *opcodes)
2056 {
2057   /* Validate: unchecked instruction fields
2058
2059      If any constant fields in the instruction were not checked by the
2060      idecode tables, output code to check that they have the correct
2061      value here */
2062   { 
2063     unsigned check_mask = 0;
2064     unsigned check_val = 0;
2065     insn_field *field;
2066     opcode_field *opcode;
2067
2068     /* form check_mask/check_val containing what needs to be checked
2069        in the instruction */
2070     for (field = instruction->fields->first;
2071          field->first < insn_size;
2072          field = field->next) {
2073
2074       check_mask <<= field->width;
2075       check_val <<= field->width;
2076
2077       /* is it a constant that could need validating? */
2078       if (!field->is_int && !field->is_slash)
2079         continue;
2080
2081       /* has it been checked by a table? */
2082       for (opcode = opcodes; opcode != NULL; opcode = opcode->parent) {
2083         if (field->first >= opcode->first
2084             && field->last <= opcode->last)
2085           break;
2086       }
2087       if (opcode != NULL)
2088         continue;
2089
2090       check_mask |= (1 << field->width)-1;
2091       check_val |= field->val_int;
2092     }
2093
2094     /* if any bits not checked by opcode tables, output code to check them */
2095     if (check_mask) {
2096       lf_printf(file, "\n");
2097       lf_printf(file, "/* validate: %s */\n",
2098                 instruction->file_entry->fields[insn_format]);
2099       lf_printf(file, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
2100                 check_mask, check_val);
2101       lf_indent(file, +2);
2102       lf_print_idecode_illegal(file);
2103       lf_indent(file, -2);
2104     }
2105   }
2106
2107   /* Validate floating point hardware
2108
2109      If the simulator is being built with out floating point hardware
2110      (different to it being disabled in the MSR) then floating point
2111      instructions are invalid */
2112   {
2113     if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2114       lf_printf(file, "\n");
2115       lf_printf(file, "/* Validate: FP hardware exists */\n");
2116       lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
2117       lf_indent(file, +2);
2118       lf_print_idecode_illegal(file);
2119       lf_indent(file, -2);
2120     }
2121   }
2122
2123   /* Validate: Floating Point available
2124
2125      If floating point is not available, we enter a floating point
2126      unavailable interrupt into the cache instead of the instruction
2127      proper.
2128
2129      The PowerPC spec requires a CSI after MSR[FP] is changed and when
2130      ever a CSI occures we flush the instruction cache. */
2131
2132   {
2133     if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2134       lf_printf(file, "\n");
2135       lf_printf(file, "/* Validate: FP available according to MSR[FP] */\n");
2136       lf_printf(file, "if (!IS_FP_AVAILABLE(processor))\n");
2137       lf_indent(file, +2);
2138       lf_print_idecode_floating_point_unavailable(file);
2139       lf_indent(file, -2);
2140     }
2141   }
2142 }
2143
2144
2145 static void
2146 lf_print_c_cracker(lf *file,
2147                    insn *instruction,
2148                    insn_bits *expanded_bits,
2149                    opcode_field *opcodes)
2150 {
2151
2152   /* function header */
2153   lf_printf(file, "{\n");
2154   lf_indent(file, +2);
2155
2156   lf_print_my_prefix(file,
2157                      instruction->file_entry,
2158                      1/*putting-value-in-cache*/);
2159
2160   lf_print_ptrace(file,
2161                   1/*putting-value-in-cache*/);
2162
2163   lf_print_c_validate(file, instruction, opcodes);
2164
2165   lf_printf(file, "\n");
2166   lf_printf(file, "{\n");
2167   lf_indent(file, +2);
2168   lf_print_c_extractions(file,
2169                          instruction,
2170                          expanded_bits,
2171                          0/*get_value_from_cache*/,
2172                          1/*put_value_in_cache*/);
2173   lf_indent(file, -2);
2174   lf_printf(file, "}\n");
2175
2176   /* return the function propper (main sorts this one out) */
2177   lf_printf(file, "\n");
2178   lf_printf(file, "/* semantic routine */\n");
2179   table_entry_lf_c_line_nr(file, instruction->file_entry);
2180   lf_printf(file, "return ");
2181   lf_print_function_name(file,
2182                          instruction->file_entry->fields[insn_name],
2183                          expanded_bits,
2184                          function_name_prefix_semantics);
2185   lf_printf(file, ";\n");
2186
2187   lf_print_lf_c_line_nr(file);
2188   lf_indent(file, -2);
2189   lf_printf(file, "}\n");
2190 }
2191
2192
2193 static void
2194 lf_print_c_semantic(lf *file,
2195                     insn *instruction,
2196                     insn_bits *expanded_bits,
2197                     opcode_field *opcodes)
2198 {
2199
2200   lf_printf(file, "{\n");
2201   lf_indent(file, +2);
2202
2203   lf_print_my_prefix(file,
2204                      instruction->file_entry,
2205                      0/*not putting value in cache*/);
2206   lf_printf(file, "unsigned_word nia = cia + %d;\n", insn_size / 8);
2207
2208   lf_printf(file, "\n");
2209   lf_print_c_extractions(file,
2210                          instruction,
2211                          expanded_bits,
2212                          idecode_cache/*get_value_from_cache*/,
2213                          0/*put_value_in_cache*/);
2214
2215   lf_print_ptrace(file,
2216                   0/*put_value_in_cache*/);
2217
2218   /* validate the instruction, if a cache this has already been done */
2219   if (!idecode_cache)
2220     lf_print_c_validate(file, instruction, opcodes);
2221
2222   /* generate the profileing call - this is delayed until after the
2223      instruction has been verified */
2224   lf_printf(file, "\n");
2225   lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
2226   lf_printf(file, "  mon_issue(");
2227   lf_print_function_name(file,
2228                          instruction->file_entry->fields[insn_name],
2229                          NULL,
2230                          function_name_prefix_itable);
2231   lf_printf(file, ", processor, cia);\n");
2232
2233   /* generate the code (or at least something */
2234   if (instruction->file_entry->annex != NULL) {
2235     /* true code */
2236     lf_printf(file, "\n");
2237     table_entry_lf_c_line_nr(file, instruction->file_entry);
2238     lf_printf(file, "{\n");
2239     lf_indent(file, +2);
2240     lf_print_c_code(file, instruction->file_entry->annex);
2241     lf_indent(file, -2);
2242     lf_printf(file, "}\n");
2243     lf_print_lf_c_line_nr(file);
2244   }
2245   else if (it_is("nop", instruction->file_entry->fields[insn_flags])) {
2246     lf_print_lf_c_line_nr(file);
2247   }
2248   else if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2249     /* unimplemented floating point instruction - call for assistance */
2250     lf_printf(file, "\n");
2251     lf_printf(file, "/* unimplemented floating point instruction - call for assistance */\n");
2252     table_entry_lf_c_line_nr(file, instruction->file_entry);
2253     lf_putstr(file, "floating_point_assist_interrupt(processor, cia);\n");
2254     lf_print_lf_c_line_nr(file);
2255   }
2256   else {
2257     /* abort so it is implemented now */
2258     table_entry_lf_c_line_nr(file, instruction->file_entry);
2259     lf_putstr(file, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2260     lf_print_lf_c_line_nr(file);
2261     lf_printf(file, "\n");
2262   }
2263
2264   /* the function footer */
2265   lf_printf(file, "return nia;\n");
2266   lf_indent(file, -2);
2267   lf_printf(file, "}\n");
2268 }
2269
2270 static void
2271 lf_print_c_semantic_function_header(lf *file,
2272                                     char *basename,
2273                                     insn_bits *expanded_bits)
2274 {
2275   lf_printf(file, "\n");
2276   lf_printf(file, "STATIC_SEMANTICS unsigned_word\n");
2277   lf_print_function_name(file,
2278                          basename,
2279                          expanded_bits,
2280                          function_name_prefix_semantics);
2281   lf_printf(file, "\n(%s)\n",
2282             (idecode_cache ? cache_semantic_formal : semantic_formal));
2283 }
2284
2285 static void
2286 lf_print_c_semantic_function(lf *file,
2287                              insn *instruction,
2288                              insn_bits *expanded_bits,
2289                              opcode_field *opcodes,
2290                              int is_inline_function)
2291 {
2292
2293   /* build the semantic routine to execute the instruction */
2294   lf_print_semantic_function_header(file,
2295                                     instruction->file_entry->fields[insn_name],
2296                                     expanded_bits,
2297                                     1/*is-function-definition*/,
2298                                     is_inline_function);
2299   lf_print_c_semantic(file,
2300                       instruction,
2301                       expanded_bits,
2302                       opcodes);
2303 }
2304
2305
2306 static void
2307 semantics_c_leaf(insn_table *entry,
2308                  void *data,
2309                  int depth)
2310 {
2311   lf *file = (lf*)data;
2312   ASSERT(entry->nr_insn == 1
2313          && entry->opcode == NULL
2314          && entry->parent != NULL
2315          && entry->parent->opcode != NULL);
2316   lf_print_c_semantic_function(file,
2317                                entry->insns,
2318                                entry->expanded_bits,
2319                                entry->parent->opcode,
2320                                !idecode_cache && entry->parent->opcode_rule->use_switch);
2321 }
2322
2323 static void
2324 semantics_c_insn(insn_table *table,
2325                  void *data,
2326                  insn *instruction)
2327 {
2328   lf *file = (lf*)data;
2329   lf_print_c_semantic_function(file, instruction,
2330                                NULL, NULL,
2331                                0/*isnt_inline_function*/);
2332 }
2333
2334 static void
2335 semantics_c_function(insn_table *table,
2336                      void *data,
2337                      table_entry *function)
2338 {
2339   lf *file = (lf*)data;
2340   if (function->fields[function_type] == NULL
2341       || function->fields[function_type][0] == '\0') {
2342     lf_print_semantic_function_header(file,
2343                                       function->fields[function_name],
2344                                       NULL,
2345                                       1/*is function definition*/,
2346                                       1/*is inline function*/);
2347   }
2348   else {
2349     lf_printf(file, "\n");
2350     lf_printf(file, "INLINE_SEMANTICS %s\n%s(%s)\n",
2351               function->fields[function_type],
2352               function->fields[function_name],
2353               function->fields[function_param]);
2354   }
2355   table_entry_lf_c_line_nr(file, function);
2356   lf_printf(file, "{\n");
2357   lf_indent(file, +2);
2358   lf_print_c_code(file, function->annex);
2359   lf_indent(file, -2);
2360   lf_printf(file, "}\n");
2361   lf_print_lf_c_line_nr(file);
2362 }
2363
2364
2365
2366 static void 
2367 gen_semantics_c(insn_table *table, lf *file)
2368 {
2369   lf_print_copyleft(file);
2370   lf_printf(file, "\n");
2371   lf_printf(file, "#ifndef _SEMANTICS_C_\n");
2372   lf_printf(file, "#define _SEMANTICS_C_\n");
2373   lf_printf(file, "\n");
2374   lf_printf(file, "#ifndef STATIC_INLINE_SEMANTICS\n");
2375   lf_printf(file, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2376   lf_printf(file, "#endif\n");
2377   lf_printf(file, "\n");
2378   lf_printf(file, "#include \"cpu.h\"\n");
2379   lf_printf(file, "#include \"idecode.h\"\n");
2380   lf_printf(file, "#include \"semantics.h\"\n");
2381   lf_printf(file, "\n");
2382
2383   /* output a definition (c-code) for all functions */
2384   insn_table_traverse_function(table,
2385                                file,
2386                                semantics_c_function);
2387
2388   /* output a definition (c-code) for all instructions */
2389   if (idecode_expand_semantics)
2390     insn_table_traverse_tree(table,
2391                              file,
2392                              1,
2393                              NULL, /* start */
2394                              semantics_c_leaf,
2395                              NULL, /* end */
2396                              NULL); /* padding */
2397   else
2398     insn_table_traverse_insn(table,
2399                              file,
2400                              semantics_c_insn);
2401
2402   lf_printf(file, "\n");
2403   lf_printf(file, "#endif /* _SEMANTICS_C_ */\n");
2404 }
2405
2406
2407 /****************************************************************/
2408
2409 static void
2410 gen_idecode_h(insn_table *table, lf *file)
2411 {
2412   lf_print_copyleft(file);
2413   lf_printf(file, "\n");
2414   lf_printf(file, "#ifndef _IDECODE_H_\n");
2415   lf_printf(file, "#define _IDECODE_H_\n");
2416   lf_printf(file, "\n");
2417   lf_printf(file, "#ifndef INLINE_IDECODE\n");
2418   lf_printf(file, "#define INLINE_IDECODE\n");
2419   lf_printf(file, "#endif\n");
2420   lf_printf(file, "\n");
2421   lf_printf(file, "#include \"idecode_expression.h\"\n");
2422   lf_printf(file, "#include \"idecode_fields.h\"\n");
2423   lf_printf(file, "#include \"idecode_branch.h\"\n");
2424   lf_printf(file, "\n");
2425   lf_printf(file, "#include \"icache.h\"\n");
2426   lf_printf(file, "\n");
2427   lf_printf(file, "typedef unsigned_word idecode_semantic\n(%s);\n",
2428             (idecode_cache ? cache_semantic_formal : semantic_formal));
2429   lf_printf(file, "\n");
2430   if (idecode_cache)
2431     lf_printf(file, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2432               cache_idecode_formal);
2433   else
2434     lf_printf(file, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2435               semantic_formal);
2436   lf_printf(file, "\n");
2437   lf_printf(file, "#endif /* _IDECODE_H_ */\n");
2438 }
2439
2440
2441 /****************************************************************/
2442
2443
2444 static void
2445 idecode_table_start(insn_table *table,
2446                     void *data,
2447                     int depth)
2448 {
2449   lf *file = (lf*)data;
2450   ASSERT(depth == 0);
2451   /* start of the table */
2452   if (!table->opcode_rule->use_switch) {
2453     lf_printf(file, "\n");
2454     lf_printf(file, "static idecode_table_entry ");
2455     lf_print_table_name(file, table);
2456     lf_printf(file, "[] = {\n");
2457   }
2458 }
2459
2460 static void
2461 idecode_table_leaf(insn_table *entry,
2462                    void *data,
2463                    int depth)
2464 {
2465   lf *file = (lf*)data;
2466   ASSERT(entry->parent != NULL);
2467   ASSERT(depth == 0);
2468
2469   /* add an entry to the table */
2470   if (!entry->parent->opcode_rule->use_switch) {
2471     if (entry->opcode == NULL) {
2472       /* table leaf entry */
2473       lf_printf(file, "  /*%d*/ { 0, 0, ", entry->opcode_nr);
2474       lf_print_function_name(file,
2475                              entry->insns->file_entry->fields[insn_name],
2476                              entry->expanded_bits,
2477                              (idecode_cache
2478                               ? function_name_prefix_idecode
2479                               : function_name_prefix_semantics));
2480       lf_printf(file, " },\n");
2481     }
2482     else if (entry->opcode_rule->use_switch) {
2483       /* table calling switch statement */
2484       lf_printf(file, "  /*%d*/ { 0, 0, ",
2485                 entry->opcode_nr);
2486       lf_print_table_name(file, entry);
2487       lf_printf(file, " },\n");
2488     }
2489     else {
2490       /* table `calling' another table */
2491       lf_printf(file, "  /*%d*/ { ", entry->opcode_nr);
2492       if (entry->opcode->is_boolean)
2493         lf_printf(file, "MASK32(%d,%d), 0, ",
2494                   i2target(hi_bit_nr, entry->opcode->first),
2495                   i2target(hi_bit_nr, entry->opcode->last));
2496       else
2497         lf_printf(file, "%d, MASK32(%d,%d), ",
2498                   insn_size - entry->opcode->last - 1,
2499                   i2target(hi_bit_nr, entry->opcode->first),
2500                   i2target(hi_bit_nr, entry->opcode->last));
2501       lf_print_table_name(file, entry);
2502       lf_printf(file, " },\n");
2503     }
2504   }
2505 }
2506
2507 static void
2508 idecode_table_end(insn_table *table,
2509                   void *data,
2510                   int depth)
2511 {
2512   lf *file = (lf*)data;
2513   ASSERT(depth == 0);
2514
2515   if (!table->opcode_rule->use_switch) {
2516     lf_printf(file, "};\n");
2517   }
2518 }
2519
2520 static void
2521 idecode_table_padding(insn_table *table,
2522                       void *data,
2523                       int depth,
2524                       int opcode_nr)
2525 {
2526   lf *file = (lf*)data;
2527   ASSERT(depth == 0);
2528
2529   if (!table->opcode_rule->use_switch) {
2530     lf_printf(file, "  /*%d*/ { 0, 0, %s_illegal },\n",
2531               opcode_nr, (idecode_cache ? "idecode" : "semantic"));
2532   }
2533 }
2534
2535
2536 /****************************************************************/
2537
2538
2539 void lf_print_idecode_switch
2540 (lf *file, 
2541  insn_table *table);
2542
2543
2544 static void
2545 idecode_switch_start(insn_table *table,
2546                 void *data,
2547                 int depth)
2548 {
2549   lf *file = (lf*)data;
2550   ASSERT(depth == 0);
2551   ASSERT(table->opcode_rule->use_switch);
2552
2553   lf_printf(file, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2554             i2target(hi_bit_nr, table->opcode->first),
2555             i2target(hi_bit_nr, table->opcode->last));
2556 }
2557
2558
2559 static void
2560 idecode_switch_leaf(insn_table *entry,
2561                     void *data,
2562                     int depth)
2563 {
2564   lf *file = (lf*)data;
2565   ASSERT(entry->parent != NULL);
2566   ASSERT(depth == 0);
2567   ASSERT(entry->parent->opcode_rule->use_switch);
2568   ASSERT(entry->parent->opcode);
2569
2570   if (!entry->parent->opcode->is_boolean
2571       || entry->opcode_nr == 0)
2572     lf_printf(file, "case %d:\n", entry->opcode_nr);
2573   else
2574     lf_printf(file, "default:\n");
2575   lf_indent(file, +2);
2576   {
2577     if (entry->opcode == NULL) {
2578       /* switch calling leaf */
2579       lf_printf(file, "return ");
2580       lf_print_function_name(file,
2581                              entry->insns->file_entry->fields[insn_name],
2582                              entry->expanded_bits,
2583                              (idecode_cache
2584                               ? function_name_prefix_idecode
2585                               : function_name_prefix_semantics));
2586       if (idecode_cache)
2587         lf_printf(file, "(%s);\n", cache_idecode_actual);
2588       else
2589         lf_printf(file, "(%s);\n", semantic_actual);
2590     }
2591     else if (entry->opcode_rule->use_switch) {
2592       /* switch calling switch */
2593       lf_print_idecode_switch(file, entry);
2594     }
2595     else {
2596       /* switch looking up a table */
2597       lf_print_idecode_table(file, entry);
2598     }
2599     lf_printf(file, "break;\n");
2600   }
2601   lf_indent(file, -2);
2602 }
2603
2604
2605 static void
2606 lf_print_idecode_switch_illegal(lf *file)
2607 {
2608   lf_indent(file, +2);
2609   lf_print_idecode_illegal(file);
2610   lf_printf(file, "break;\n");
2611   lf_indent(file, -2);
2612 }
2613
2614 static void
2615 idecode_switch_end(insn_table *table,
2616                    void *data,
2617                    int depth)
2618 {
2619   lf *file = (lf*)data;
2620   ASSERT(depth == 0);
2621   ASSERT(table->opcode_rule->use_switch);
2622   ASSERT(table->opcode);
2623
2624   if (table->opcode_rule->use_switch == 1
2625       && !table->opcode->is_boolean) {
2626     lf_printf(file, "default:\n");
2627     lf_print_idecode_switch_illegal(file);
2628   }
2629   lf_printf(file, "}\n");
2630 }
2631
2632 static void
2633 idecode_switch_padding(insn_table *table,
2634                        void *data,
2635                        int depth,
2636                        int opcode_nr)
2637 {
2638   lf *file = (lf*)data;
2639
2640   ASSERT(depth == 0);
2641   ASSERT(table->opcode_rule->use_switch);
2642
2643   if (table->opcode_rule->use_switch > 1) {
2644     lf_printf(file, "case %d:\n", opcode_nr);
2645     lf_print_idecode_switch_illegal(file);
2646   }
2647 }
2648
2649
2650 void
2651 lf_print_idecode_switch(lf *file, 
2652                         insn_table *table)
2653 {
2654   insn_table_traverse_tree(table,
2655                            file,
2656                            0,
2657                            idecode_switch_start,
2658                            idecode_switch_leaf,
2659                            idecode_switch_end,
2660                            idecode_switch_padding);
2661 }
2662
2663
2664 static void
2665 lf_print_idecode_switch_function_header(lf *file,
2666                                         insn_table *table,
2667                                         int is_function_definition)
2668 {
2669   lf_printf(file, "\n");
2670   lf_printf(file, "static ");
2671   if (idecode_cache)
2672     lf_printf(file, "idecode_semantic *");
2673   else
2674     lf_printf(file, "unsigned_word");
2675   if (is_function_definition)
2676     lf_printf(file, "\n");
2677   else
2678     lf_printf(file, " ");
2679   lf_print_table_name(file, table);
2680   lf_printf(file, "\n(%s)",
2681             (idecode_cache ? cache_idecode_formal : semantic_formal));
2682   if (!is_function_definition)
2683     lf_printf(file, ";");
2684   lf_printf(file, "\n");
2685 }
2686
2687
2688 static void
2689 idecode_declare_if_switch(insn_table *table,
2690                           void *data,
2691                           int depth)
2692 {
2693   lf *file = (lf*)data;
2694
2695   if (table->opcode_rule->use_switch
2696       && table->parent != NULL /* don't declare the top one yet */
2697       && !table->parent->opcode_rule->use_switch) {
2698     lf_print_idecode_switch_function_header(file,
2699                                             table,
2700                                             0/*isnt function definition*/);
2701   }
2702 }
2703
2704
2705 static void
2706 idecode_expand_if_switch(insn_table *table,
2707                          void *data,
2708                          int depth)
2709 {
2710   lf *file = (lf*)data;
2711
2712   if (table->opcode_rule->use_switch
2713       && table->parent != NULL /* don't expand the top one yet */
2714       && !table->parent->opcode_rule->use_switch) {
2715     lf_print_idecode_switch_function_header(file,
2716                                             table,
2717                                             1/*is function definition*/);
2718     lf_printf(file, "{\n");
2719     {
2720       lf_indent(file, +2);
2721       lf_print_idecode_switch(file, table);
2722       lf_indent(file, -2);
2723     }
2724     lf_printf(file, "}\n");
2725   }
2726 }
2727
2728
2729 static void
2730 lf_print_c_cracker_function(lf *file,
2731                             insn *instruction,
2732                             insn_bits *expanded_bits,
2733                             opcode_field *opcodes,
2734                             int is_inline_function)
2735 {
2736   /* if needed, generate code to enter this routine into a cache */
2737   lf_printf(file, "\n");
2738   lf_printf(file, "STATIC_IDECODE idecode_semantic *\n");
2739   lf_print_function_name(file,
2740                          instruction->file_entry->fields[insn_name],
2741                          expanded_bits,
2742                          function_name_prefix_idecode);
2743   lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2744
2745   lf_print_c_cracker(file,
2746                      instruction,
2747                      expanded_bits,
2748                      opcodes);
2749 }
2750
2751 static void
2752 idecode_crack_leaf(insn_table *entry,
2753                    void *data,
2754                    int depth)
2755 {
2756   lf *file = (lf*)data;
2757   ASSERT(entry->nr_insn == 1
2758          && entry->opcode == NULL
2759          && entry->parent != NULL
2760          && entry->parent->opcode != NULL
2761          && entry->parent->opcode_rule != NULL);
2762   lf_print_c_cracker_function(file,
2763                               entry->insns,
2764                               entry->expanded_bits,
2765                               entry->opcode,
2766                               entry->parent->opcode_rule->use_switch);
2767 }
2768
2769 static void
2770 idecode_crack_insn(insn_table *entry,
2771                    void *data,
2772                    insn *instruction)
2773 {
2774   lf *file = (lf*)data;
2775   lf_print_c_cracker_function(file,
2776                               instruction,
2777                               NULL,
2778                               NULL,
2779                               0/*isnt inline function*/);
2780 }
2781
2782 static void
2783 idecode_c_internal_function(insn_table *table,
2784                             void *data,
2785                             table_entry *function)
2786 {
2787   lf *file = (lf*)data;
2788   ASSERT(idecode_cache != 0);
2789   if (it_is("internal", function->fields[insn_flags])) {
2790     lf_printf(file, "\n");
2791     lf_printf(file, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2792     lf_print_function_name(file,
2793                            function->fields[insn_name],
2794                            NULL,
2795                            function_name_prefix_idecode);
2796     lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2797     lf_printf(file, "{\n");
2798     lf_indent(file, +2);
2799     lf_printf(file, "/* semantic routine */\n");
2800     table_entry_lf_c_line_nr(file, function);
2801     lf_printf(file, "return ");
2802     lf_print_function_name(file,
2803                            function->fields[insn_name],
2804                            NULL,
2805                            function_name_prefix_semantics);
2806     lf_printf(file, ";\n");
2807
2808     lf_print_lf_c_line_nr(file);
2809     lf_indent(file, -2);
2810     lf_printf(file, "}\n");
2811   }
2812 }
2813
2814
2815 /****************************************************************/
2816
2817 static void
2818 gen_idecode_c(insn_table *table, lf *file)
2819 {
2820   int depth;
2821
2822   /* the intro */
2823   lf_print_copyleft(file);
2824   lf_printf(file, "\n");
2825   lf_printf(file, "\n");
2826   lf_printf(file, "#ifndef _IDECODE_C_\n");
2827   lf_printf(file, "#define _IDECODE_C_\n");
2828   lf_printf(file, "\n");
2829   lf_printf(file, "#ifndef STATIC_INLINE_IDECODE\n");
2830   lf_printf(file, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2831   lf_printf(file, "#endif\n");
2832   lf_printf(file, "\n");
2833   lf_printf(file, "#ifndef STATIC_IDECODE\n");
2834   lf_printf(file, "#define STATIC_IDECODE\n");
2835   lf_printf(file, "#endif\n");
2836   lf_printf(file, "\n");
2837   lf_printf(file, "#include \"cpu.h\"\n");
2838   lf_printf(file, "#include \"idecode.h\"\n");
2839   lf_printf(file, "#include \"semantics.h\"\n");
2840   lf_printf(file, "\n");
2841   lf_printf(file, "\n");
2842   lf_printf(file, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2843             (idecode_cache ? cache_idecode_formal : semantic_formal));
2844   lf_printf(file, "\n");
2845   lf_printf(file, "typedef struct _idecode_table_entry {\n");
2846   lf_printf(file, "  unsigned shift;\n");
2847   lf_printf(file, "  unsigned mask;\n");
2848   lf_printf(file, "  void *function_or_table;\n");
2849   lf_printf(file, "} idecode_table_entry;\n");
2850   lf_printf(file, "\n");
2851   lf_printf(file, "\n");
2852
2853   /* output `internal' invalid/floating-point unavailable functions
2854      where needed */
2855   if (idecode_cache) {
2856     insn_table_traverse_function(table,
2857                                  file,
2858                                  idecode_c_internal_function);
2859   }
2860
2861   /* output cracking functions where needed */
2862   if (idecode_cache) {
2863     if (idecode_expand_semantics)
2864       insn_table_traverse_tree(table,
2865                                file,
2866                                1,
2867                                NULL,
2868                                idecode_crack_leaf,
2869                                NULL,
2870                                NULL);
2871     else
2872       insn_table_traverse_insn(table,
2873                                file,
2874                                idecode_crack_insn);
2875   }
2876
2877   /* output switch function declarations where needed by tables */
2878   insn_table_traverse_tree(table,
2879                            file,
2880                            1,
2881                            idecode_declare_if_switch, /* START */
2882                            NULL, NULL, NULL);
2883
2884   /* output tables where needed */
2885   for (depth = insn_table_depth(table);
2886        depth > 0;
2887        depth--) {
2888     insn_table_traverse_tree(table,
2889                              file,
2890                              1-depth,
2891                              idecode_table_start,
2892                              idecode_table_leaf,
2893                              idecode_table_end,
2894                              idecode_table_padding);
2895   }
2896
2897   /* output switch functions where needed */
2898   insn_table_traverse_tree(table,
2899                            file,
2900                            1,
2901                            idecode_expand_if_switch, /* START */
2902                            NULL, NULL, NULL);
2903
2904   /* output the main idecode routine */
2905   lf_printf(file, "\n");
2906   if (idecode_cache)
2907     lf_printf(file, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2908               cache_idecode_formal);
2909   else
2910     lf_printf(file, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2911               semantic_formal);
2912   lf_printf(file, "{\n");
2913   lf_indent(file, +2);
2914   if (table->opcode_rule->use_switch)
2915     lf_print_idecode_switch(file, table);
2916   else
2917     lf_print_idecode_table(file, table);
2918   lf_indent(file, -2);
2919   lf_printf(file, "}\n");
2920   lf_printf(file, "\n");
2921   lf_printf(file, "#endif /* _IDECODE_C_ */\n");
2922 }
2923
2924
2925 /****************************************************************/
2926
2927 static void
2928 itable_h_insn(insn_table *entry,
2929               void *data,
2930               insn *instruction)
2931 {
2932   lf *file = (lf*)data;
2933   lf_printf(file, "  ");
2934   lf_print_function_name(file,
2935                          instruction->file_entry->fields[insn_name],
2936                          NULL,
2937                          function_name_prefix_itable);
2938   lf_printf(file, ",\n");
2939 }
2940
2941
2942 static void 
2943 gen_itable_h(insn_table *table, lf *file)
2944 {
2945
2946   lf_print_copyleft(file);
2947   lf_printf(file, "\n");
2948   lf_printf(file, "#ifndef _ITABLE_H_\n");
2949   lf_printf(file, "#define _ITABLE_H_\n");
2950   lf_printf(file, "\n");
2951   lf_printf(file, "#ifndef INLINE_ITABLE\n");
2952   lf_printf(file, "#define INLINE_ITABLE\n");
2953   lf_printf(file, "#endif\n");
2954   lf_printf(file, "\n");
2955   lf_printf(file, "\n");
2956
2957   /* output an enumerated type for each instruction */
2958   lf_printf(file, "typedef enum {\n");
2959   insn_table_traverse_insn(table,
2960                            file,
2961                            itable_h_insn);
2962   lf_printf(file, "  nr_itable_entries,\n");
2963   lf_printf(file, "} itable_index;\n");
2964   lf_printf(file, "\n");
2965
2966   /* output the table that contains the actual instruction info */
2967   lf_printf(file, "typedef struct _itable_instruction_info {\n");
2968   lf_printf(file, "  itable_index nr;\n");
2969   lf_printf(file, "  char *format;\n");
2970   lf_printf(file, "  char *form;\n");
2971   lf_printf(file, "  char *flags;\n");
2972   lf_printf(file, "  char *mnemonic;\n");
2973   lf_printf(file, "  char *name;\n");
2974   lf_printf(file, "} itable_info;\n");
2975   lf_printf(file, "\n");
2976   lf_printf(file, "extern itable_info itable[nr_itable_entries];\n");
2977
2978   lf_printf(file, "\n");
2979   lf_printf(file, "#endif /* _ITABLE_C_ */\n");
2980
2981 }
2982
2983 /****************************************************************/
2984
2985 static void
2986 itable_c_insn(insn_table *entry,
2987               void *data,
2988               insn *instruction)
2989 {
2990   lf *file = (lf*)data;
2991   char **fields = instruction->file_entry->fields;
2992   lf_printf(file, "  { ");
2993   lf_print_function_name(file,
2994                          instruction->file_entry->fields[insn_name],
2995                          NULL,
2996                          function_name_prefix_itable);
2997   lf_printf(file, ",\n");
2998   lf_printf(file, "    \"%s\",\n", fields[insn_format]);
2999   lf_printf(file, "    \"%s\",\n", fields[insn_form]);
3000   lf_printf(file, "    \"%s\",\n", fields[insn_flags]);
3001   lf_printf(file, "    \"%s\",\n", fields[insn_mnemonic]);
3002   lf_printf(file, "    \"%s\",\n", fields[insn_name]);
3003   lf_printf(file, "    },\n");
3004 }
3005
3006
3007 static void 
3008 gen_itable_c(insn_table *table, lf *file)
3009 {
3010
3011   lf_print_copyleft(file);
3012   lf_printf(file, "\n");
3013   lf_printf(file, "#ifndef _ITABLE_C_\n");
3014   lf_printf(file, "#define _ITABLE_C_\n");
3015   lf_printf(file, "\n");
3016   lf_printf(file, "#ifndef STATIC_INLINE_ITABLE\n");
3017   lf_printf(file, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
3018   lf_printf(file, "#endif\n");
3019   lf_printf(file, "\n");
3020   lf_printf(file, "#include \"itable.h\"\n");
3021   lf_printf(file, "\n");
3022
3023   /* output the table that contains the actual instruction info */
3024   lf_printf(file, "itable_info itable[nr_itable_entries] = {\n");
3025   insn_table_traverse_insn(table,
3026                            file,
3027                            itable_c_insn);
3028   lf_printf(file, "};\n");
3029   lf_printf(file, "\n");
3030
3031   lf_printf(file, "\n");
3032   lf_printf(file, "#endif /* _ITABLE_C_ */\n");
3033 }
3034
3035 /****************************************************************/
3036
3037 static void
3038 model_c_or_h_data(insn_table *table,
3039                   lf *file,
3040                   table_entry *data)
3041 {
3042   if (data->annex) {
3043     table_entry_lf_c_line_nr(file, data);
3044     lf_print_c_code(file, data->annex);
3045     lf_print_lf_c_line_nr(file);
3046     lf_printf(file, "\n");
3047   }
3048 }
3049
3050 static void
3051 model_c_or_h_function(insn_table *entry,
3052                       lf *file,
3053                       table_entry *function,
3054                       char *prefix)
3055 {
3056   if (function->fields[function_type] == NULL
3057       || function->fields[function_type][0] == '\0') {
3058     error("Model function type not specified for %s", function->fields[function_name]);
3059   }
3060   else {
3061     lf_printf(file, "\n");
3062     lf_printf(file, "%s %s %s\n(%s);\n",
3063               prefix,
3064               function->fields[function_type],
3065               function->fields[function_name],
3066               function->fields[function_param]);
3067   }
3068   lf_printf(file, "\n");
3069 }
3070
3071 static void 
3072 gen_model_h(insn_table *table, lf *file)
3073 {
3074   insn *insn_ptr;
3075   model *model_ptr;
3076   model_func_unit *func_unit_ptr;
3077   insn *macro;
3078   int hex_size;
3079
3080   lf_print_copyleft(file);
3081   lf_printf(file, "\n");
3082   lf_printf(file, "#ifndef _MODEL_H_\n");
3083   lf_printf(file, "#define _MODEL_H_\n");
3084   lf_printf(file, "\n");
3085
3086   for(macro = model_macros; macro; macro = macro->next) {
3087     model_c_or_h_data(table, file, insn_ptr->file_entry);
3088   }
3089
3090   lf_printf(file, "#ifndef INLINE_MODEL\n");
3091   lf_printf(file, "#define INLINE_MODEL\n");
3092   lf_printf(file, "#endif\n");
3093   lf_printf(file, "#ifndef STATIC_INLINE_MODEL\n");
3094   lf_printf(file, "#define STATIC_INLINE_MODEL STATIC_INLINE\n");
3095   lf_printf(file, "#endif\n");
3096   lf_printf(file, "\n");
3097   lf_printf(file, "\n");
3098
3099   if (table->max_func_unit_mask > 0xffff) {
3100     hex_size = 8;
3101     lf_printf(file, "#ifndef MODEL_UNITS\n");
3102     lf_printf(file, "#define MODEL_UNITS unsigned32\n");
3103     lf_printf(file, "#endif\n");
3104     lf_printf(file, "\n");
3105
3106     lf_printf(file, "#ifndef MODEL_CYCLES\n");
3107     lf_printf(file, "#define MODEL_CYCLES unsigned16\n");
3108     lf_printf(file, "#endif\n");
3109     lf_printf(file, "\n");
3110   } else {
3111     hex_size = 4;
3112     lf_printf(file, "#ifndef MODEL_UNITS\n");
3113     lf_printf(file, "#define MODEL_UNITS unsigned16\n");
3114     lf_printf(file, "#endif\n");
3115     lf_printf(file, "\n");
3116
3117     lf_printf(file, "#ifndef MODEL_CYCLES\n");
3118     lf_printf(file, "#define MODEL_CYCLES unsigned8\n");
3119     lf_printf(file, "#endif\n");
3120     lf_printf(file, "\n");
3121   }
3122
3123   lf_printf(file, "#ifndef MODEL_FLAGS\n");
3124   lf_printf(file, "#define MODEL_FLAGS unsigned32\n");
3125   lf_printf(file, "#endif\n");
3126   lf_printf(file, "\n");
3127
3128   lf_printf(file, "typedef struct _model_time {\t/* Instruction cycle time */\n");
3129   lf_printf(file, "  MODEL_UNITS  units;\n");
3130   lf_printf(file, "  MODEL_CYCLES initial;\n");
3131   lf_printf(file, "  MODEL_CYCLES finish;\n");
3132   lf_printf(file, "  MODEL_FLAGS  flags;\n");
3133   lf_printf(file, "} model_time;\n");
3134   lf_printf(file, "\n");
3135
3136   lf_printf(file, "typedef enum _model_enum {\n");
3137   lf_printf(file, "  MODEL_NONE,\n");
3138   for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3139     lf_printf(file, "  MODEL_%s,\n", model_ptr->name);
3140   }
3141   lf_printf(file, "  nr_models\n");
3142   lf_printf(file, "} model_enum;\n");
3143   lf_printf(file, "\n");
3144
3145   lf_printf(file, "#define DEFAULT_MODEL MODEL_%s\n", (models) ? models->name : "NONE");
3146   lf_printf(file, "\n");
3147
3148   for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3149     for (func_unit_ptr = model_ptr->func_unit_start; func_unit_ptr; func_unit_ptr = func_unit_ptr->next) {
3150       if (func_unit_ptr->comment) {
3151         lf_printf(file, "#define %-*s 0x%.*x  /* %s functional unit */\n",
3152                   table->max_func_unit_name_len, func_unit_ptr->name,
3153                   hex_size, func_unit_ptr->mask,
3154                   func_unit_ptr->comment);
3155       } else {
3156         lf_printf(file, "#define %-*s 0x%.*x\n",
3157                   table->max_func_unit_name_len, func_unit_ptr->name,
3158                   hex_size, func_unit_ptr->mask);
3159       }
3160     }
3161     lf_printf(file, "\n");
3162   }
3163
3164   lf_printf(file, "extern model_enum current_model;\n");
3165   lf_printf(file, "extern const char *model_name[ (int)nr_models ];\n");
3166   lf_printf(file, "extern const char *const *const model_func_unit_name[ (int)nr_models ];\n");
3167   lf_printf(file, "extern const model_time *const model_time_mapping[ (int)nr_models ];\n");
3168   lf_printf(file, "\n");
3169   lf_printf(file, "INLINE_MODEL void model_set\n");
3170   lf_printf(file, "(const char *name);\n");
3171
3172   for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
3173     model_c_or_h_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
3174     lf_printf(file, "\n");
3175   }
3176
3177   lf_printf(file, "\n");
3178   lf_printf(file, "#endif /* _MODEL_H_ */\n");
3179 }
3180
3181 /****************************************************************/
3182
3183 typedef struct _model_c_passed_data model_c_passed_data;
3184 struct _model_c_passed_data {
3185   lf *file;
3186   model *model_ptr;
3187 };
3188
3189 static void
3190 model_c_insn(insn_table *entry,
3191               void *data,
3192               insn *instruction)
3193 {
3194   model_c_passed_data *data_ptr = (model_c_passed_data *)data;
3195   lf *file = data_ptr->file;
3196   char *current_name = data_ptr->model_ptr->name;
3197   table_model_entry *model_ptr = instruction->file_entry->model_first;
3198   int i;
3199
3200   while (model_ptr) {
3201     if (model_ptr->fields[insn_model_name] == current_name) {
3202       lf_printf(file, "  {");
3203       for(i = insn_model_unit; i < nr_insn_model_table_fields; i++) {
3204         lf_printf(file, " %s,", model_ptr->fields[i]);
3205       }
3206       lf_printf(file, " }, /* %s */\n", instruction->file_entry->fields[insn_name]);
3207       return;
3208     }
3209
3210     model_ptr = model_ptr->next;
3211   }
3212
3213   lf_printf(file, "  { %s_SENTINEL },\n", current_name);
3214 }
3215
3216 static void
3217 model_c_function(insn_table *table,
3218                  lf *file,
3219                  table_entry *function,
3220                  const char *prefix)
3221 {
3222   if (function->fields[function_type] == NULL
3223       || function->fields[function_type][0] == '\0') {
3224     error("Model function return type not specified for %s", function->fields[function_name]);
3225   }
3226   else {
3227     lf_printf(file, "\n");
3228     lf_printf(file, "%s %s\n%s(%s)\n",
3229               prefix,
3230               function->fields[function_type],
3231               function->fields[function_name],
3232               function->fields[function_param]);
3233   }
3234   table_entry_lf_c_line_nr(file, function);
3235   lf_printf(file, "{\n");
3236   if (function->annex) {
3237     lf_indent(file, +2);
3238     lf_print_c_code(file, function->annex);
3239     lf_indent(file, -2);
3240   }
3241   lf_printf(file, "}\n");
3242   lf_print_lf_c_line_nr(file);
3243   lf_printf(file, "\n");
3244 }
3245
3246 static void 
3247 gen_model_c(insn_table *table, lf *file)
3248 {
3249   insn *insn_ptr;
3250   model *model_ptr;
3251   model_func_unit *func_unit_ptr;
3252   int i;
3253
3254   lf_print_copyleft(file);
3255   lf_printf(file, "\n");
3256   lf_printf(file, "#ifndef _MODEL_C_\n");
3257   lf_printf(file, "#define _MODEL_C_\n");
3258   lf_printf(file, "\n");
3259   lf_printf(file, "#include \"cpu.h\"\n");
3260   lf_printf(file, "\n");
3261
3262   for(insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next) {
3263     model_c_or_h_data(table, file, insn_ptr->file_entry);
3264   }
3265
3266   for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
3267     model_c_or_h_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
3268   }
3269
3270   lf_printf(file, "/* map model enumeration into printable string */\n");
3271   lf_printf(file, "const char *model_name[ (int)nr_models ] = {\n");
3272   lf_printf(file, "  \"NONE\",\n");
3273   for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3274     lf_printf(file, "  \"%s\",\n", model_ptr->printable_name);
3275   }
3276   lf_printf(file, "};\n");
3277   lf_printf(file, "\n");
3278
3279   lf_printf(file, "/* Emit each model's individual function unit names */\n");
3280   lf_printf(file, "static const char *const model_func_unit_name_NONE[] = {\n");
3281   lf_printf(file, "  \"none\",\n");
3282   lf_printf(file, "  (const char *)0\n");
3283   lf_printf(file, "};\n");
3284   lf_printf(file, "\n");
3285
3286   for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3287     lf_printf(file, "static const char *const model_func_unit_name_%s[] = {\n", model_ptr->name);
3288     lf_printf(file, "  \"none\",\n");
3289     for (func_unit_ptr = model_ptr->func_unit_start; func_unit_ptr; func_unit_ptr = func_unit_ptr->next) {
3290
3291       if (func_unit_ptr->comment)
3292         lf_printf(file, "  \"%s %s functional unit\",\n", func_unit_ptr->name, func_unit_ptr->comment);
3293       else
3294         lf_printf(file, "  \"%s\",\n", func_unit_ptr->name);
3295
3296       for(i = 2; i < func_unit_ptr->number; i++) {
3297         if (func_unit_ptr->comment)
3298           lf_printf(file, "  \"%s %s functional unit #%d\",\n", func_unit_ptr->name,
3299                     func_unit_ptr->comment, i);
3300         else
3301           lf_printf(file, "  \"%s #%d\",\n", func_unit_ptr->name, i);
3302       }
3303     }
3304
3305     lf_printf(file, "  (const char *)0\n");
3306     lf_printf(file, "};\n");
3307     lf_printf(file, "\n");
3308   }
3309
3310   lf_printf(file, "/* Array to map model,function unit number to printable string. */\n");
3311   lf_printf(file, "const char *const *const model_func_unit_name[] = {\n");
3312   lf_printf(file, "  model_func_unit_name_NONE,\n");
3313   for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3314     lf_printf(file, "  model_func_unit_name_%s,\n", model_ptr->name);
3315   }
3316   lf_printf(file, "};\n");
3317   lf_printf(file, "\n");
3318   lf_printf(file, "\f\n");
3319
3320   lf_printf(file, "/* Insn functional unit info */\n");
3321   for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3322     model_c_passed_data data;
3323
3324     lf_printf(file, "static const model_time model_time_%s[] = {\n", model_ptr->name);
3325     data.file = file;
3326     data.model_ptr = model_ptr;
3327     insn_table_traverse_insn(table,
3328                              (void *)&data,
3329                              model_c_insn);
3330
3331     lf_printf(file, "};\n");
3332     lf_printf(file, "\n");
3333     lf_printf(file, "\f\n");
3334   }
3335
3336   lf_printf(file, "const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
3337   lf_printf(file, "  (const model_time *const)0,\n");
3338   for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3339     lf_printf(file, "  model_time_%s,\n", model_ptr->name);
3340   }
3341   lf_printf(file, "};\n");
3342   lf_printf(file, "\n");
3343
3344   for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
3345     model_c_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
3346   }
3347
3348   for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
3349     model_c_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
3350   }
3351
3352   lf_printf(file, "INLINE_MODEL void\n");
3353   lf_printf(file, "model_set(const char *name)\n");
3354   lf_printf(file, "{\n");
3355   if (models) {
3356     lf_printf(file, "  model_enum model;\n");
3357     lf_printf(file, "  for(model = MODEL_%s; model < nr_models; model++) {\n", models->name);
3358     lf_printf(file, "    if(strcasecmp(name, model_name[model]) == 0) {\n");
3359     lf_printf(file, "      current_model = model;\n");
3360     lf_printf(file, "      return;\n");
3361     lf_printf(file, "    }\n");
3362     lf_printf(file, "  }\n");
3363     lf_printf(file, "\n");
3364     lf_printf(file, "  error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
3365     lf_printf(file, "        name,\n");
3366     lf_printf(file, "        \"");
3367     for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3368       lf_printf(file, "\\n\\t%s", model_ptr->printable_name);
3369     }
3370     lf_printf(file, "\");\n");
3371   } else {
3372     lf_printf(file, "  error(\"No models are currently known about\");\n");
3373   }
3374
3375   lf_printf(file, "}\n");
3376   lf_printf(file, "\n");
3377
3378   lf_printf(file, "#endif /* _MODEL_C_ */\n");
3379
3380 }
3381
3382 /****************************************************************/
3383
3384
3385 int
3386 main(int argc,
3387      char **argv,
3388      char **envp)
3389 {
3390   insn_table *instructions = NULL;
3391   icache_tree *cache_fields = NULL;
3392   char *real_file_name = NULL;
3393   int ch;
3394
3395   if (argc == 1) {
3396     printf("Usage:\n");
3397     printf("  igen <config-opts> ... <input-opts>... <output-opts>...\n");
3398     printf("Config options:\n");
3399     printf("  -f <filter-out-flag>  eg -f 64 to skip 64bit instructions\n");
3400     printf("  -e    Expand (duplicate) semantic functions\n");
3401     printf("  -r <icache-size>  Generate cracking cache version\n");
3402     printf("  -l    Supress line numbering in output files\n");
3403     printf("  -b <bit-size>  Set the number of bits in an instruction\n");
3404     printf("  -h <high-bit>  Set the nr of the high (msb bit)\n");
3405     printf("Input options (ucase version also dumps loaded table):\n");
3406     printf("  -[Oo] <opcode-rules>\n");
3407     printf("  -[Kk] <cache-rules>\n");
3408     printf("  -[Ii] <instruction-table>\n");
3409     printf("Output options:\n");
3410     printf("  -[Cc] <output-file>  output icache.h(C) invalid(c)\n");
3411     printf("  -[Dd] <output-file>  output idecode.h(D) idecode.c(d)\n");
3412     printf("  -[Mm] <output-file>  output model.h(M) model.c(M)\n");
3413     printf("  -[Ss] <output-file>  output schematic.h(S) schematic.c(s)\n");
3414     printf("  -[Tt] <table>      output itable.h(T) itable.c(t)\n");
3415   }
3416
3417   while ((ch = getopt(argc, argv,
3418                       "leb:h:r:f:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
3419     fprintf(stderr, "\t-%c %s\n", ch, (optarg ? optarg : ""));
3420     switch(ch) {
3421     case 'l':
3422       number_lines = 0;
3423       break;
3424     case 'e':
3425       idecode_expand_semantics = 1;
3426       break;
3427     case 'r':
3428       idecode_cache = a2i(optarg);
3429       break;
3430     case 'b':
3431       insn_size = a2i(optarg);
3432       ASSERT(insn_size > 0 && insn_size <= max_insn_size
3433              && (hi_bit_nr == insn_size-1 || hi_bit_nr == 0));
3434       break;
3435     case 'h':
3436       hi_bit_nr = a2i(optarg);
3437       ASSERT(hi_bit_nr == insn_size-1 || hi_bit_nr == 0);
3438       break;
3439     case 'f':
3440       {
3441         filter *new_filter = ZALLOC(filter);
3442         new_filter->flag = strdup(optarg);
3443         new_filter->next = filters;
3444         filters = new_filter;
3445         break;
3446       }
3447     case 'I':
3448     case 'i':
3449       ASSERT(opcode_table != NULL);
3450       ASSERT(cache_table != NULL);
3451       instructions = insn_table_load_insns(optarg);
3452       fprintf(stderr, "\texpanding ...\n");
3453       insn_table_expand_insns(instructions);
3454       fprintf(stderr, "\tcache fields ...\n");
3455       cache_fields = insn_table_cache_fields(instructions);
3456       if (ch == 'I') {
3457         dump_traverse(instructions);
3458         dump_insn_table(instructions, 0, 1);
3459       }
3460       break;
3461     case 'O':
3462     case 'o':
3463       opcode_table = load_opcode_rules(optarg);
3464       if (ch == 'O')
3465         dump_opcode_rules(opcode_table, 0);
3466       break;
3467     case 'K':
3468     case 'k':
3469       cache_table = load_cache_rules(optarg);
3470       if (ch == 'K')
3471         dump_cache_rules(cache_table, 0);
3472       break;
3473     case 'n':
3474       real_file_name = strdup(optarg);
3475       break;
3476     case 'S':
3477     case 's':
3478     case 'D':
3479     case 'd':
3480     case 'M':
3481     case 'm':
3482     case 'T':
3483     case 't':
3484     case 'C':
3485       {
3486         lf *file = lf_open(optarg, real_file_name, number_lines);
3487         ASSERT(instructions != NULL);
3488         switch (ch) {
3489         case 'S':
3490           gen_semantics_h(instructions, file);
3491           break;
3492         case 's':
3493           gen_semantics_c(instructions, file);
3494           break;
3495         case 'D':
3496           gen_idecode_h(instructions, file);
3497           break;
3498         case 'd':
3499           gen_idecode_c(instructions, file);
3500           break;
3501         case 'M':
3502           gen_model_h(instructions, file);
3503           break;
3504         case 'm':
3505           gen_model_c(instructions, file);
3506           break;
3507         case 'T':
3508           gen_itable_h(instructions, file);
3509           break;
3510         case 't':
3511           gen_itable_c(instructions, file);
3512           break;
3513         case 'C':
3514           gen_icache_h(cache_fields, file);
3515           break;
3516         }
3517         lf_close(file);
3518       }
3519       real_file_name = NULL;
3520       break;
3521     default:
3522       error("unknown option\n");
3523     }
3524   }
3525   return 0;
3526 }