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