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