00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "sysdep.h"
00027 #include <stdio.h>
00028 #include "ansidecl.h"
00029 #include "libiberty.h"
00030 #include "safe-ctype.h"
00031 #include "bfd.h"
00032 #include "symcat.h"
00033 #include "opcode/cgen.h"
00034 #include "opintl.h"
00035
00036 static CGEN_INSN_LIST * hash_insn_array (CGEN_CPU_DESC, const CGEN_INSN *, int, int, CGEN_INSN_LIST **, CGEN_INSN_LIST *);
00037 static CGEN_INSN_LIST * hash_insn_list (CGEN_CPU_DESC, const CGEN_INSN_LIST *, CGEN_INSN_LIST **, CGEN_INSN_LIST *);
00038 static void build_asm_hash_table (CGEN_CPU_DESC);
00039
00040
00041
00042 void
00043 cgen_set_parse_operand_fn (CGEN_CPU_DESC cd, cgen_parse_operand_fn fn)
00044 {
00045 cd->parse_operand_fn = fn;
00046 }
00047
00048
00049
00050 void
00051 cgen_init_parse_operand (CGEN_CPU_DESC cd)
00052 {
00053
00054 (void) (* cd->parse_operand_fn)
00055 (cd, CGEN_PARSE_OPERAND_INIT, NULL, 0, 0, NULL, NULL);
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 static CGEN_INSN_LIST *
00071 hash_insn_array (CGEN_CPU_DESC cd,
00072 const CGEN_INSN *insns,
00073 int count,
00074 int entsize ATTRIBUTE_UNUSED,
00075 CGEN_INSN_LIST **htable,
00076 CGEN_INSN_LIST *hentbuf)
00077 {
00078 int i;
00079
00080 for (i = count - 1; i >= 0; --i, ++hentbuf)
00081 {
00082 unsigned int hash;
00083 const CGEN_INSN *insn = &insns[i];
00084
00085 if (! (* cd->asm_hash_p) (insn))
00086 continue;
00087 hash = (* cd->asm_hash) (CGEN_INSN_MNEMONIC (insn));
00088 hentbuf->next = htable[hash];
00089 hentbuf->insn = insn;
00090 htable[hash] = hentbuf;
00091 }
00092
00093 return hentbuf;
00094 }
00095
00096
00097
00098
00099
00100 static CGEN_INSN_LIST *
00101 hash_insn_list (CGEN_CPU_DESC cd,
00102 const CGEN_INSN_LIST *insns,
00103 CGEN_INSN_LIST **htable,
00104 CGEN_INSN_LIST *hentbuf)
00105 {
00106 const CGEN_INSN_LIST *ilist;
00107
00108 for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf)
00109 {
00110 unsigned int hash;
00111
00112 if (! (* cd->asm_hash_p) (ilist->insn))
00113 continue;
00114 hash = (* cd->asm_hash) (CGEN_INSN_MNEMONIC (ilist->insn));
00115 hentbuf->next = htable[hash];
00116 hentbuf->insn = ilist->insn;
00117 htable[hash] = hentbuf;
00118 }
00119
00120 return hentbuf;
00121 }
00122
00123
00124
00125 static void
00126 build_asm_hash_table (CGEN_CPU_DESC cd)
00127 {
00128 int count = cgen_insn_count (cd) + cgen_macro_insn_count (cd);
00129 CGEN_INSN_TABLE *insn_table = &cd->insn_table;
00130 CGEN_INSN_TABLE *macro_insn_table = &cd->macro_insn_table;
00131 unsigned int hash_size = cd->asm_hash_size;
00132 CGEN_INSN_LIST *hash_entry_buf;
00133 CGEN_INSN_LIST **asm_hash_table;
00134 CGEN_INSN_LIST *asm_hash_table_entries;
00135
00136
00137
00138
00139 asm_hash_table = (CGEN_INSN_LIST **)
00140 xmalloc (hash_size * sizeof (CGEN_INSN_LIST *));
00141 memset (asm_hash_table, 0, hash_size * sizeof (CGEN_INSN_LIST *));
00142 asm_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
00143 xmalloc (count * sizeof (CGEN_INSN_LIST));
00144
00145
00146
00147
00148
00149
00150 hash_entry_buf = hash_insn_array (cd,
00151 insn_table->init_entries + 1,
00152 insn_table->num_init_entries - 1,
00153 insn_table->entry_size,
00154 asm_hash_table, hash_entry_buf);
00155
00156
00157
00158 hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
00159 macro_insn_table->num_init_entries,
00160 macro_insn_table->entry_size,
00161 asm_hash_table, hash_entry_buf);
00162
00163
00164
00165
00166 hash_entry_buf = hash_insn_list (cd, insn_table->new_entries,
00167 asm_hash_table, hash_entry_buf);
00168
00169
00170
00171 hash_insn_list (cd, macro_insn_table->new_entries,
00172 asm_hash_table, hash_entry_buf);
00173
00174 cd->asm_hash_table = asm_hash_table;
00175 cd->asm_hash_table_entries = asm_hash_table_entries;
00176 }
00177
00178
00179
00180 CGEN_INSN_LIST *
00181 cgen_asm_lookup_insn (CGEN_CPU_DESC cd, const char *insn)
00182 {
00183 unsigned int hash;
00184
00185 if (cd->asm_hash_table == NULL)
00186 build_asm_hash_table (cd);
00187
00188 hash = (* cd->asm_hash) (insn);
00189 return cd->asm_hash_table[hash];
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 const char *
00201 cgen_parse_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00202 const char **strp,
00203 CGEN_KEYWORD *keyword_table,
00204 long *valuep)
00205 {
00206 const CGEN_KEYWORD_ENTRY *ke;
00207 char buf[256];
00208 const char *p,*start;
00209
00210 if (keyword_table->name_hash_table == NULL)
00211 (void) cgen_keyword_search_init (keyword_table, NULL);
00212
00213 p = start = *strp;
00214
00215
00216
00217
00218 if (*p)
00219 ++p;
00220
00221
00222 while (((p - start) < (int) sizeof (buf))
00223 && *p
00224 && (ISALNUM (*p)
00225 || *p == '_'
00226 || strchr (keyword_table->nonalpha_chars, *p)))
00227 ++p;
00228
00229 if (p - start >= (int) sizeof (buf))
00230 {
00231
00232
00233 buf[0] = 0;
00234 }
00235 else
00236 {
00237 memcpy (buf, start, p - start);
00238 buf[p - start] = 0;
00239 }
00240
00241 ke = cgen_keyword_lookup_name (keyword_table, buf);
00242
00243 if (ke != NULL)
00244 {
00245 *valuep = ke->value;
00246
00247 if (ke->name[0] != 0)
00248 *strp = p;
00249 return NULL;
00250 }
00251
00252 return "unrecognized keyword/register name";
00253 }
00254
00255
00256
00257
00258
00259
00260 const char *
00261 cgen_parse_signed_integer (CGEN_CPU_DESC cd,
00262 const char **strp,
00263 int opindex,
00264 long *valuep)
00265 {
00266 bfd_vma value;
00267 enum cgen_parse_operand_result result;
00268 const char *errmsg;
00269
00270 errmsg = (* cd->parse_operand_fn)
00271 (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
00272 &result, &value);
00273
00274 if (!errmsg)
00275 *valuep = value;
00276 return errmsg;
00277 }
00278
00279
00280
00281
00282
00283
00284 const char *
00285 cgen_parse_unsigned_integer (CGEN_CPU_DESC cd,
00286 const char **strp,
00287 int opindex,
00288 unsigned long *valuep)
00289 {
00290 bfd_vma value;
00291 enum cgen_parse_operand_result result;
00292 const char *errmsg;
00293
00294 errmsg = (* cd->parse_operand_fn)
00295 (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
00296 &result, &value);
00297
00298 if (!errmsg)
00299 *valuep = value;
00300 return errmsg;
00301 }
00302
00303
00304
00305 const char *
00306 cgen_parse_address (CGEN_CPU_DESC cd,
00307 const char **strp,
00308 int opindex,
00309 int opinfo,
00310 enum cgen_parse_operand_result *resultp,
00311 bfd_vma *valuep)
00312 {
00313 bfd_vma value;
00314 enum cgen_parse_operand_result result_type;
00315 const char *errmsg;
00316
00317 errmsg = (* cd->parse_operand_fn)
00318 (cd, CGEN_PARSE_OPERAND_ADDRESS, strp, opindex, opinfo,
00319 &result_type, &value);
00320
00321 if (!errmsg)
00322 {
00323 if (resultp != NULL)
00324 *resultp = result_type;
00325 *valuep = value;
00326 }
00327 return errmsg;
00328 }
00329
00330
00331
00332 const char *
00333 cgen_validate_signed_integer (long value, long min, long max)
00334 {
00335 if (value < min || value > max)
00336 {
00337 static char buf[100];
00338
00339
00340 sprintf (buf, _("operand out of range (%ld not between %ld and %ld)"),
00341 value, min, max);
00342 return buf;
00343 }
00344
00345 return NULL;
00346 }
00347
00348
00349
00350
00351
00352 const char *
00353 cgen_validate_unsigned_integer (unsigned long value,
00354 unsigned long min,
00355 unsigned long max)
00356 {
00357 if (value < min || value > max)
00358 {
00359 static char buf[100];
00360
00361
00362 sprintf (buf, _("operand out of range (%lu not between %lu and %lu)"),
00363 value, min, max);
00364 return buf;
00365 }
00366
00367 return NULL;
00368 }