From 19d45995ed84226904c5d4d5a665539f3eb50bdb Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Mon, 12 Jan 1998 20:58:56 +0000 Subject: [PATCH] * cgen.h (*): Clean up pass over `struct foo' usage. (CGEN_ATTR): Make unsigned char. (CGEN_ATTR_TYPE): Update. (CGEN_ATTR_{ENTRY,TABLE}): New types. (cgen_base): Move member `attrs' to cgen_insn. (CGEN_KEYWORD): New member `null_entry'. (CGEN_{SYNTAX,FORMAT}): New types. (cgen_insn): Format and syntax separated from each other. --- include/opcode/ChangeLog | 11 ++ include/opcode/cgen.h | 398 +++++++++++++++++++++++---------------- 2 files changed, 247 insertions(+), 162 deletions(-) diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 81ae0a3da24..93878de23d0 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,14 @@ +Mon Jan 12 11:37:36 1998 Doug Evans + + * cgen.h (*): Clean up pass over `struct foo' usage. + (CGEN_ATTR): Make unsigned char. + (CGEN_ATTR_TYPE): Update. + (CGEN_ATTR_{ENTRY,TABLE}): New types. + (cgen_base): Move member `attrs' to cgen_insn. + (CGEN_KEYWORD): New member `null_entry'. + (CGEN_{SYNTAX,FORMAT}): New types. + (cgen_insn): Format and syntax separated from each other. + start-sanitize-sky Mon Jan 5 13:33:21 1998 Doug Evans diff --git a/include/opcode/cgen.h b/include/opcode/cgen.h index 932eb15fc0f..a436ee913f6 100644 --- a/include/opcode/cgen.h +++ b/include/opcode/cgen.h @@ -1,6 +1,6 @@ /* Header file for targets using CGEN: Cpu tools GENerator. -Copyright (C) 1996, 1997 Free Software Foundation, Inc. +Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. This file is part of GDB, the GNU debugger, and the GNU Binutils. @@ -14,9 +14,9 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef CGEN_H #define CGEN_H @@ -82,7 +82,7 @@ enum cgen_endian { /* Struct to record attribute information. */ typedef struct { - unsigned int num_nonbools; + unsigned char num_nonbools; unsigned int bool; unsigned int nonbool[1]; } CGEN_ATTR; @@ -94,7 +94,7 @@ typedef struct { nonbool: values of non-boolean attributes There is a maximum of 32 attributes total. */ #define CGEN_ATTR_TYPE(n) \ -const struct { unsigned int num_nonbools; \ +const struct { unsigned char num_nonbools; \ unsigned int bool; \ unsigned int nonbool[(n) ? (n) : 1]; } @@ -108,6 +108,22 @@ const struct { unsigned int num_nonbools; \ ((unsigned int) (attr) < (attr_table)->num_nonbools \ ? ((attr_table)->nonbool[attr]) \ : (((attr_table)->bool & (1 << (attr))) != 0)) + +/* Attribute name/value tables. + These are used to assist parsing of descriptions at runtime. */ + +typedef struct { + const char *name; + int value; +} CGEN_ATTR_ENTRY; + +/* For each domain (fld,operand,insn), list of attributes. */ + +typedef struct { + const char *name; + /* NULL for boolean attributes. */ + const CGEN_ATTR_ENTRY *vals; +} CGEN_ATTR_TABLE; /* Parse result (also extraction result). @@ -207,11 +223,12 @@ extern cgen_print_fn * CGEN_SYM (print_handlers) []; #define CGEN_PRINT_FN(x) (CGEN_SYM (print_handlers)[(x)->base.print]) /* Base class of parser/printer. - (Don't read too much into the use of the phrase "base class"). + (Don't read too much into the use of the phrase "base class". + It's a name I'm using to organize my thoughts.) Instructions and expressions all share this data in common. - It's a collection of the common elements needed to parse and print - each of them. */ + It's a collection of the common elements needed to parse, insert, extract, + and print each of them. */ #ifndef CGEN_MAX_INSN_ATTRS #define CGEN_MAX_INSN_ATTRS 1 @@ -223,71 +240,81 @@ struct cgen_base { 90% of them would be identical and that's a lot of redundant data. 0 means use the default (what the default is is up to the code). */ unsigned char parse, insert, extract, print; - - /* Attributes. */ - CGEN_ATTR_TYPE (CGEN_MAX_INSN_ATTRS) attrs; }; -/* Syntax table. +/* Assembler interface. - Each insn and subexpression has one of these. + The interface to the assembler is intended to be clean in the sense that + libopcodes.a is a standalone entity and could be used with any assembler. + Not that one would necessarily want to do that but rather that it helps + keep a clean interface. The interface will obviously be slanted towards + GAS, but at least it's a start. - The syntax "string" consists of characters (n > 0 && n < 128), and operand - values (n >= 128), and is terminated by 0. Operand values are 128 + index - into the operand table. The operand table doesn't exist in C, per se, as - the data is recorded in the parse/insert/extract/print switch statements. + Parsing is controlled by the assembler which calls + CGEN_SYM (assemble_insn). If it can parse and build the entire insn + it doesn't call back to the assembler. If it needs/wants to call back + to the assembler, (*cgen_parse_operand_fn) is called which can either - ??? Whether we want to use yacc instead is unclear, but we do make an - effort to not make doing that difficult. At least that's the intent. -*/ + - return a number to be inserted in the insn + - return a "register" value to be inserted + (the register might not be a register per pe) + - queue the argument and return a marker saying the expression has been + queued (eg: a fix-up) + - return an error message indicating the expression wasn't recognizable + + The result is an error message or NULL for success. + The parsed value is stored in the bfd_vma *. */ -struct cgen_syntax { - /* Original syntax string, for debugging purposes. */ - char *orig; +/* Values for indicating what the caller wants. */ +enum cgen_parse_operand_type { + CGEN_PARSE_OPERAND_INIT, CGEN_PARSE_OPERAND_INTEGER, + CGEN_PARSE_OPERAND_ADDRESS +}; - /* Name of entry (that distinguishes it from all other entries). - This is used, for example, in simulator profiling results. */ - char *name; +/* Values for indicating what was parsed. + ??? Not too useful at present but in time. */ +enum cgen_parse_operand_result { + CGEN_PARSE_OPERAND_RESULT_NUMBER, CGEN_PARSE_OPERAND_RESULT_REGISTER, + CGEN_PARSE_OPERAND_RESULT_QUEUED, CGEN_PARSE_OPERAND_RESULT_ERROR +}; -#if 0 /* not needed yet */ - /* Format of this insn. - This doesn't closely follow the notion of instruction formats for more - complex instruction sets. This is the value computed at runtime. */ - enum cgen_fmt_type fmt; +/* Don't require bfd.h unnecessarily. */ +#ifdef BFD_VERSION +extern const char * (*cgen_parse_operand_fn) + PARAMS ((enum cgen_parse_operand_type, const char **, int, int, + enum cgen_parse_operand_result *, bfd_vma *)); #endif - /* Mnemonic (or name if expression). */ - char *mnemonic; +/* Called before trying to match a table entry with the insn. */ +void cgen_init_parse_operand PARAMS ((void)); - /* Syntax string. */ - /* FIXME: If each insn's mnemonic is constant, do we want to record just - the arguments here? */ -#ifndef CGEN_MAX_SYNTAX_BYTES -#define CGEN_MAX_SYNTAX_BYTES 16 -#endif - unsigned char syntax[CGEN_MAX_SYNTAX_BYTES]; +/* Called from -asm.c to initialize operand parsing. */ -#define CGEN_SYNTAX_CHAR_P(c) ((c) < 128) -#define CGEN_SYNTAX_CHAR(c) (c) -#define CGEN_SYNTAX_FIELD(c) ((c) - 128) +/* These are GAS specific. They're not here as part of the interface, + but rather that we need to put them somewhere. */ - /* recognize insn if (op & mask) == value - For architectures with variable length insns, this is just a preliminary - test. */ - /* FIXME: Might want a selectable type (rather than always - unsigned long). */ - unsigned long mask, value; +/* Call this from md_assemble to initialize the assembler callback. */ +void cgen_asm_init_parse PARAMS ((void)); - /* length, in bits - This is the size that `mask' and `value' have been calculated to. - Normally it is CGEN_BASE_INSN_BITSIZE. On vliw architectures where - the base insn size may be larger than the size of an insn, this field is - less than CGEN_BASE_INSN_BITSIZE. - On architectures like the 386 and m68k the real size of the insn may - be computed while parsing. */ - /* FIXME: wip, of course */ - int length; -}; +/* Don't require bfd.h unnecessarily. */ +#ifdef BFD_VERSION +/* The result is an error message or NULL for success. + The parsed value is stored in the bfd_vma *. */ +const char *cgen_parse_operand PARAMS ((enum cgen_parse_operand_type, + const char **, int, int, + enum cgen_parse_operand_result *, + bfd_vma *)); +#endif + +/* Add a register to the assembler's hash table. + This makes lets GAS parse registers for us. + ??? This isn't currently used, but it could be in the future. */ +void cgen_asm_record_register PARAMS ((char *, int)); + +/* After CGEN_SYM (assemble_insn) is done, this is called to + output the insn and record any fixups. */ +void cgen_asm_finish_insn PARAMS ((const struct cgen_insn *, cgen_insn_t *, + unsigned int)); /* Operand values (keywords, integers, symbols, etc.) */ @@ -325,7 +352,13 @@ typedef struct cgen_keyword_entry { IDEA: Have "FUNCTION" attribute? [function is called to fetch value]. */ int value; - /* Attributes. */ + /* Attributes. + This should, but technically needn't, appear last. It is a variable sized + array in that one architecture may have 1 nonbool attribute and another + may have more. Having this last means the non-architecture specific code + needn't care. */ + /* ??? Moving this last should be done by treating keywords like insn lists + and moving the `next' fields into a CGEN_KEYWORD_LIST struct. */ /* FIXME: Not used yet. */ CGEN_ATTR_TYPE (CGEN_MAX_KEYWORD_ATTRS) attrs; @@ -340,61 +373,63 @@ typedef struct cgen_keyword_entry { This struct supports runtime entry of new values, and hashed lookups. */ -typedef struct cgen_keyword { +typedef struct { /* Pointer to initial [compiled in] values. */ - struct cgen_keyword_entry *init_entries; + CGEN_KEYWORD_ENTRY *init_entries; /* Number of entries in `init_entries'. */ unsigned int num_init_entries; /* Hash table used for name lookup. */ - struct cgen_keyword_entry **name_hash_table; + CGEN_KEYWORD_ENTRY **name_hash_table; /* Hash table used for value lookup. */ - struct cgen_keyword_entry **value_hash_table; + CGEN_KEYWORD_ENTRY **value_hash_table; /* Number of entries in the hash_tables. */ unsigned int hash_table_size; + /* Pointer to null keyword "" entry if present. */ + const CGEN_KEYWORD_ENTRY *null_entry; } CGEN_KEYWORD; /* Structure used for searching. */ -typedef struct cgen_keyword_search { +typedef struct { /* Table being searched. */ - const struct cgen_keyword *table; + const CGEN_KEYWORD *table; /* Specification of what is being searched for. */ const char *spec; /* Current index in hash table. */ unsigned int current_hash; /* Current element in current hash chain. */ - struct cgen_keyword_entry *current_entry; + CGEN_KEYWORD_ENTRY *current_entry; } CGEN_KEYWORD_SEARCH; /* Lookup a keyword from its name. */ -const struct cgen_keyword_entry * cgen_keyword_lookup_name - PARAMS ((struct cgen_keyword *, const char *)); +const CGEN_KEYWORD_ENTRY * cgen_keyword_lookup_name + PARAMS ((CGEN_KEYWORD *, const char *)); /* Lookup a keyword from its value. */ -const struct cgen_keyword_entry * cgen_keyword_lookup_value - PARAMS ((struct cgen_keyword *, int)); +const CGEN_KEYWORD_ENTRY * cgen_keyword_lookup_value + PARAMS ((CGEN_KEYWORD *, int)); /* Add a keyword. */ -void cgen_keyword_add PARAMS ((struct cgen_keyword *, - struct cgen_keyword_entry *)); +void cgen_keyword_add PARAMS ((CGEN_KEYWORD *, CGEN_KEYWORD_ENTRY *)); /* Keyword searching. This can be used to retrieve every keyword, or a subset. */ -struct cgen_keyword_search cgen_keyword_search_init - PARAMS ((struct cgen_keyword *, const char *)); -const struct cgen_keyword_entry *cgen_keyword_search_next - PARAMS ((struct cgen_keyword_search *)); +CGEN_KEYWORD_SEARCH cgen_keyword_search_init + PARAMS ((CGEN_KEYWORD *, const char *)); +const CGEN_KEYWORD_ENTRY *cgen_keyword_search_next + PARAMS ((CGEN_KEYWORD_SEARCH *)); /* Operand value support routines. */ /* FIXME: some of the long's here will need to be bfd_vma or some such. */ const char * cgen_parse_keyword PARAMS ((const char **, - struct cgen_keyword *, + CGEN_KEYWORD *, long *)); const char * cgen_parse_signed_integer PARAMS ((const char **, int, long, long, long *)); const char * cgen_parse_unsigned_integer PARAMS ((const char **, int, unsigned long, unsigned long, unsigned long *)); -const char * cgen_parse_address PARAMS ((const char **, int, - int, long *)); +const char * cgen_parse_address PARAMS ((const char **, int, int, + enum cgen_parse_operand_result *, + long *)); const char * cgen_validate_signed_integer PARAMS ((long, long, long)); const char * cgen_validate_unsigned_integer PARAMS ((unsigned long, unsigned long, @@ -406,27 +441,33 @@ const char * cgen_validate_unsigned_integer PARAMS ((unsigned long, #define CGEN_MAX_OPERAND_ATTRS 1 #endif -typedef struct cgen_operand { - /* For debugging. */ +typedef struct { + /* Name as it appears in the syntax string. */ char *name; /* Bit position (msb of first byte = bit 0). + This is just a hint, and may be unused in more complex operands. May be unused for a modifier. */ unsigned char start; /* The number of bits in the operand. + This is just a hint, and may be unused in more complex operands. May be unused for a modifier. */ unsigned char length; - /* Attributes. */ - CGEN_ATTR_TYPE (CGEN_MAX_OPERAND_ATTRS) attrs; -#define CGEN_OPERAND_ATTRS(operand) (&(operand)->attrs) - -#if 0 /* ??? Interesting idea but relocs tend to get too complicated for - simple table lookups to work. */ +#if 0 /* ??? Interesting idea but relocs tend to get too complicated, + and ABI dependent, for simple table lookups to work. */ /* Ideally this would be the internal (external?) reloc type. */ int reloc_type; #endif + + /* Attributes. + This should, but technically needn't, appear last. It is a variable sized + array in that one architecture may have 1 nonbool attribute and another + may have more. Having this last means the non-architecture specific code + needn't care, now or tomorrow. */ + CGEN_ATTR_TYPE (CGEN_MAX_OPERAND_ATTRS) attrs; +#define CGEN_OPERAND_ATTRS(operand) (&(operand)->attrs) } CGEN_OPERAND; /* Return value of attribute ATTR in OPERAND. */ @@ -443,41 +484,132 @@ enum cgen_operand_type; #define CGEN_OPERAND_TYPE(operand) ((enum cgen_operand_type) CGEN_OPERAND_INDEX (operand)) #define CGEN_OPERAND_ENTRY(n) (& CGEN_SYM (operand_table) [n]) +/* Syntax string. + + Each insn format and subexpression has one of these. + + The syntax "string" consists of characters (n > 0 && n < 128), and operand + values (n >= 128), and is terminated by 0. Operand values are 128 + index + into the operand table. The operand table doesn't exist in C, per se, as + the data is recorded in the parse/insert/extract/print switch statements. */ + +#ifndef CGEN_MAX_SYNTAX_BYTES +#define CGEN_MAX_SYNTAX_BYTES 16 +#endif + +typedef struct { + unsigned char syntax[CGEN_MAX_SYNTAX_BYTES]; +} CGEN_SYNTAX; + +#define CGEN_SYNTAX_STRING(syn) (syn->syntax) +#define CGEN_SYNTAX_CHAR_P(c) ((c) < 128) +#define CGEN_SYNTAX_CHAR(c) (c) +#define CGEN_SYNTAX_FIELD(c) ((c) - 128) + +/* ??? I can't currently think of any case where the mnemonic doesn't come + first [and if one ever doesn't building the hash tables will be tricky]. + However, we treat mnemonics as just another operand of the instruction. + A value of 1 means "this is where the mnemonic appears". 1 isn't + special other than it's a non-printable ASCII char. */ +#define CGEN_SYNTAX_MNEMONIC_P(ch) ((ch) == 1) + +/* Instruction formats. + + Instructions are grouped by format. Associated with an instruction is its + format. Each opcode table entry contains a pointer into the format table. + This cuts down on the size of the opcode table as there are relatively few + formats compared with the number of instructions. */ + +typedef struct { + /* Length that MASK and VALUE have been calculated to + [VALUE is recorded elsewhere]. + Normally it is CGEN_BASE_INSN_BITSIZE. On [V]LIW architectures where + the base insn size may be larger than the size of an insn, this field is + less than CGEN_BASE_INSN_BITSIZE. */ + unsigned char mask_length; + + /* Total length of instruction. */ + unsigned char length; + + /* Mask to apply to the first BASE_LENGTH bits. + Each insn's value is stored with the insn. + The first step in recognizing an insn for disassembly is + (opcode & mask) == value. */ + unsigned int mask; +} CGEN_FORMAT; + /* This struct defines each entry in the instruction table. */ struct cgen_insn { + /* ??? Further table size reductions can be had by moving this element + either to the format table or to a separate table of its own. Not + sure this is desirable yet. */ struct cgen_base base; /* Given a pointer to a cgen_insn struct, return a pointer to `base'. */ #define CGEN_INSN_BASE(insn) (&(insn)->base) -#define CGEN_INSN_ATTRS(insn) (&(insn)->base.attrs) - - struct cgen_syntax syntax; -#define CGEN_INSN_SYNTAX(insn) (&(insn)->syntax) -#define CGEN_INSN_FMT(insn) ((insn)->syntax.fmt) -#define CGEN_INSN_BITSIZE(insn) ((insn)->syntax.length) -}; + /* Name of entry (that distinguishes it from all other entries). + This is used, for example, in simulator profiling results. */ + /* ??? If mnemonics have operands, try to print full mnemonic. */ + const char *name; +#define CGEN_INSN_NAME(insn) ((insn)->name) + + /* Mnemonic. This is used when parsing and printing the insn. + In the case of insns that have operands on the mnemonics, this is + only the constant part. E.g. for conditional execution of an `add' insn, + where the full mnemonic is addeq, addne, etc., this is only "add". */ + const char *mnemonic; +#define CGEN_INSN_MNEMONIC(insn) ((insn)->mnemonic) + + /* Syntax string. + For now this only points to CGEN_SYNTAX elements, but it can point + to other things (e.g. something different for macros?). */ + const CGEN_SYNTAX *syntax; +#define CGEN_INSN_SYNTAX(insn) ((CGEN_SYNTAX *) (insn)->syntax) + + /* Format entry. + For now this only points to CGEN_FORMAT elements, but it can point + to other things (e.g. something different for macros?). */ + const CGEN_FORMAT *format; +#define CGEN_INSN_MASK_BITSIZE(insn) (((CGEN_FORMAT *) (insn)->format)->mask_length) +#define CGEN_INSN_BITSIZE(insn) (((CGEN_FORMAT *) (insn)->format)->length) + + /* Instruction opcode value. */ + unsigned int value; +#define CGEN_INSN_VALUE(insn) ((insn)->value) +#define CGEN_INSN_MASK(insn) (((CGEN_FORMAT *) (insn)->format)->mask) + + /* Attributes. + This must appear last. It is a variable sized array in that one + architecture may have 1 nonbool attribute and another may have more. + Having this last means the non-architecture specific code needn't + care. */ + CGEN_ATTR_TYPE (CGEN_MAX_INSN_ATTRS) attrs; +#define CGEN_INSN_ATTRS(insn) (&(insn)->attrs) /* Return value of attribute ATTR in INSN. */ #define CGEN_INSN_ATTR(insn, attr) \ CGEN_ATTR_VALUE (insn, CGEN_INSN_ATTRS (insn), attr) +}; /* Instruction lists. This is used for adding new entries and for creating the hash lists. */ typedef struct cgen_insn_list { struct cgen_insn_list *next; - const struct cgen_insn *insn; + const CGEN_INSN *insn; } CGEN_INSN_LIST; /* The table of instructions. */ -typedef struct cgen_insn_table { +typedef struct { /* Pointer to initial [compiled in] entries. */ - const struct cgen_insn *init_entries; + const CGEN_INSN *init_entries; + /* Size of an entry (since the attribute member is variable sized). */ + unsigned int entry_size; /* Number of entries in `init_entries', including trailing NULL entry. */ unsigned int num_init_entries; /* Values added at runtime. */ - struct cgen_insn_list *new_entries; + CGEN_INSN_LIST *new_entries; /* Assembler hash function. */ unsigned int (*asm_hash) PARAMS ((const char *)); /* Number of entries in assembler hash table. */ @@ -498,7 +630,7 @@ extern const CGEN_INSN CGEN_SYM (insn_table_entries)[]; /* Return number of instructions. This includes any added at runtime. */ -int cgen_insn_count PARAMS (()); +int cgen_insn_count PARAMS ((void)); /* The assembler insn table is hashed based on some function of the mnemonic (the actually hashing done is up to the target, but we provide a few @@ -541,7 +673,7 @@ CGEN_INSN_LIST * cgen_dis_lookup_insn PARAMS ((const char *, unsigned long)); /* Top level structures and functions. */ -typedef struct cgen_opcode_data { +typedef struct { CGEN_HW_ENTRY *hw_list; /*CGEN_OPERAND_TABLE *operand_table; - FIXME:wip */ CGEN_INSN_TABLE *insn_table; @@ -580,12 +712,12 @@ void CGEN_SYM (init_extract) PARAMS ((void)); const struct cgen_insn * CGEN_SYM (assemble_insn) PARAMS ((const char *, struct cgen_fields *, cgen_insn_t *, char **)); -int CGEN_SYM (insn_supported) PARAMS ((const struct cgen_syntax *)); #if 0 /* old */ +int CGEN_SYM (insn_supported) PARAMS ((const struct cgen_insn *)); int CGEN_SYM (opval_supported) PARAMS ((const struct cgen_opval *)); #endif -extern const struct cgen_keyword CGEN_SYM (operand_mach); +extern const CGEN_KEYWORD CGEN_SYM (operand_mach); int CGEN_SYM (get_mach) PARAMS ((const char *)); CGEN_INLINE void @@ -608,63 +740,5 @@ extern cgen_print_fn CGEN_SYM (print_insn); /* Read in a cpu description file. */ const char * cgen_read_cpu_file PARAMS ((const char *)); - -/* Assembler interface. - - The interface to the assembler is intended to be clean in the sense that - libopcodes.a is a standalone entity and could be used with any assembler. - Not that one would necessarily want to do that but rather that it helps - keep a clean interface. The interface will obviously be slanted towards - GAS, but at least it's a start. - - Parsing is controlled by the assembler which calls - CGEN_SYM (assemble_insn). If it can parse and build the entire insn - it doesn't call back to the assembler. If it needs/wants to call back - to the assembler, (*cgen_asm_parse_operand_fn) is called which can either - - - return a number to be inserted in the insn - - return a "register" value to be inserted - (the register might not be a register per pe) - - queue the argument and return a marker saying the expression has been - queued (eg: a fix-up) - - return an error message indicating the expression wasn't recognizable - - The result is an error message or NULL for success. - The parsed value is stored in the bfd_vma *. */ - -enum cgen_asm_result { - CGEN_ASM_NUMBER, CGEN_ASM_REGISTER, CGEN_ASM_QUEUED, CGEN_ASM_ERROR -}; - -/* Don't require bfd.h unnecessarily. */ -#ifdef BFD_VERSION -extern const char * (*cgen_asm_parse_operand_fn) - PARAMS ((const char **, int, int, enum cgen_asm_result *, bfd_vma *)); -#endif - -/* These are GAS specific. They're not here as part of the interface, - but rather that we need to put them somewhere. */ - -/* Call this for each insn to initialize the assembler callback interface. */ -void cgen_asm_init_parse PARAMS ((void)); - -/* Don't require bfd.h unnecessarily. */ -#ifdef BFD_VERSION -/* The result is an error message or NULL for success. - The parsed value is stored in the bfd_vma *. */ -const char *cgen_asm_parse_operand PARAMS ((const char **, int, int, - enum cgen_asm_result *, - bfd_vma *)); -#endif - -/* Add a register to the assembler's hash table. - This makes lets GAS parse registers for us. - ??? This isn't currently used, but it could be in the future. */ -void cgen_asm_record_register PARAMS ((char *, int)); - -/* After CGEN_SYM (assemble_insn) is done, this is called to - output the insn and record any fixups. */ -void cgen_asm_finish_insn PARAMS ((const struct cgen_insn *, cgen_insn_t *, - unsigned int)); #endif /* CGEN_H */ -- 2.30.2