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