From 9a6c492c141486947f4d24d91ab5ba02d4d76c58 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Fri, 15 May 1998 21:59:35 +0000 Subject: * cgen-opc.c (cgen_hw_lookup_by_name): Renamed from cgen_hw_lookup. (cgen_hw_lookup_by_enum): New function. * m32r-opc.c, m32r-opc.h: Regenerate, delete h-abort. --- opcodes/ChangeLog | 18 ++++++ opcodes/cgen-opc.c | 186 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 139 insertions(+), 65 deletions(-) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 5b38cd7..c0949d9 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,12 @@ +Fri May 15 14:58:31 1998 Doug Evans + + * cgen-opc.c (cgen_hw_lookup_by_name): Renamed from cgen_hw_lookup. + (cgen_hw_lookup_by_enum): New function. + +start-sanitize-m32rx + * m32r-opc.c, m32r-opc.h: Regenerate, delete h-abort. + +end-sanitize-m32rx Wed May 13 17:03:59 1998 Doug Evans * m32r-asm.c: Regenerate (handle uppercase HIGH/SHIGH/LOW/SDA). @@ -7,6 +16,15 @@ Wed May 13 14:34:31 1998 Mark Alexander * sparc-dis.c (print_insn_sparc): Always fetch instructions as big-endian on SPARClite. +start-sanitize-m32rx +Tue May 12 13:39:51 1998 Nick Clifton + + * m32r-opc.c: Regenerated - SPECIAL attribute added to some + insns. + * m32r-opc.h: Regenerated - SPECIAL attribute added to some + insns. + +end-sanitize-m32rx Tue May 12 11:46:31 1998 Richard Henderson * d30v-opc.c (pre_defined_register): Remove alias for r0. diff --git a/opcodes/cgen-opc.c b/opcodes/cgen-opc.c index cb622c4..aef9d6b 100644 --- a/opcodes/cgen-opc.c +++ b/opcodes/cgen-opc.c @@ -1,34 +1,30 @@ /* CGEN generic opcode support. -Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. -This file is part of the GNU Binutils and GDB, the GNU debugger. + This file is part of the GNU Binutils and GDB, the GNU debugger. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. -This program is distributed in the hope that it will be useful, -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. + This program is distributed in the hope that it will be useful, + 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. */ -#include "config.h" +#include "sysdep.h" +#include #include -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_STRINGS_H -#include -#endif #include "ansidecl.h" #include "libiberty.h" #include "bfd.h" +#include "symcat.h" #include "opcode/cgen.h" /* State variables. @@ -36,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc., They are set by cgen_set_cpu. */ /* Current opcode data. */ -CGEN_OPCODE_DATA *cgen_current_opcode_data; +const CGEN_OPCODE_TABLE *cgen_current_opcode_table; /* Current machine (a la BFD machine number). */ int cgen_current_mach; @@ -44,31 +40,44 @@ int cgen_current_mach; /* Current endian. */ enum cgen_endian cgen_current_endian = CGEN_ENDIAN_UNKNOWN; +/* FIXME: To support multiple architectures, we need to return a handle + to the state set up by this function, and pass the handle back to the + other functions. Later. */ + void -cgen_set_cpu (data, mach, endian) - CGEN_OPCODE_DATA *data; +cgen_set_cpu (table, mach, endian) + const CGEN_OPCODE_TABLE * table; int mach; enum cgen_endian endian; { - cgen_current_opcode_data = data; + static int init_once_p; + + cgen_current_opcode_table = table; cgen_current_mach = mach; cgen_current_endian = endian; + /* Initialize those things that only need be done once. */ + if (! init_once_p) + { + /* Nothing to do currently. */ + init_once_p = 1; + } + #if 0 /* This isn't done here because it would put assembler support in the disassembler, etc. The caller is required to call these after calling us. */ /* Reset the hash tables. */ cgen_asm_init (); cgen_dis_init (); -#endif +#endif } static unsigned int hash_keyword_name - PARAMS ((const struct cgen_keyword *, const char *)); + PARAMS ((const CGEN_KEYWORD *, const char *, int)); static unsigned int hash_keyword_value - PARAMS ((const struct cgen_keyword *, int)); + PARAMS ((const CGEN_KEYWORD *, unsigned int)); static void build_keyword_hash_tables - PARAMS ((struct cgen_keyword *)); + PARAMS ((CGEN_KEYWORD *)); /* Return number of hash table entries to use for N elements. */ #define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31) @@ -76,18 +85,18 @@ static void build_keyword_hash_tables /* Look up *NAMEP in the keyword table KT. The result is the keyword entry or NULL if not found. */ -const struct cgen_keyword_entry * +const CGEN_KEYWORD_ENTRY * cgen_keyword_lookup_name (kt, name) - struct cgen_keyword *kt; + CGEN_KEYWORD *kt; const char *name; { - const struct cgen_keyword_entry *ke; + const CGEN_KEYWORD_ENTRY *ke; const char *p,*n; if (kt->name_hash_table == NULL) build_keyword_hash_tables (kt); - ke = kt->name_hash_table[hash_keyword_name (kt, name)]; + ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)]; /* We do case insensitive comparisons. If that ever becomes a problem, add an attribute that denotes @@ -100,7 +109,9 @@ cgen_keyword_lookup_name (kt, name) while (*p && (*p == *n - || (isalpha (*p) && tolower (*p) == tolower (*n)))) + || (isalpha ((unsigned char) *p) + && (tolower ((unsigned char) *p) + == tolower ((unsigned char) *n))))) ++n, ++p; if (!*p && !*n) @@ -109,18 +120,20 @@ cgen_keyword_lookup_name (kt, name) ke = ke->next_name; } + if (kt->null_entry) + return kt->null_entry; return NULL; } /* Look up VALUE in the keyword table KT. The result is the keyword entry or NULL if not found. */ -const struct cgen_keyword_entry * +const CGEN_KEYWORD_ENTRY * cgen_keyword_lookup_value (kt, value) - struct cgen_keyword *kt; + CGEN_KEYWORD *kt; int value; { - const struct cgen_keyword_entry *ke; + const CGEN_KEYWORD_ENTRY *ke; if (kt->name_hash_table == NULL) build_keyword_hash_tables (kt); @@ -141,21 +154,24 @@ cgen_keyword_lookup_value (kt, value) void cgen_keyword_add (kt, ke) - struct cgen_keyword *kt; - struct cgen_keyword_entry *ke; + CGEN_KEYWORD *kt; + CGEN_KEYWORD_ENTRY *ke; { unsigned int hash; if (kt->name_hash_table == NULL) build_keyword_hash_tables (kt); - hash = hash_keyword_name (kt, ke->name); + hash = hash_keyword_name (kt, ke->name, 0); ke->next_name = kt->name_hash_table[hash]; kt->name_hash_table[hash] = ke; hash = hash_keyword_value (kt, ke->value); ke->next_value = kt->value_hash_table[hash]; kt->value_hash_table[hash] = ke; + + if (ke->name[0] == 0) + kt->null_entry = ke; } /* FIXME: Need function to return count of keywords. */ @@ -168,12 +184,12 @@ cgen_keyword_add (kt, ke) The result is an opaque data item used to record the search status. It is passed to each call to cgen_keyword_search_next. */ -struct cgen_keyword_search +CGEN_KEYWORD_SEARCH cgen_keyword_search_init (kt, spec) - struct cgen_keyword *kt; + CGEN_KEYWORD *kt; const char *spec; { - struct cgen_keyword_search search; + CGEN_KEYWORD_SEARCH search; /* FIXME: Need to specify format of PARAMS. */ if (spec != NULL) @@ -192,12 +208,10 @@ cgen_keyword_search_init (kt, spec) /* Return the next keyword specified by SEARCH. The result is the next entry or NULL if there are no more. */ -const struct cgen_keyword_entry * +const CGEN_KEYWORD_ENTRY * cgen_keyword_search_next (search) - struct cgen_keyword_search *search; + CGEN_KEYWORD_SEARCH *search; { - const struct cgen_keyword_entry *ke; - /* Has search finished? */ if (search->current_hash == search->table->hash_table_size) return NULL; @@ -226,17 +240,23 @@ cgen_keyword_search_next (search) return NULL; } -/* Return first entry in hash chain for NAME. */ +/* Return first entry in hash chain for NAME. + If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */ static unsigned int -hash_keyword_name (kt, name) - const struct cgen_keyword *kt; +hash_keyword_name (kt, name, case_sensitive_p) + const CGEN_KEYWORD *kt; const char *name; + int case_sensitive_p; { unsigned int hash; - for (hash = 0; *name; ++name) - hash = (hash * 97) + (unsigned char) *name; + if (case_sensitive_p) + for (hash = 0; *name; ++name) + hash = (hash * 97) + (unsigned char) *name; + else + for (hash = 0; *name; ++name) + hash = (hash * 97) + (unsigned char) tolower (*name); return hash % kt->hash_table_size; } @@ -244,8 +264,8 @@ hash_keyword_name (kt, name) static unsigned int hash_keyword_value (kt, value) - const struct cgen_keyword *kt; - int value; + const CGEN_KEYWORD *kt; + unsigned int value; { return value % kt->hash_table_size; } @@ -256,7 +276,7 @@ hash_keyword_value (kt, value) static void build_keyword_hash_tables (kt) - struct cgen_keyword *kt; + CGEN_KEYWORD *kt; { int i; /* Use the number of compiled in entries as an estimate for the @@ -264,12 +284,12 @@ build_keyword_hash_tables (kt) unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries); kt->hash_table_size = size; - kt->name_hash_table = (struct cgen_keyword_entry **) - xmalloc (size * sizeof (struct cgen_keyword_entry *)); - memset (kt->name_hash_table, 0, size * sizeof (struct cgen_keyword_entry *)); - kt->value_hash_table = (struct cgen_keyword_entry **) - xmalloc (size * sizeof (struct cgen_keyword_entry *)); - memset (kt->value_hash_table, 0, size * sizeof (struct cgen_keyword_entry *)); + kt->name_hash_table = (CGEN_KEYWORD_ENTRY **) + xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *)); + memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *)); + kt->value_hash_table = (CGEN_KEYWORD_ENTRY **) + xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *)); + memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *)); /* The table is scanned backwards as we want keywords appearing earlier to be prefered over later ones. */ @@ -279,11 +299,13 @@ build_keyword_hash_tables (kt) /* Hardware support. */ -CGEN_HW_ENTRY * -cgen_hw_lookup (name) +/* Lookup a hardware element by its name. */ + +const CGEN_HW_ENTRY * +cgen_hw_lookup_by_name (name) const char *name; { - CGEN_HW_ENTRY *hw = cgen_current_opcode_data->hw_list; + const CGEN_HW_ENTRY * hw = cgen_current_opcode_table->hw_list; while (hw != NULL) { @@ -294,6 +316,26 @@ cgen_hw_lookup (name) return NULL; } + +/* Lookup a hardware element by its enum. + Hardware elements are enumerated, however it may be possible to add some + at runtime, thus HWNUM is not an enum type but rather an int. */ + +const CGEN_HW_ENTRY * +cgen_hw_lookup_by_enum (hwnum) + int hwnum; +{ + const CGEN_HW_ENTRY * hw = cgen_current_opcode_table->hw_list; + + /* ??? This can be speeded up if we first make a guess into + the compiled in table. */ + while (hw != NULL) + { + if (hwnum == hw->type) + return hw; + } + return NULL; +} /* Instruction support. */ @@ -302,8 +344,22 @@ cgen_hw_lookup (name) int cgen_insn_count () { - int count = cgen_current_opcode_data->insn_table->num_init_entries; - CGEN_INSN_LIST *insn = cgen_current_opcode_data->insn_table->new_entries; + int count = cgen_current_opcode_table->insn_table->num_init_entries; + CGEN_INSN_LIST * insn = cgen_current_opcode_table->insn_table->new_entries; + + for ( ; insn != NULL; insn = insn->next) + ++count; + + return count; +} + +/* Return number of macro-instructions. This includes any added at runtime. */ + +int +cgen_macro_insn_count () +{ + int count = cgen_current_opcode_table->macro_insn_table->num_init_entries; + CGEN_INSN_LIST * insn = cgen_current_opcode_table->macro_insn_table->new_entries; for ( ; insn != NULL; insn = insn->next) ++count; -- cgit v1.1