+#define CGEN_CPU_PARSE_OPERAND(cd) ((cd)->parse_operand)
+#define CGEN_CPU_INSERT_OPERAND(cd) ((cd)->insert_operand)
+#define CGEN_CPU_EXTRACT_OPERAND(cd) ((cd)->extract_operand)
+#define CGEN_CPU_PRINT_OPERAND(cd) ((cd)->print_operand)
+
+ /* Size of CGEN_FIELDS struct. */
+ unsigned int sizeof_fields;
+#define CGEN_CPU_SIZEOF_FIELDS(cd) ((cd)->sizeof_fields)
+
+ /* Set the bitsize field. */
+ void (*set_fields_bitsize) PARAMS ((CGEN_FIELDS *fields_, int size_));
+#define CGEN_CPU_SET_FIELDS_BITSIZE(cd) ((cd)->set_fields_bitsize)
+
+ /* CGEN_FIELDS accessors. */
+ int (*get_int_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_));
+ void (*set_int_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, int value_));
+#ifdef BFD_VERSION
+ bfd_vma (*get_vma_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_));
+ void (*set_vma_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, bfd_vma value_));
+#else
+ long (*get_vma_operand) ();
+ void (*set_vma_operand) ();
+#endif
+#define CGEN_CPU_GET_INT_OPERAND(cd) ((cd)->get_int_operand)
+#define CGEN_CPU_SET_INT_OPERAND(cd) ((cd)->set_int_operand)
+#define CGEN_CPU_GET_VMA_OPERAND(cd) ((cd)->get_vma_operand)
+#define CGEN_CPU_SET_VMA_OPERAND(cd) ((cd)->set_vma_operand)
+
+ /* Instruction parse/insert/extract/print handlers. */
+ /* FIXME: make these types uppercase. */
+ cgen_parse_fn * const *parse_handlers;
+ cgen_insert_fn * const *insert_handlers;
+ cgen_extract_fn * const *extract_handlers;
+ cgen_print_fn * const *print_handlers;
+#define CGEN_PARSE_FN(cd, insn) (cd->parse_handlers[(insn)->opcode->handlers.parse])
+#define CGEN_INSERT_FN(cd, insn) (cd->insert_handlers[(insn)->opcode->handlers.insert])
+#define CGEN_EXTRACT_FN(cd, insn) (cd->extract_handlers[(insn)->opcode->handlers.extract])
+#define CGEN_PRINT_FN(cd, insn) (cd->print_handlers[(insn)->opcode->handlers.print])
+
+ /* Return non-zero if insn should be added to hash table. */
+ int (* asm_hash_p) PARAMS ((const CGEN_INSN *));
+
+ /* Assembler hash function. */
+ unsigned int (* asm_hash) PARAMS ((const char *));
+
+ /* Number of entries in assembler hash table. */
+ unsigned int asm_hash_size;
+
+ /* Return non-zero if insn should be added to hash table. */
+ int (* dis_hash_p) PARAMS ((const CGEN_INSN *));
+
+ /* Disassembler hash function. */
+ unsigned int (* dis_hash) PARAMS ((const char *, CGEN_INSN_INT));
+
+ /* Number of entries in disassembler hash table. */
+ unsigned int dis_hash_size;
+
+ /* Assembler instruction hash table. */
+ CGEN_INSN_LIST **asm_hash_table;
+ CGEN_INSN_LIST *asm_hash_table_entries;
+
+ /* Disassembler instruction hash table. */
+ CGEN_INSN_LIST **dis_hash_table;
+ CGEN_INSN_LIST *dis_hash_table_entries;
+
+ /* This field could be turned into a bitfield if room for other flags is needed. */
+ unsigned int signed_overflow_ok_p;
+
+} CGEN_CPU_TABLE;
+
+/* wip */
+#ifndef CGEN_WORD_ENDIAN
+#define CGEN_WORD_ENDIAN(cd) CGEN_CPU_ENDIAN (cd)
+#endif
+#ifndef CGEN_INSN_WORD_ENDIAN
+#define CGEN_INSN_WORD_ENDIAN(cd) CGEN_CPU_INSN_ENDIAN (cd)
+#endif
+\f
+/* Prototypes of major functions. */
+/* FIXME: Move more CGEN_SYM-defined functions into CGEN_CPU_DESC.
+ Not the init fns though, as that would drag in things that mightn't be
+ used and might not even exist. */
+
+/* Argument types to cpu_open. */
+
+enum cgen_cpu_open_arg {
+ CGEN_CPU_OPEN_END,
+ /* Select instruction set(s), arg is bitmap or 0 meaning "unspecified". */
+ CGEN_CPU_OPEN_ISAS,
+ /* Select machine(s), arg is bitmap or 0 meaning "unspecified". */
+ CGEN_CPU_OPEN_MACHS,
+ /* Select machine, arg is mach's bfd name.
+ Multiple machines can be specified by repeated use. */
+ CGEN_CPU_OPEN_BFDMACH,
+ /* Select endian, arg is CGEN_ENDIAN_*. */
+ CGEN_CPU_OPEN_ENDIAN
+};
+
+/* Open a cpu descriptor table for use.
+ ??? We only support ISO C stdargs here, not K&R.
+ Laziness, plus experiment to see if anything requires K&R - eventually
+ K&R will no longer be supported - e.g. GDB is currently trying this. */
+
+extern CGEN_CPU_DESC CGEN_SYM (cpu_open) (enum cgen_cpu_open_arg, ...);
+
+/* Cover fn to handle simple case. */
+
+extern CGEN_CPU_DESC CGEN_SYM (cpu_open_1) PARAMS ((const char *mach_name_,
+ enum cgen_endian endian_));
+
+/* Close it. */
+
+extern void CGEN_SYM (cpu_close) PARAMS ((CGEN_CPU_DESC));
+
+/* Initialize the opcode table for use.
+ Called by init_asm/init_dis. */
+
+extern void CGEN_SYM (init_opcode_table) PARAMS ((CGEN_CPU_DESC cd_));
+
+/* Initialize the ibld table for use.
+ Called by init_asm/init_dis. */
+
+extern void CGEN_SYM (init_ibld_table) PARAMS ((CGEN_CPU_DESC cd_));
+
+/* Initialize an cpu table for assembler or disassembler use.
+ These must be called immediately after cpu_open. */
+
+extern void CGEN_SYM (init_asm) PARAMS ((CGEN_CPU_DESC));
+extern void CGEN_SYM (init_dis) PARAMS ((CGEN_CPU_DESC));
+
+/* Initialize the operand instance table for use. */
+
+extern void CGEN_SYM (init_opinst_table) PARAMS ((CGEN_CPU_DESC cd_));
+
+/* Assemble an instruction. */
+
+extern const CGEN_INSN * CGEN_SYM (assemble_insn)
+ PARAMS ((CGEN_CPU_DESC, const char *, CGEN_FIELDS *,
+ CGEN_INSN_BYTES_PTR, char **));
+
+extern const CGEN_KEYWORD CGEN_SYM (operand_mach);
+extern int CGEN_SYM (get_mach) PARAMS ((const char *));
+
+/* Operand index computation. */
+extern const CGEN_INSN * cgen_lookup_insn
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN * insn_,
+ CGEN_INSN_INT int_value_, unsigned char *bytes_value_,
+ int length_, CGEN_FIELDS *fields_, int alias_p_));
+extern void cgen_get_insn_operands
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN * insn_,
+ const CGEN_FIELDS *fields_, int *indices_));
+extern const CGEN_INSN * cgen_lookup_get_insn_operands
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *insn_,
+ CGEN_INSN_INT int_value_, unsigned char *bytes_value_,
+ int length_, int *indices_, CGEN_FIELDS *fields_));
+
+/* Cover fns to bfd_get/set. */