Commit | Line | Data |
---|---|---|
feaee4bd AC |
1 | /* The IGEN simulator generator for GDB, the GNU Debugger. |
2 | ||
3 | Copyright 2002 Free Software Foundation, Inc. | |
4 | ||
5 | Contributed by Andrew Cagney. | |
6 | ||
7 | This file is part of GDB. | |
8 | ||
9 | This program is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 2 of the License, or | |
12 | (at your option) any later version. | |
13 | ||
14 | This program is distributed in the hope that it will be useful, | |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | GNU General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
20 | along with this program; if not, write to the Free Software | |
21 | Foundation, Inc., 59 Temple Place - Suite 330, | |
22 | Boston, MA 02111-1307, USA. */ | |
c906108c SS |
23 | |
24 | ||
25 | ||
26 | typedef unsigned64 insn_uint; | |
27 | ||
28 | ||
29 | /* Common among most entries: | |
30 | ||
31 | All non instruction records have the format: | |
32 | ||
33 | <...> ::= | |
34 | ":" <record-name> | |
35 | ":" <filter-flags> | |
36 | ":" <filter-models> | |
37 | ":" ... | |
38 | ||
39 | */ | |
40 | ||
41 | enum { | |
42 | record_type_field = 1, | |
43 | old_record_type_field = 2, | |
44 | record_filter_flags_field = 2, | |
45 | record_filter_models_field = 3, | |
46 | }; | |
47 | ||
48 | ||
49 | /* Include: | |
50 | ||
51 | Include the specified file. | |
52 | ||
53 | <include> ::= | |
54 | ":" "include" | |
55 | ":" <filter-flags> | |
56 | ":" <filter-models> | |
57 | ":" <filename> | |
58 | <nl> | |
59 | ; | |
60 | ||
61 | */ | |
62 | ||
63 | enum { | |
64 | include_filename_field = 4, | |
65 | nr_include_fields, | |
66 | }; | |
67 | ||
68 | ||
69 | ||
70 | /* Options: | |
71 | ||
72 | Valid options are: hi-bit-nr (default 0), insn-bit-size (default | |
73 | 32), insn-specifying-widths (default true), multi-sim (default false). | |
74 | ||
75 | <option> ::= | |
76 | ":" "option" | |
77 | ":" <filter-flags> | |
78 | ":" <filter-models> | |
79 | ":" <option-name> | |
80 | ":" <option-value> | |
81 | <nl> | |
82 | ; | |
83 | ||
84 | <option-name> ::= | |
85 | "insn-bit-size" | |
86 | | "insn-specifying-widths" | |
87 | | "hi-bit-nr" | |
88 | | "flags-filter" | |
89 | | "model-filter" | |
90 | | "multi-sim" | |
91 | | "format-names" | |
92 | ; | |
93 | ||
94 | <option-value> ::= | |
95 | "true" | |
96 | | "false" | |
97 | | <integer> | |
98 | | <list> | |
99 | ; | |
100 | ||
101 | ||
102 | These update the global options structure. */ | |
103 | ||
104 | ||
105 | enum { | |
106 | option_name_field = 4, | |
107 | option_value_field, | |
108 | nr_option_fields, | |
109 | }; | |
110 | ||
111 | ||
112 | ||
113 | /* Macro definitions: | |
114 | ||
115 | <insn-macro> ::= | |
116 | ":" "define" | |
117 | ":" <filter-flags> | |
118 | ":" <filter-models> | |
119 | ":" <name> | |
120 | ":" <arg-list> | |
121 | ":" <expression> | |
122 | <nl> | |
123 | ; | |
124 | ||
125 | <arg-list> ::= | |
126 | [ <name> { "," <arg-list> } ] | |
127 | ; | |
128 | ||
129 | */ | |
130 | ||
131 | ||
132 | enum { | |
133 | macro_name_field = 4, | |
134 | macro_args_field, | |
135 | macro_expr_field, | |
136 | nr_macro_fields, | |
137 | }; | |
138 | ||
139 | ||
140 | ||
141 | /* Functions and internal routins: | |
142 | ||
143 | NB: <filter-models> and <function-models> are equivalent. | |
144 | ||
145 | ||
146 | <function> ::= | |
147 | ":" "function" | |
148 | <function-spec> | |
149 | ; | |
150 | ||
151 | <internal> ::= | |
152 | ":" "internal" | |
153 | <function-spec> | |
154 | ; | |
155 | ||
156 | <format> ::= | |
157 | ":" ( "%s" | ... ) | |
158 | <function-spec> | |
159 | ; | |
160 | ||
161 | <function-model> ::= | |
162 | "*" [ <processor-list> ] | |
163 | ":" | |
164 | <nl> | |
165 | ; | |
166 | ||
167 | <function-spec> ::= | |
168 | ":" <filter-flags> | |
169 | ":" <filter-models> | |
170 | ":" <typedef> | |
171 | ":" <name> | |
172 | [ ":" <parameter-list> ] | |
173 | <nl> | |
174 | [ <function-model> ] | |
175 | <code-block> | |
176 | ; | |
177 | ||
178 | */ | |
179 | ||
180 | enum { | |
181 | function_typedef_field = 4, | |
182 | function_name_field, | |
183 | function_param_field, | |
184 | nr_function_fields, | |
185 | }; | |
186 | ||
187 | enum { | |
188 | function_model_name_field = 0, | |
189 | nr_function_model_fields = 1, | |
190 | }; | |
191 | ||
192 | enum { | |
193 | old_function_typedef_field = 0, | |
194 | old_function_type_field = 2, | |
195 | old_function_name_field = 4, | |
196 | old_function_param_field = 5, | |
197 | nr_old_function_fields = 5, /* parameter-list is optional */ | |
198 | }; | |
199 | ||
200 | ||
201 | typedef struct _function_entry function_entry; | |
202 | struct _function_entry { | |
203 | line_ref *line; | |
204 | filter *flags; | |
205 | filter *models; | |
206 | char *type; | |
207 | char *name; | |
208 | char *param; | |
209 | table_entry *code; | |
210 | int is_internal; | |
211 | function_entry *next; | |
212 | }; | |
213 | ||
214 | ||
215 | typedef void function_entry_handler | |
216 | (lf *file, | |
217 | function_entry *function, | |
218 | void *data); | |
219 | ||
220 | extern void function_entry_traverse | |
221 | (lf *file, | |
222 | function_entry *functions, | |
223 | function_entry_handler *handler, | |
224 | void *data); | |
225 | ||
226 | ||
227 | /* cache-macro: | |
228 | ||
229 | <cache-macro> ::= | |
230 | ":" <macro-type> | |
231 | ":" <filter-flags> | |
232 | ":" <filter-models> | |
233 | ":" <typedef> | |
234 | ":" <name> | |
235 | ":" <field-name> { "," <field-name> } | |
236 | ":" <expression> | |
237 | <nl> | |
238 | ; | |
239 | ||
240 | <cache-macro-type> ::= | |
241 | "scratch" | |
242 | | "cache" | |
243 | | "compute" | |
244 | ; | |
245 | ||
246 | <name> ::= | |
247 | <ident> | |
248 | | <ident> "_is_" <integer> | |
249 | ; | |
250 | ||
251 | A cache entry is defined (for an instruction) when all | |
252 | <field-name>s are present as named opcode fields within the | |
253 | instructions format. | |
254 | ||
255 | SCRATCH and CACHE macros are defined during the cache fill stage | |
256 | while CACHE and COMPUTE macros are defined during the instruction | |
257 | execution stage. | |
258 | ||
259 | */ | |
260 | ||
261 | enum { | |
262 | cache_typedef_field = 4, | |
263 | cache_name_field, | |
264 | cache_original_fields_field, | |
265 | cache_expression_field, | |
266 | nr_cache_fields, | |
267 | }; | |
268 | ||
269 | typedef enum { | |
270 | scratch_value, | |
271 | cache_value, | |
272 | compute_value, | |
273 | } cache_entry_type; | |
274 | ||
275 | typedef struct _cache_entry cache_entry; | |
276 | struct _cache_entry { | |
277 | line_ref *line; | |
278 | filter *flags; | |
279 | filter *models; | |
280 | cache_entry_type entry_type; | |
281 | char *name; | |
282 | filter *original_fields; | |
283 | char *type; | |
284 | char *expression; | |
285 | cache_entry *next; | |
286 | }; | |
287 | ||
288 | ||
289 | ||
290 | /* Model specs: | |
291 | ||
292 | <model-processor> ::= | |
293 | ":" "model" | |
294 | ":" <filter-flags> | |
295 | ":" <filter-models> | |
296 | ":" <processor> | |
297 | ":" <BFD-processor> | |
298 | ":" <function-unit-data> | |
299 | <nl> | |
300 | ; | |
301 | ||
302 | <model-macro> ::= | |
303 | ":" "model-macro" | |
304 | ":" <filter-flags> | |
305 | ":" <filter-models> | |
306 | <nl> | |
307 | <code-block> | |
308 | ; | |
309 | ||
310 | <model-data> ::= | |
311 | ":" "model-data" | |
312 | ":" <filter-flags> | |
313 | ":" <filter-models> | |
314 | <nl> | |
315 | <code-block> | |
316 | ; | |
317 | ||
318 | <model-static> ::= | |
319 | ":" "model-static" | |
320 | <function-spec> | |
321 | ; | |
322 | ||
323 | <model-internal> ::= | |
324 | ":" "model-internal" | |
325 | <function-spec> | |
326 | ; | |
327 | ||
328 | <model-function> ::= | |
329 | ":" "model-internal" | |
330 | <function-spec> | |
331 | ; | |
332 | ||
333 | */ | |
334 | ||
335 | enum { | |
336 | nr_model_macro_fields = 4, | |
337 | nr_model_data_fields = 4, | |
338 | nr_model_static_fields = nr_function_fields, | |
339 | nr_model_internal_fields = nr_function_fields, | |
340 | nr_model_function_fields = nr_function_fields, | |
341 | }; | |
342 | ||
343 | typedef struct _model_data model_data; | |
344 | struct _model_data { | |
345 | line_ref *line; | |
346 | filter *flags; | |
347 | table_entry *entry; | |
348 | table_entry *code; | |
349 | model_data *next; | |
350 | }; | |
351 | ||
352 | enum { | |
353 | model_name_field = 4, | |
354 | model_full_name_field, | |
355 | model_unit_data_field, | |
356 | nr_model_processor_fields, | |
357 | }; | |
358 | ||
359 | typedef struct _model_entry model_entry; | |
360 | struct _model_entry { | |
361 | line_ref *line; | |
362 | filter *flags; | |
363 | char *name; | |
364 | char *full_name; | |
365 | char *unit_data; | |
366 | model_entry *next; | |
367 | }; | |
368 | ||
369 | ||
370 | typedef struct _model_table model_table; | |
371 | struct _model_table { | |
372 | filter *processors; | |
373 | int nr_models; | |
374 | model_entry *models; | |
375 | model_data *macros; | |
376 | model_data *data; | |
377 | function_entry *statics; | |
378 | function_entry *internals; | |
379 | function_entry *functions; | |
380 | }; | |
381 | ||
382 | ||
383 | ||
384 | /* Instruction format: | |
385 | ||
386 | An instruction is composed of a sequence of N bit instruction | |
387 | words. Each word broken into a number of instruction fields. | |
388 | Those fields being constant (ex. an opcode) or variable (register | |
389 | spec). | |
390 | ||
391 | <insn-word> ::= | |
392 | <insn-field> { "," <insn-field> } ; | |
393 | ||
394 | <insn-field> ::= | |
395 | ( <binary-value-implying-width> | |
396 | | <field-name-implying-width> | |
397 | | [ <start-or-width> "." ] <field> | |
398 | ) | |
399 | { [ "!" | "=" ] [ <value> | <field-name> ] } | |
400 | ; | |
401 | ||
402 | <field> ::= | |
403 | { "*" }+ | |
404 | | { "/" }+ | |
405 | | <field-name> | |
406 | | "0x" <hex-value> | |
407 | | "0b" <binary-value> | |
408 | | "0" <octal-value> | |
409 | | <integer-value> ; | |
410 | ||
411 | */ | |
412 | ||
413 | typedef enum _insn_field_cond_type { | |
414 | insn_field_cond_value, | |
415 | insn_field_cond_field, | |
416 | } insn_field_cond_type; | |
417 | typedef enum _insn_field_cond_test { | |
418 | insn_field_cond_eq, | |
419 | insn_field_cond_ne, | |
420 | } insn_field_cond_test; | |
421 | typedef struct _insn_field_cond insn_field_cond; | |
422 | struct _insn_field_cond { | |
423 | insn_field_cond_type type; | |
424 | insn_field_cond_test test; | |
425 | insn_uint value; | |
426 | struct _insn_field_entry *field; | |
427 | char *string; | |
428 | insn_field_cond *next; | |
429 | }; | |
430 | ||
431 | ||
432 | typedef enum _insn_field_type { | |
433 | insn_field_invalid, | |
434 | insn_field_int, | |
435 | insn_field_reserved, | |
436 | insn_field_wild, | |
437 | insn_field_string, | |
438 | } insn_field_type; | |
439 | ||
440 | typedef struct _insn_field_entry insn_field_entry; | |
441 | struct _insn_field_entry { | |
442 | int first; | |
443 | int last; | |
444 | int width; | |
445 | int word_nr; | |
446 | insn_field_type type; | |
447 | insn_uint val_int; | |
448 | char *pos_string; | |
449 | char *val_string; | |
450 | insn_field_cond *conditions; | |
451 | insn_field_entry *next; | |
452 | insn_field_entry *prev; | |
453 | }; | |
454 | ||
455 | typedef struct _insn_bit_entry insn_bit_entry; | |
456 | struct _insn_bit_entry { | |
457 | int value; | |
458 | int mask; | |
459 | insn_field_entry *field; | |
460 | }; | |
461 | ||
462 | ||
463 | ||
464 | ||
465 | typedef struct _insn_entry insn_entry; /* forward */ | |
466 | ||
467 | typedef struct _insn_word_entry insn_word_entry; | |
468 | struct _insn_word_entry { | |
469 | /* list of sub-fields making up the instruction. bit provides | |
470 | faster access to the field data for bit N. */ | |
471 | insn_field_entry *first; | |
472 | insn_field_entry *last; | |
473 | insn_bit_entry *bit[max_insn_bit_size]; | |
474 | /* set of all the string fields */ | |
475 | filter *field_names; | |
476 | /* For multi-word instructions, The Nth word (from zero). */ | |
477 | insn_word_entry *next; | |
478 | }; | |
479 | ||
480 | ||
481 | ||
482 | /* Instruction model: | |
483 | ||
484 | Provides scheduling and other data for the code modeling the | |
485 | instruction unit. | |
486 | ||
487 | <insn-model> ::= | |
488 | "*" [ <processor-list> ] | |
489 | ":" [ <function-unit-data> ] | |
490 | <nl> | |
491 | ; | |
492 | ||
493 | <processor-list> ::= | |
494 | <processor> { "," <processor>" } | |
495 | ; | |
496 | ||
497 | If the <processor-list> is empty, the model is made the default for | |
498 | this instruction. | |
499 | ||
500 | */ | |
501 | ||
502 | enum { | |
503 | insn_model_name_field = 0, | |
504 | insn_model_unit_data_field = 1, | |
505 | nr_insn_model_fields = 1, | |
506 | }; | |
507 | ||
508 | typedef struct _insn_model_entry insn_model_entry; | |
509 | struct _insn_model_entry { | |
510 | line_ref *line; | |
511 | insn_entry *insn; | |
512 | filter *names; | |
513 | char *full_name; | |
514 | char *unit_data; | |
515 | insn_model_entry *next; | |
516 | }; | |
517 | ||
518 | ||
519 | ||
520 | /* Instruction mnemonic: | |
521 | ||
522 | List of assembler mnemonics for the instruction. | |
523 | ||
524 | <insn-mnenonic> ::= | |
525 | "\"" <assembler-mnemonic> "\"" | |
526 | [ ":" <conditional-expression> ] | |
527 | <nl> | |
528 | ; | |
529 | ||
530 | An assembler mnemonic string has the syntax: | |
531 | ||
532 | <assembler-mnemonic> ::= | |
533 | ( [ "%" <format-spec> ] "<" <func> [ "#" <param-list> ] ">" | |
534 | | "%%" | |
535 | | <other-letter> | |
536 | )+ | |
537 | ||
538 | Where, for instance, the text is translated into a printf format | |
539 | and argument pair: | |
540 | ||
541 | "<FUNC>" : "%ld", (long) FUNC | |
542 | "%<FUNC>..." : "%...", FUNC | |
543 | "%s<FUNC>" : "%s", <%s>FUNC (SD_, FUNC) | |
544 | "%s<FUNC#P1,P2>" : "%s", <%s>FUNC (SD_, P1,P2) | |
545 | "%lx<FUNC>" : "%lx", (unsigned long) FUNC | |
546 | "%08lx<FUNC>" : "%08lx", (unsigned long) FUNC | |
547 | ||
548 | And "<%s>FUNC" denotes a function declared using the "%s" record | |
549 | specifier. | |
550 | ||
551 | ||
552 | ||
553 | ; | |
554 | ||
555 | */ | |
556 | ||
557 | enum { | |
558 | insn_mnemonic_format_field = 0, | |
559 | insn_mnemonic_condition_field = 1, | |
560 | nr_insn_mnemonic_fields = 1, | |
561 | }; | |
562 | ||
563 | typedef struct _insn_mnemonic_entry insn_mnemonic_entry; | |
564 | struct _insn_mnemonic_entry { | |
565 | line_ref *line; | |
566 | insn_entry *insn; | |
567 | char *format; | |
568 | char *condition; | |
569 | insn_mnemonic_entry *next; | |
570 | }; | |
571 | ||
572 | ||
573 | ||
574 | /* Instruction: | |
575 | ||
576 | <insn> ::= | |
577 | <insn-word> { "+" <insn-word> } | |
578 | ":" <format-name> | |
579 | ":" <filter-flags> | |
580 | ":" <options> | |
581 | ":" <name> | |
582 | <nl> | |
583 | { <insn-model> } | |
584 | { <insn-mnemonic> } | |
585 | <code-block> | |
586 | ||
587 | */ | |
588 | ||
589 | enum { | |
590 | insn_word_field = 0, | |
591 | insn_format_name_field = 1, | |
592 | insn_filter_flags_field = 2, | |
593 | insn_options_field = 3, | |
594 | insn_name_field = 4, | |
595 | nr_insn_fields = 5, | |
596 | }; | |
597 | ||
598 | ||
599 | /* typedef struct _insn_entry insn_entry; */ | |
600 | struct _insn_entry { | |
601 | line_ref *line; | |
602 | filter *flags; /* filtered by options.filters */ | |
603 | char *format_name; | |
604 | filter *options; | |
605 | char *name; | |
606 | /* the words that make up the instruction. Word provides direct | |
607 | access to word N. Pseudo instructions can be identified by | |
608 | nr_words == 0. */ | |
609 | int nr_words; | |
610 | insn_word_entry *words; | |
611 | insn_word_entry **word; | |
612 | /* a set of all the fields from all the words */ | |
613 | filter *field_names; | |
614 | /* an array of processor models, missing models are NULL! */ | |
615 | int nr_models; | |
616 | insn_model_entry *models; | |
617 | insn_model_entry **model; | |
618 | filter *processors; | |
619 | /* list of assember formats */ | |
620 | int nr_mnemonics; | |
621 | insn_mnemonic_entry *mnemonics; | |
622 | /* code body */ | |
623 | table_entry *code; | |
624 | insn_entry *next; | |
625 | }; | |
626 | ||
627 | ||
628 | /* Instruction table: | |
629 | ||
630 | */ | |
631 | ||
632 | typedef struct _insn_table insn_table; | |
633 | struct _insn_table { | |
634 | cache_entry *caches; | |
635 | int max_nr_words; | |
636 | int nr_insns; | |
637 | insn_entry *insns; | |
638 | function_entry *functions; | |
639 | insn_entry *illegal_insn; | |
640 | model_table *model; | |
641 | filter *options; | |
642 | filter *flags; | |
643 | }; | |
644 | ||
645 | extern insn_table *load_insn_table | |
646 | (char *file_name, | |
647 | cache_entry *cache); | |
648 | ||
649 | typedef void insn_entry_handler | |
650 | (lf *file, | |
651 | insn_table *isa, | |
652 | insn_entry *insn, | |
653 | void *data); | |
654 | ||
655 | extern void insn_table_traverse_insn | |
656 | (lf *file, | |
657 | insn_table *isa, | |
658 | insn_entry_handler *handler, | |
659 | void *data); | |
660 | ||
661 | ||
662 | ||
663 | /* Printing */ | |
664 | ||
665 | extern void print_insn_words | |
666 | (lf *file, | |
667 | insn_entry *insn); | |
668 | ||
669 | ||
670 | ||
671 | /* Debugging */ | |
672 | ||
673 | void | |
674 | dump_insn_field | |
675 | (lf *file, | |
676 | char *prefix, | |
677 | insn_field_entry *field, | |
678 | char *suffix); | |
679 | ||
680 | void | |
681 | dump_insn_word_entry | |
682 | (lf *file, | |
683 | char *prefix, | |
684 | insn_word_entry *word, | |
685 | char *suffix); | |
686 | ||
687 | void | |
688 | dump_insn_entry | |
689 | (lf *file, | |
690 | char *prefix, | |
691 | insn_entry *insn, | |
692 | char *suffix); | |
693 | ||
694 | void | |
695 | dump_cache_entries | |
696 | (lf *file, | |
697 | char *prefix, | |
698 | cache_entry *entry, | |
699 | char *suffix); | |
700 | ||
701 | void | |
702 | dump_insn_table | |
703 | (lf *file, | |
704 | char *prefix, | |
705 | insn_table *isa, | |
706 | char *suffix); |