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