1 /* Header file for targets using CGEN: Cpu tools GENerator.
2 
3 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
4 
5 This file is part of GDB, the GNU debugger, and the GNU Binutils.
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20 
21 #ifndef CGEN_H
22 #define CGEN_H
23 
24 /* Prepend the cpu name, defined in cpu-opc.h, and _cgen_ to symbol S.
25    The lack of spaces in the arg list is important for non-stdc systems.
26    This file is included by <cpu>-opc.h.
27    It can be included independently of cpu-opc.h, in which case the cpu
28    dependent portions will be declared as "unknown_cgen_foo".  */
29 
30 #ifndef CGEN_SYM
31 #define CGEN_SYM(s) CONCAT3 (unknown,_cgen_,s)
32 #endif
33 
34 /* This file contains the static (unchanging) pieces and as much other stuff
35    as we can reasonably put here.  It's generally cleaner to put stuff here
36    rather than having it machine generated if possible.  */
37 
38 /* The assembler syntax is made up of expressions (duh...).
39    At the lowest level the values are mnemonics, register names, numbers, etc.
40    Above that are subexpressions, if any (an example might be the
41    "effective address" in m68k cpus).  At the second highest level are the
42    insns themselves.  Above that are pseudo-insns, synthetic insns, and macros,
43    if any.
44 */
45 
46 /* Lots of cpu's have a fixed insn size, or one which rarely changes,
47    and it's generally easier to handle these by treating the insn as an
48    integer type, rather than an array of characters.  So we allow targets
49    to control this.  */
50 
51 #ifdef CGEN_INT_INSN
52 typedef unsigned int cgen_insn_t;
53 #else
54 typedef char * cgen_insn_t;
55 #endif
56 
57 #ifdef __GNUC__
58 #define CGEN_INLINE inline
59 #else
60 #define CGEN_INLINE
61 #endif
62 
63 /* Perhaps we should just use bfd.h, but it's not clear
64    one would want to require that yet.  */
65 enum cgen_endian
66 {
67   CGEN_ENDIAN_UNKNOWN,
68   CGEN_ENDIAN_LITTLE,
69   CGEN_ENDIAN_BIG
70 };
71 
72 /* Attributes.
73    Attributes are used to describe various random things.  */
74 
75 /* Struct to record attribute information.  */
76 typedef struct
77 {
78   unsigned char num_nonbools;
79   unsigned int bool;
80   unsigned int nonbool[1];
81 } CGEN_ATTR;
82 
83 /* Define a structure member for attributes with N non-boolean entries.
84    The attributes are sorted so that the non-boolean ones come first.
85    num_nonbools: count of nonboolean attributes
86    bool: values of boolean attributes
87    nonbool: values of non-boolean attributes
88    There is a maximum of 32 attributes total.  */
89 #define CGEN_ATTR_TYPE(n) \
90 const struct { unsigned char num_nonbools; \
91 	       unsigned int bool; \
92 	       unsigned int nonbool[(n) ? (n) : 1]; }
93 
94 /* Given an attribute number, return its mask.  */
95 #define CGEN_ATTR_MASK(attr) (1 << (attr))
96 
97 /* Return the value of boolean attribute ATTR in ATTRS.  */
98 #define CGEN_BOOL_ATTR(attrs, attr) \
99 ((CGEN_ATTR_MASK (attr) & (attrs)) != 0)
100 
101 /* Return value of attribute ATTR in ATTR_TABLE for OBJ.
102    OBJ is a pointer to the entity that has the attributes.
103    It's not used at present but is reserved for future purposes.  */
104 #define CGEN_ATTR_VALUE(obj, attr_table, attr) \
105 ((unsigned int) (attr) < (attr_table)->num_nonbools \
106  ? ((attr_table)->nonbool[attr]) \
107  : (((attr_table)->bool & (1 << (attr))) != 0))
108 
109 /* Attribute name/value tables.
110    These are used to assist parsing of descriptions at runtime.  */
111 
112 typedef struct
113 {
114   const char * name;
115   int          value;
116 } CGEN_ATTR_ENTRY;
117 
118 /* For each domain (fld,operand,insn), list of attributes.  */
119 
120 typedef struct
121 {
122   const char *            name;
123   /* NULL for boolean attributes.  */
124   const CGEN_ATTR_ENTRY * vals;
125 } CGEN_ATTR_TABLE;
126 
127 /* Parse result (also extraction result).
128 
129    The result of parsing an insn is stored here.
130    To generate the actual insn, this is passed to the insert handler.
131    When printing an insn, the result of extraction is stored here.
132    To print the insn, this is passed to the print handler.
133 
134    It is machine generated so we don't define it here,
135    but we do need a forward decl for the handler fns.
136 
137    There is one member for each possible field in the insn.
138    The type depends on the field.
139    Also recorded here is the computed length of the insn for architectures
140    where it varies.
141 */
142 
143 typedef struct cgen_fields CGEN_FIELDS;
144 
145 /* Total length of the insn, as recorded in the `fields' struct.  */
146 /* ??? The field insert handler has lots of opportunities for optimization
147    if it ever gets inlined.  On architectures where insns all have the same
148    size, may wish to detect that and make this macro a constant - to allow
149    further optimizations.  */
150 #define CGEN_FIELDS_BITSIZE(fields) ((fields)->length)
151 
152 /* Associated with each insn or expression is a set of "handlers" for
153    performing operations like parsing, printing, etc.  */
154 
155 /* Forward decl.  */
156 typedef struct cgen_insn CGEN_INSN;
157 
158 /* Parse handler.
159    The first argument is a pointer to a struct describing the insn being
160    parsed.
161    The second argument is a pointer to a pointer to the text being parsed.
162    The third argument is a pointer to a cgen_fields struct
163    in which the results are placed.
164    If the expression is successfully parsed, the pointer to the text is
165    updated.  If not it is left alone.
166    The result is NULL if success or an error message.  */
167 typedef const char * (cgen_parse_fn) PARAMS ((const struct cgen_insn *,
168 					      const char **,
169 					      CGEN_FIELDS *));
170 
171 /* Print handler.
172    The first argument is a pointer to the disassembly info.
173    Eg: disassemble_info.  It's defined as `PTR' so this file can be included
174    without dis-asm.h.
175    The second argument is a pointer to a struct describing the insn being
176    printed.
177    The third argument is a pointer to a cgen_fields struct.
178    The fourth argument is the pc value of the insn.
179    The fifth argument is the length of the insn, in bytes.  */
180 /* Don't require bfd.h unnecessarily.  */
181 #ifdef BFD_VERSION
182 typedef void (cgen_print_fn) PARAMS ((PTR, const struct cgen_insn *,
183 				      CGEN_FIELDS *, bfd_vma, int));
184 #else
185 typedef void (cgen_print_fn) ();
186 #endif
187 
188 /* Insert handler.
189    The first argument is a pointer to a struct describing the insn being
190    parsed.
191    The second argument is a pointer to a cgen_fields struct
192    from which the values are fetched.
193    The third argument is a pointer to a buffer in which to place the insn.
194    The result is an error message or NULL if success.  */
195 typedef const char * (cgen_insert_fn) PARAMS ((const struct cgen_insn *,
196 					       CGEN_FIELDS *, cgen_insn_t *));
197 
198 /* Extract handler.
199    The first argument is a pointer to a struct describing the insn being
200    parsed.
201    The second argument is a pointer to a struct controlling extraction
202    (only used for variable length insns).
203    The third argument is the first CGEN_BASE_INSN_SIZE bytes.
204    The fourth argument is a pointer to a cgen_fields struct
205    in which the results are placed.
206    The result is the length of the insn or zero if not recognized.  */
207 typedef int (cgen_extract_fn) PARAMS ((const struct cgen_insn *,
208 				       void *, cgen_insn_t,
209 				       CGEN_FIELDS *));
210 
211 /* The `parse' and `insert' fields are indices into these tables.
212    The elements are pointer to specialized handler functions.
213    Element 0 is special, it means use the default handler.  */
214 extern cgen_parse_fn * CGEN_SYM (parse_handlers) [];
215 #define CGEN_PARSE_FN(x) (CGEN_SYM (parse_handlers)[(x)->base.parse])
216 extern cgen_insert_fn * CGEN_SYM (insert_handlers) [];
217 #define CGEN_INSERT_FN(x) (CGEN_SYM (insert_handlers)[(x)->base.insert])
218 
219 /* Likewise for the `extract' and `print' fields.  */
220 extern cgen_extract_fn * CGEN_SYM (extract_handlers) [];
221 #define CGEN_EXTRACT_FN(x) (CGEN_SYM (extract_handlers)[(x)->base.extract])
222 extern cgen_print_fn * CGEN_SYM (print_handlers) [];
223 #define CGEN_PRINT_FN(x) (CGEN_SYM (print_handlers)[(x)->base.print])
224 
225 /* Base class of parser/printer.
226    (Don't read too much into the use of the phrase "base class".
227    It's a name I'm using to organize my thoughts.)
228 
229    Instructions and expressions all share this data in common.
230    It's a collection of the common elements needed to parse, insert, extract,
231    and print each of them.  */
232 
233 struct cgen_base
234 {
235   /* Indices into the handler tables.
236      We could use pointers here instead, but in the case of the insn table,
237      90% of them would be identical and that's a lot of redundant data.
238      0 means use the default (what the default is is up to the code).  */
239   unsigned char parse, insert, extract, print;
240 };
241 
242 /* Assembler interface.
243 
244    The interface to the assembler is intended to be clean in the sense that
245    libopcodes.a is a standalone entity and could be used with any assembler.
246    Not that one would necessarily want to do that but rather that it helps
247    keep a clean interface.  The interface will obviously be slanted towards
248    GAS, but at least it's a start.
249 
250    Parsing is controlled by the assembler which calls
251    CGEN_SYM (assemble_insn).  If it can parse and build the entire insn
252    it doesn't call back to the assembler.  If it needs/wants to call back
253    to the assembler, (*cgen_parse_operand_fn) is called which can either
254 
255    - return a number to be inserted in the insn
256    - return a "register" value to be inserted
257      (the register might not be a register per pe)
258    - queue the argument and return a marker saying the expression has been
259      queued (eg: a fix-up)
260    - return an error message indicating the expression wasn't recognizable
261 
262    The result is an error message or NULL for success.
263    The parsed value is stored in the bfd_vma *.  */
264 
265 /* Values for indicating what the caller wants.  */
266 enum cgen_parse_operand_type
267 {
268   CGEN_PARSE_OPERAND_INIT,
269   CGEN_PARSE_OPERAND_INTEGER,
270   CGEN_PARSE_OPERAND_ADDRESS
271 };
272 
273 /* Values for indicating what was parsed.
274    ??? Not too useful at present but in time.  */
275 enum cgen_parse_operand_result
276 {
277   CGEN_PARSE_OPERAND_RESULT_NUMBER,
278   CGEN_PARSE_OPERAND_RESULT_REGISTER,
279   CGEN_PARSE_OPERAND_RESULT_QUEUED,
280   CGEN_PARSE_OPERAND_RESULT_ERROR
281 };
282 
283 /* Don't require bfd.h unnecessarily.  */
284 #ifdef BFD_VERSION
285 extern const char * (*cgen_parse_operand_fn)
286      PARAMS ((enum cgen_parse_operand_type, const char **, int, int,
287 	      enum cgen_parse_operand_result *, bfd_vma *));
288 #endif
289 
290 /* Called before trying to match a table entry with the insn.  */
291 void cgen_init_parse_operand PARAMS ((void));
292 
293 /* Called from <cpu>-asm.c to initialize operand parsing.  */
294 
295 /* These are GAS specific.  They're not here as part of the interface,
296    but rather that we need to put them somewhere.  */
297 
298 /* Call this from md_assemble to initialize the assembler callback.  */
299 void cgen_asm_init_parse PARAMS ((void));
300 
301 /* Don't require bfd.h unnecessarily.  */
302 #ifdef BFD_VERSION
303 /* The result is an error message or NULL for success.
304    The parsed value is stored in the bfd_vma *.  */
305 const char * cgen_parse_operand PARAMS ((enum cgen_parse_operand_type,
306 					 const char **, int, int,
307 					 enum cgen_parse_operand_result *,
308 					 bfd_vma *));
309 #endif
310 
311 void cgen_save_fixups PARAMS ((void));
312 void cgen_restore_fixups PARAMS ((void));
313 void cgen_swap_fixups PARAMS ((void));
314 
315 /* Add a register to the assembler's hash table.
316    This makes lets GAS parse registers for us.
317    ??? This isn't currently used, but it could be in the future.  */
318 void cgen_asm_record_register PARAMS ((char *, int));
319 
320 /* After CGEN_SYM (assemble_insn) is done, this is called to
321    output the insn and record any fixups.  The address of the
322    assembled instruction is returned in case it is needed by
323    the caller.  */
324 char * cgen_asm_finish_insn PARAMS ((const struct cgen_insn *, cgen_insn_t *,
325 				   unsigned int));
326 
327 /* Operand values (keywords, integers, symbols, etc.)  */
328 
329 /* Types of assembler elements.  */
330 
331 enum cgen_asm_type
332 {
333   CGEN_ASM_KEYWORD, CGEN_ASM_MAX
334 };
335 
336 /* List of hardware elements.  */
337 
338 typedef struct cgen_hw_entry
339 {
340   /* The type of this entry, one of `enum hw_type'.
341      This is an int and not the enum as the latter may not be declared yet.  */
342   int                          type;
343   const struct cgen_hw_entry * next;
344   char *                       name;
345   enum cgen_asm_type           asm_type;
346   PTR                          asm_data;
347 } CGEN_HW_ENTRY;
348 
349 const CGEN_HW_ENTRY * cgen_hw_lookup PARAMS ((const char *));
350 
351 /* This struct is used to describe things like register names, etc.  */
352 
353 typedef struct cgen_keyword_entry
354 {
355   /* Name (as in register name).  */
356   char * name;
357 
358   /* Value (as in register number).
359      The value cannot be -1 as that is used to indicate "not found".
360      IDEA: Have "FUNCTION" attribute? [function is called to fetch value].  */
361   int value;
362 
363   /* Attributes.
364      This should, but technically needn't, appear last.  It is a variable sized
365      array in that one architecture may have 1 nonbool attribute and another
366      may have more.  Having this last means the non-architecture specific code
367      needn't care.  */
368   /* ??? Moving this last should be done by treating keywords like insn lists
369      and moving the `next' fields into a CGEN_KEYWORD_LIST struct.  */
370   /* FIXME: Not used yet.  */
371 #ifndef CGEN_KEYWORD_NBOOL_ATTRS
372 #define CGEN_KEYWORD_NBOOL_ATTRS 1
373 #endif
374   CGEN_ATTR_TYPE (CGEN_KEYWORD_NBOOL_ATTRS) attrs;
375 
376   /* Next name hash table entry.  */
377   struct cgen_keyword_entry *next_name;
378   /* Next value hash table entry.  */
379   struct cgen_keyword_entry *next_value;
380 } CGEN_KEYWORD_ENTRY;
381 
382 /* Top level struct for describing a set of related keywords
383    (e.g. register names).
384 
385    This struct supports runtime entry of new values, and hashed lookups.  */
386 
387 typedef struct cgen_keyword
388 {
389   /* Pointer to initial [compiled in] values.  */
390   CGEN_KEYWORD_ENTRY * init_entries;
391 
392   /* Number of entries in `init_entries'.  */
393   unsigned int num_init_entries;
394 
395   /* Hash table used for name lookup.  */
396   CGEN_KEYWORD_ENTRY ** name_hash_table;
397 
398   /* Hash table used for value lookup.  */
399   CGEN_KEYWORD_ENTRY ** value_hash_table;
400 
401   /* Number of entries in the hash_tables.  */
402   unsigned int hash_table_size;
403 
404   /* Pointer to null keyword "" entry if present.  */
405   const CGEN_KEYWORD_ENTRY * null_entry;
406 } CGEN_KEYWORD;
407 
408 /* Structure used for searching.  */
409 
410 typedef struct
411 {
412   /* Table being searched.  */
413   const CGEN_KEYWORD * table;
414 
415   /* Specification of what is being searched for.  */
416   const char * spec;
417 
418   /* Current index in hash table.  */
419   unsigned int current_hash;
420 
421   /* Current element in current hash chain.  */
422   CGEN_KEYWORD_ENTRY * current_entry;
423 } CGEN_KEYWORD_SEARCH;
424 
425 /* Lookup a keyword from its name.  */
426 const CGEN_KEYWORD_ENTRY * cgen_keyword_lookup_name
427   PARAMS ((CGEN_KEYWORD *, const char *));
428 /* Lookup a keyword from its value.  */
429 const CGEN_KEYWORD_ENTRY * cgen_keyword_lookup_value
430   PARAMS ((CGEN_KEYWORD *, int));
431 /* Add a keyword.  */
432 void cgen_keyword_add PARAMS ((CGEN_KEYWORD *, CGEN_KEYWORD_ENTRY *));
433 /* Keyword searching.
434    This can be used to retrieve every keyword, or a subset.  */
435 CGEN_KEYWORD_SEARCH cgen_keyword_search_init
436   PARAMS ((CGEN_KEYWORD *, const char *));
437 const CGEN_KEYWORD_ENTRY *cgen_keyword_search_next
438   PARAMS ((CGEN_KEYWORD_SEARCH *));
439 
440 /* Operand value support routines.  */
441 /* FIXME: some of the long's here will need to be bfd_vma or some such.  */
442 
443 const char * cgen_parse_keyword PARAMS ((const char **,
444 					 CGEN_KEYWORD *,
445 					 long *));
446 const char * cgen_parse_signed_integer PARAMS ((const char **, int, long *));
447 const char * cgen_parse_unsigned_integer PARAMS ((const char **, int,
448 						  unsigned long *));
449 const char * cgen_parse_address PARAMS ((const char **, int, int,
450 					 enum cgen_parse_operand_result *,
451 					 long *));
452 const char * cgen_validate_signed_integer PARAMS ((long, long, long));
453 const char * cgen_validate_unsigned_integer PARAMS ((unsigned long,
454 						     unsigned long,
455 						     unsigned long));
456 
457 /* Operand modes.  */
458 
459 /* ??? This duplicates the values in arch.h.  Revisit.
460    These however need the CGEN_ prefix [as does everything in this file].  */
461 /* ??? Targets may need to add their own modes so we may wish to move this
462    to <arch>-opc.h, or add a hook.  */
463 
464 enum cgen_mode {
465   CGEN_MODE_VOID, /* FIXME: rename simulator's VM to VOID */
466   CGEN_MODE_BI, CGEN_MODE_QI, CGEN_MODE_HI, CGEN_MODE_SI, CGEN_MODE_DI,
467   CGEN_MODE_UBI, CGEN_MODE_UQI, CGEN_MODE_UHI, CGEN_MODE_USI, CGEN_MODE_UDI,
468   CGEN_MODE_SF, CGEN_MODE_DF, CGEN_MODE_XF, CGEN_MODE_TF,
469   CGEN_MODE_MAX
470 };
471 
472 /* FIXME: Until simulator is updated.  */
473 #define CGEN_MODE_VM CGEN_MODE_VOID
474 
475 /* This struct defines each entry in the operand table.  */
476 
477 typedef struct cgen_operand
478 {
479   /* Name as it appears in the syntax string.  */
480   char * name;
481 
482   /* The hardware element associated with this operand.  */
483   const CGEN_HW_ENTRY *hw;
484 
485   /* FIXME: We don't yet record ifield definitions, which we should.
486      When we do it might make sense to delete start/length (since they will
487      be duplicated in the ifield's definition) and replace them with a
488      pointer to the ifield entry.  Note that as more complicated situations
489      need to be handled, going more and more with an OOP paradigm will help
490      keep the complication under control.  Of course, this was the goal from
491      the start, but getting there in one step was too much too soon.  */
492 
493   /* Bit position (msb of first byte = bit 0).
494      This is just a hint, and may be unused in more complex operands.
495      May be unused for a modifier.  */
496   unsigned char start;
497 
498   /* The number of bits in the operand.
499      This is just a hint, and may be unused in more complex operands.
500      May be unused for a modifier.  */
501   unsigned char length;
502 
503 #if 0 /* ??? Interesting idea but relocs tend to get too complicated,
504 	 and ABI dependent, for simple table lookups to work.  */
505   /* Ideally this would be the internal (external?) reloc type.  */
506   int reloc_type;
507 #endif
508 
509   /* Attributes.
510      This should, but technically needn't, appear last.  It is a variable sized
511      array in that one architecture may have 1 nonbool attribute and another
512      may have more.  Having this last means the non-architecture specific code
513      needn't care, now or tomorrow.  */
514 #ifndef CGEN_OPERAND_NBOOL_ATTRS
515 #define CGEN_OPERAND_NBOOL_ATTRS 1
516 #endif
517   CGEN_ATTR_TYPE (CGEN_OPERAND_NBOOL_ATTRS) attrs;
518 #define CGEN_OPERAND_ATTRS(operand) (&(operand)->attrs)
519 } CGEN_OPERAND;
520 
521 /* Return value of attribute ATTR in OPERAND.  */
522 #define CGEN_OPERAND_ATTR(operand, attr) \
523 CGEN_ATTR_VALUE (operand, CGEN_OPERAND_ATTRS (operand), attr)
524 
525 /* The operand table is currently a very static entity.  */
526 extern const CGEN_OPERAND CGEN_SYM (operand_table)[];
527 
528 enum cgen_operand_type;
529 
530 #define CGEN_OPERAND_INDEX(operand) ((int) ((operand) - CGEN_SYM (operand_table)))
531 /* FIXME: Rename, cpu-opc.h defines this as the typedef of the enum.  */
532 #define CGEN_OPERAND_TYPE(operand) ((enum cgen_operand_type) CGEN_OPERAND_INDEX (operand))
533 #define CGEN_OPERAND_ENTRY(n) (& CGEN_SYM (operand_table) [n])
534 
535 /* Types of parse/insert/extract/print cover-fn handlers.  */
536 /* FIXME: move opindex first to match caller.  */
537 /* FIXME: also need types of insert/extract/print fns.  */
538 /* FIXME: not currently used as type of 3rd arg varies.  */
539 typedef const char * (CGEN_PARSE_OPERAND_FN) PARAMS ((const char **, int,
540 						      long *));
541 
542 /* Instruction operand instances.
543 
544    For each instruction, a list of the hardware elements that are read and
545    written are recorded.  */
546 
547 /* The type of the instance.  */
548 enum cgen_operand_instance_type {
549   /* End of table marker.  */
550   CGEN_OPERAND_INSTANCE_END = 0,
551   CGEN_OPERAND_INSTANCE_INPUT, CGEN_OPERAND_INSTANCE_OUTPUT
552 };
553 
554 typedef struct
555 {
556   /* The type of this operand.  */
557   enum cgen_operand_instance_type type;
558 #define CGEN_OPERAND_INSTANCE_TYPE(opinst) ((opinst)->type)
559 
560   /* The hardware element referenced.  */
561   const CGEN_HW_ENTRY *hw;
562 #define CGEN_OPERAND_INSTANCE_HW(opinst) ((opinst)->hw)
563 
564   /* The mode in which the operand is being used.  */
565   enum cgen_mode mode;
566 #define CGEN_OPERAND_INSTANCE_MODE(opinst) ((opinst)->mode)
567 
568   /* The operand table entry or NULL if there is none (i.e. an explicit
569      hardware reference).  */
570   const CGEN_OPERAND *operand;
571 #define CGEN_OPERAND_INSTANCE_OPERAND(opinst) ((opinst)->operand)
572 
573   /* If `operand' is NULL, the index (e.g. into array of registers).  */
574   int index;
575 #define CGEN_OPERAND_INSTANCE_INDEX(opinst) ((opinst)->index)
576 } CGEN_OPERAND_INSTANCE;
577 
578 /* Syntax string.
579 
580    Each insn format and subexpression has one of these.
581 
582    The syntax "string" consists of characters (n > 0 && n < 128), and operand
583    values (n >= 128), and is terminated by 0.  Operand values are 128 + index
584    into the operand table.  The operand table doesn't exist in C, per se, as
585    the data is recorded in the parse/insert/extract/print switch statements. */
586 
587 #ifndef CGEN_MAX_SYNTAX_BYTES
588 #define CGEN_MAX_SYNTAX_BYTES 16
589 #endif
590 
591 typedef struct
592 {
593   unsigned char syntax[CGEN_MAX_SYNTAX_BYTES];
594 } CGEN_SYNTAX;
595 
596 #define CGEN_SYNTAX_STRING(syn) (syn->syntax)
597 #define CGEN_SYNTAX_CHAR_P(c) ((c) < 128)
598 #define CGEN_SYNTAX_CHAR(c) (c)
599 #define CGEN_SYNTAX_FIELD(c) ((c) - 128)
600 #define CGEN_SYNTAX_MAKE_FIELD(c) ((c) + 128)
601 
602 /* ??? I can't currently think of any case where the mnemonic doesn't come
603    first [and if one ever doesn't building the hash tables will be tricky].
604    However, we treat mnemonics as just another operand of the instruction.
605    A value of 1 means "this is where the mnemonic appears".  1 isn't
606    special other than it's a non-printable ASCII char.  */
607 #define CGEN_SYNTAX_MNEMONIC       1
608 #define CGEN_SYNTAX_MNEMONIC_P(ch) ((ch) == CGEN_SYNTAX_MNEMONIC)
609 
610 /* Instruction formats.
611 
612    Instructions are grouped by format.  Associated with an instruction is its
613    format.  Each opcode table entry contains a format table entry.
614    ??? There is usually very few formats compared with the number of insns,
615    so one can reduce the size of the opcode table by recording the format table
616    as a separate entity.  Given that we currently don't, format table entries
617    are also distinguished by their operands.  This increases the size of the
618    table, but reduces the number of tables.  It's all minutiae anyway so it
619    doesn't really matter [at this point in time].
620 
621    ??? Support for variable length ISA's is wip.  */
622 
623 typedef struct
624 {
625   /* Length that MASK and VALUE have been calculated to
626      [VALUE is recorded elsewhere].
627      Normally it is CGEN_BASE_INSN_BITSIZE.  On [V]LIW architectures where
628      the base insn size may be larger than the size of an insn, this field is
629      less than CGEN_BASE_INSN_BITSIZE.  */
630   unsigned char mask_length;
631 
632   /* Total length of instruction, in bits.  */
633   unsigned char length;
634 
635   /* Mask to apply to the first MASK_LENGTH bits.
636      Each insn's value is stored with the insn.
637      The first step in recognizing an insn for disassembly is
638      (opcode & mask) == value.  */
639   unsigned int mask;
640 } CGEN_FORMAT;
641 
642 /* This struct defines each entry in the instruction table.  */
643 
644 struct cgen_insn
645 {
646   /* ??? Further table size reductions can be had by moving this element
647      either to the format table or to a separate table of its own.  Not
648      sure this is desirable yet.  */
649   struct cgen_base base;
650 
651 /* Given a pointer to a cgen_insn struct, return a pointer to `base'.  */
652 #define CGEN_INSN_BASE(insn) (&(insn)->base)
653 
654   /* Name of entry (that distinguishes it from all other entries).
655      This is used, for example, in simulator profiling results.  */
656   /* ??? If mnemonics have operands, try to print full mnemonic.  */
657   const char * name;
658 #define CGEN_INSN_NAME(insn) ((insn)->name)
659 
660   /* Mnemonic.  This is used when parsing and printing the insn.
661      In the case of insns that have operands on the mnemonics, this is
662      only the constant part.  E.g. for conditional execution of an `add' insn,
663      where the full mnemonic is addeq, addne, etc., this is only "add".  */
664   const char * mnemonic;
665 #define CGEN_INSN_MNEMONIC(insn) ((insn)->mnemonic)
666 
667   /* Syntax string.  */
668   const CGEN_SYNTAX syntax;
669 #define CGEN_INSN_SYNTAX(insn) (& (insn)->syntax)
670 
671   /* Format entry.  */
672   const CGEN_FORMAT format;
673 #define CGEN_INSN_MASK_BITSIZE(insn) ((insn)->format.mask_length)
674 #define CGEN_INSN_BITSIZE(insn) ((insn)->format.length)
675 
676   /* Instruction opcode value.  */
677   unsigned int value;
678 #define CGEN_INSN_VALUE(insn) ((insn)->value)
679 #define CGEN_INSN_MASK(insn) ((insn)->format.mask)
680 
681   /* Pointer to NULL entry terminated table of operands used,
682      or NULL if none.  */
683   const CGEN_OPERAND_INSTANCE *operands;
684 #define CGEN_INSN_OPERANDS(insn) ((insn)->operands)
685 
686   /* Attributes.
687      This must appear last.  It is a variable sized array in that one
688      architecture may have 1 nonbool attribute and another may have more.
689      Having this last means the non-architecture specific code needn't
690      care.  */
691 #ifndef CGEN_INSN_NBOOL_ATTRS
692 #define CGEN_INSN_NBOOL_ATTRS 1
693 #endif
694   CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) attrs;
695 #define CGEN_INSN_ATTRS(insn) (&(insn)->attrs)
696 /* Return value of attribute ATTR in INSN.  */
697 #define CGEN_INSN_ATTR(insn, attr) \
698 CGEN_ATTR_VALUE (insn, CGEN_INSN_ATTRS (insn), attr)
699 };
700 
701 /* Instruction lists.
702    This is used for adding new entries and for creating the hash lists.  */
703 
704 typedef struct cgen_insn_list
705 {
706   struct cgen_insn_list * next;
707   const CGEN_INSN * insn;
708 } CGEN_INSN_LIST;
709 
710 /* The table of instructions.  */
711 
712 typedef struct
713 {
714   /* Pointer to initial [compiled in] entries.  */
715   const CGEN_INSN * init_entries;
716 
717   /* Size of an entry (since the attribute member is variable sized).  */
718   unsigned int entry_size;
719 
720   /* Number of entries in `init_entries', including trailing NULL entry.  */
721   unsigned int num_init_entries;
722 
723   /* Values added at runtime.  */
724   CGEN_INSN_LIST * new_entries;
725 
726   /* Assembler hash function.  */
727   unsigned int (* asm_hash) PARAMS ((const char *));
728 
729   /* Number of entries in assembler hash table.  */
730   unsigned int asm_hash_table_size;
731 
732   /* Disassembler hash function.  */
733   unsigned int (* dis_hash) PARAMS ((const char *, unsigned long));
734 
735   /* Number of entries in disassembler hash table.  */
736   unsigned int dis_hash_table_size;
737 } CGEN_INSN_TABLE;
738 
739 /* ??? This is currently used by the simulator.
740    We want this to be fast and the simulator currently doesn't handle
741    runtime added instructions so this is ok.  An alternative would be to
742    store the index in the table.  */
743 extern const CGEN_INSN CGEN_SYM (insn_table_entries)[];
744 #define CGEN_INSN_INDEX(insn) ((int) ((insn) - CGEN_SYM (insn_table_entries)))
745 #define CGEN_INSN_ENTRY(n) (& CGEN_SYM (insn_table_entries) [n])
746 
747 /* Return number of instructions.  This includes any added at runtime.  */
748 
749 int cgen_insn_count PARAMS ((void));
750 
751 /* The assembler insn table is hashed based on some function of the mnemonic
752    (the actually hashing done is up to the target, but we provide a few
753    examples like the first letter or a function of the entire mnemonic).
754    The index of each entry is the index of the corresponding table entry.
755    The value of each entry is the index of the next entry, with a 0
756    terminating (thus the first entry is reserved).  */
757 
758 #ifndef CGEN_ASM_HASH
759 #ifdef CGEN_MNEMONIC_OPERANDS
760 #define CGEN_ASM_HASH_SIZE 127
761 #define CGEN_ASM_HASH(string) (*(unsigned char *) (string) % CGEN_ASM_HASH_SIZE)
762 #else
763 #define CGEN_ASM_HASH_SIZE 128
764 #define CGEN_ASM_HASH(string) (*(unsigned char *) (string) % CGEN_ASM_HASH_SIZE) /*FIXME*/
765 #endif
766 #endif
767 
768 unsigned int CGEN_SYM (asm_hash_insn) PARAMS ((const char *));
769 CGEN_INSN_LIST * cgen_asm_lookup_insn PARAMS ((const char *));
770 #define CGEN_ASM_LOOKUP_INSN(insn) cgen_asm_lookup_insn (insn)
771 #define CGEN_ASM_NEXT_INSN(insn) ((insn)->next)
772 
773 /* The disassembler insn table is hashed based on some function of machine
774    instruction (the actually hashing done is up to the target).  */
775 
776 /* It doesn't make much sense to provide a default here,
777    but while this is under development we do.
778    BUFFER is a pointer to the bytes of the insn.
779    INSN is the first CGEN_BASE_INSN_SIZE bytes as an int in host order.  */
780 #ifndef CGEN_DIS_HASH
781 #define CGEN_DIS_HASH_SIZE 256
782 #define CGEN_DIS_HASH(buffer, insn) (*(unsigned char *) (buffer))
783 #endif
784 
785 unsigned int CGEN_SYM (dis_hash_insn) PARAMS ((const char *, unsigned long));
786 CGEN_INSN_LIST * cgen_dis_lookup_insn PARAMS ((const char *, unsigned long));
787 #define CGEN_DIS_LOOKUP_INSN(buf, insn) cgen_dis_lookup_insn (buf, insn)
788 #define CGEN_DIS_NEXT_INSN(insn) ((insn)->next)
789 
790 /* Top level structures and functions.  */
791 
792 typedef struct
793 {
794   const CGEN_HW_ENTRY *  hw_list;
795   /*CGEN_OPERAND_TABLE * operand_table; - FIXME:wip */
796   CGEN_INSN_TABLE *      insn_table;
797 } CGEN_OPCODE_DATA;
798 
799 /* Each CPU has one of these.  */
800 extern CGEN_OPCODE_DATA CGEN_SYM (opcode_data);
801 
802 /* Global state access macros.
803    Some of these are tucked away and accessed with cover fns.
804    Simpler things like the current machine and endian are not.  */
805 
806 extern int cgen_current_machine;
807 #define CGEN_CURRENT_MACHINE cgen_current_machine
808 
809 extern enum cgen_endian cgen_current_endian;
810 #define CGEN_CURRENT_ENDIAN cgen_current_endian
811 
812 /* Prototypes of major functions.  */
813 
814 /* Set the current cpu (+ mach number, endian, etc.).  */
815 void cgen_set_cpu PARAMS ((CGEN_OPCODE_DATA *, int, enum cgen_endian));
816 
817 /* Initialize the assembler, disassembler.  */
818 void cgen_asm_init PARAMS ((void));
819 void cgen_dis_init PARAMS ((void));
820 
821 /* `init_tables' must be called before `xxx_supported'.  */
822 void CGEN_SYM (init_tables) PARAMS ((int));
823 void CGEN_SYM (init_asm) PARAMS ((int, enum cgen_endian));
824 void CGEN_SYM (init_dis) PARAMS ((int, enum cgen_endian));
825 void CGEN_SYM (init_parse) PARAMS ((void));
826 void CGEN_SYM (init_print) PARAMS ((void));
827 void CGEN_SYM (init_insert) PARAMS ((void));
828 void CGEN_SYM (init_extract) PARAMS ((void));
829 
830 /* FIXME: This prototype is wrong ifndef CGEN_INT_INSN.
831    Furthermore, ifdef CGEN_INT_INSN, the insn is created in
832    target byte order (in which case why use int's at all).
833    Perhaps replace cgen_insn_t * with char *?  */
834 const struct cgen_insn *
835 CGEN_SYM (assemble_insn) PARAMS ((const char *, CGEN_FIELDS *,
836 				  cgen_insn_t *, char **));
837 #if 0 /* old */
838 int CGEN_SYM (insn_supported) PARAMS ((const struct cgen_insn *));
839 int CGEN_SYM (opval_supported) PARAMS ((const struct cgen_opval *));
840 #endif
841 
842 extern const CGEN_KEYWORD  CGEN_SYM (operand_mach);
843 int CGEN_SYM (get_mach) PARAMS ((const char *));
844 
845 const CGEN_INSN *
846 CGEN_SYM (get_insn_operands) PARAMS ((const CGEN_INSN *, cgen_insn_t,
847 				      int, int *));
848 const CGEN_INSN *
849 CGEN_SYM (lookup_insn) PARAMS ((const CGEN_INSN *, cgen_insn_t,
850 				int, CGEN_FIELDS *, int));
851 
852 CGEN_INLINE void
853 CGEN_SYM (put_operand) PARAMS ((int, const long *,
854 				CGEN_FIELDS *));
855 CGEN_INLINE long
856 CGEN_SYM (get_operand) PARAMS ((int, const CGEN_FIELDS *));
857 
858 const char *
859 CGEN_SYM (parse_operand) PARAMS ((int, const char **, CGEN_FIELDS *));
860 
861 const char *
862 CGEN_SYM (insert_operand) PARAMS ((int, CGEN_FIELDS *, char *));
863 
864 /* Default insn parser, printer.  */
865 extern cgen_parse_fn CGEN_SYM (parse_insn);
866 extern cgen_insert_fn CGEN_SYM (insert_insn);
867 extern cgen_extract_fn CGEN_SYM (extract_insn);
868 extern cgen_print_fn CGEN_SYM (print_insn);
869 
870 /* Read in a cpu description file.  */
871 const char * cgen_read_cpu_file PARAMS ((const char *));
872 
873 #endif /* CGEN_H */
874