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