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