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