2001-05-17 H.J. Lu <hjl@gnu.org>
[binutils.git] / opcodes / cgen-opc.c
blob7e958e7779a07c34f6f84bc24a2c8b0486e62b15
1 /* CGEN generic opcode support.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001
4 Free Software Foundation, Inc.
6 This file is part of the GNU Binutils and GDB, the GNU debugger.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "sysdep.h"
23 #include <ctype.h>
24 #include <stdio.h>
25 #include "ansidecl.h"
26 #include "libiberty.h"
27 #include "bfd.h"
28 #include "symcat.h"
29 #include "opcode/cgen.h"
31 #ifdef HAVE_ALLOCA_H
32 #include <alloca.h>
33 #endif
35 static unsigned int hash_keyword_name
36 PARAMS ((const CGEN_KEYWORD *, const char *, int));
37 static unsigned int hash_keyword_value
38 PARAMS ((const CGEN_KEYWORD *, unsigned int));
39 static void build_keyword_hash_tables
40 PARAMS ((CGEN_KEYWORD *));
42 /* Return number of hash table entries to use for N elements. */
43 #define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
45 /* Look up *NAMEP in the keyword table KT.
46 The result is the keyword entry or NULL if not found. */
48 const CGEN_KEYWORD_ENTRY *
49 cgen_keyword_lookup_name (kt, name)
50 CGEN_KEYWORD *kt;
51 const char *name;
53 const CGEN_KEYWORD_ENTRY *ke;
54 const char *p,*n;
56 if (kt->name_hash_table == NULL)
57 build_keyword_hash_tables (kt);
59 ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)];
61 /* We do case insensitive comparisons.
62 If that ever becomes a problem, add an attribute that denotes
63 "do case sensitive comparisons". */
65 while (ke != NULL)
67 n = name;
68 p = ke->name;
70 while (*p
71 && (*p == *n
72 || (isalpha ((unsigned char) *p)
73 && (tolower ((unsigned char) *p)
74 == tolower ((unsigned char) *n)))))
75 ++n, ++p;
77 if (!*p && !*n)
78 return ke;
80 ke = ke->next_name;
83 if (kt->null_entry)
84 return kt->null_entry;
85 return NULL;
88 /* Look up VALUE in the keyword table KT.
89 The result is the keyword entry or NULL if not found. */
91 const CGEN_KEYWORD_ENTRY *
92 cgen_keyword_lookup_value (kt, value)
93 CGEN_KEYWORD *kt;
94 int value;
96 const CGEN_KEYWORD_ENTRY *ke;
98 if (kt->name_hash_table == NULL)
99 build_keyword_hash_tables (kt);
101 ke = kt->value_hash_table[hash_keyword_value (kt, value)];
103 while (ke != NULL)
105 if (value == ke->value)
106 return ke;
107 ke = ke->next_value;
110 return NULL;
113 /* Add an entry to a keyword table. */
115 void
116 cgen_keyword_add (kt, ke)
117 CGEN_KEYWORD *kt;
118 CGEN_KEYWORD_ENTRY *ke;
120 unsigned int hash;
122 if (kt->name_hash_table == NULL)
123 build_keyword_hash_tables (kt);
125 hash = hash_keyword_name (kt, ke->name, 0);
126 ke->next_name = kt->name_hash_table[hash];
127 kt->name_hash_table[hash] = ke;
129 hash = hash_keyword_value (kt, ke->value);
130 ke->next_value = kt->value_hash_table[hash];
131 kt->value_hash_table[hash] = ke;
133 if (ke->name[0] == 0)
134 kt->null_entry = ke;
137 /* FIXME: Need function to return count of keywords. */
139 /* Initialize a keyword table search.
140 SPEC is a specification of what to search for.
141 A value of NULL means to find every keyword.
142 Currently NULL is the only acceptable value [further specification
143 deferred].
144 The result is an opaque data item used to record the search status.
145 It is passed to each call to cgen_keyword_search_next. */
147 CGEN_KEYWORD_SEARCH
148 cgen_keyword_search_init (kt, spec)
149 CGEN_KEYWORD *kt;
150 const char *spec;
152 CGEN_KEYWORD_SEARCH search;
154 /* FIXME: Need to specify format of PARAMS. */
155 if (spec != NULL)
156 abort ();
158 if (kt->name_hash_table == NULL)
159 build_keyword_hash_tables (kt);
161 search.table = kt;
162 search.spec = spec;
163 search.current_hash = 0;
164 search.current_entry = NULL;
165 return search;
168 /* Return the next keyword specified by SEARCH.
169 The result is the next entry or NULL if there are no more. */
171 const CGEN_KEYWORD_ENTRY *
172 cgen_keyword_search_next (search)
173 CGEN_KEYWORD_SEARCH *search;
175 /* Has search finished? */
176 if (search->current_hash == search->table->hash_table_size)
177 return NULL;
179 /* Search in progress? */
180 if (search->current_entry != NULL
181 /* Anything left on this hash chain? */
182 && search->current_entry->next_name != NULL)
184 search->current_entry = search->current_entry->next_name;
185 return search->current_entry;
188 /* Move to next hash chain [unless we haven't started yet]. */
189 if (search->current_entry != NULL)
190 ++search->current_hash;
192 while (search->current_hash < search->table->hash_table_size)
194 search->current_entry = search->table->name_hash_table[search->current_hash];
195 if (search->current_entry != NULL)
196 return search->current_entry;
197 ++search->current_hash;
200 return NULL;
203 /* Return first entry in hash chain for NAME.
204 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
206 static unsigned int
207 hash_keyword_name (kt, name, case_sensitive_p)
208 const CGEN_KEYWORD *kt;
209 const char *name;
210 int case_sensitive_p;
212 unsigned int hash;
214 if (case_sensitive_p)
215 for (hash = 0; *name; ++name)
216 hash = (hash * 97) + (unsigned char) *name;
217 else
218 for (hash = 0; *name; ++name)
219 hash = (hash * 97) + (unsigned char) tolower (*name);
220 return hash % kt->hash_table_size;
223 /* Return first entry in hash chain for VALUE. */
225 static unsigned int
226 hash_keyword_value (kt, value)
227 const CGEN_KEYWORD *kt;
228 unsigned int value;
230 return value % kt->hash_table_size;
233 /* Build a keyword table's hash tables.
234 We probably needn't build the value hash table for the assembler when
235 we're using the disassembler, but we keep things simple. */
237 static void
238 build_keyword_hash_tables (kt)
239 CGEN_KEYWORD *kt;
241 int i;
242 /* Use the number of compiled in entries as an estimate for the
243 typical sized table [not too many added at runtime]. */
244 unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);
246 kt->hash_table_size = size;
247 kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
248 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
249 memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
250 kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
251 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
252 memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
254 /* The table is scanned backwards as we want keywords appearing earlier to
255 be prefered over later ones. */
256 for (i = kt->num_init_entries - 1; i >= 0; --i)
257 cgen_keyword_add (kt, &kt->init_entries[i]);
260 /* Hardware support. */
262 /* Lookup a hardware element by its name.
263 Returns NULL if NAME is not supported by the currently selected
264 mach/isa. */
266 const CGEN_HW_ENTRY *
267 cgen_hw_lookup_by_name (cd, name)
268 CGEN_CPU_DESC cd;
269 const char *name;
271 unsigned int i;
272 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
274 for (i = 0; i < cd->hw_table.num_entries; ++i)
275 if (hw[i] && strcmp (name, hw[i]->name) == 0)
276 return hw[i];
278 return NULL;
281 /* Lookup a hardware element by its number.
282 Hardware elements are enumerated, however it may be possible to add some
283 at runtime, thus HWNUM is not an enum type but rather an int.
284 Returns NULL if HWNUM is not supported by the currently selected mach. */
286 const CGEN_HW_ENTRY *
287 cgen_hw_lookup_by_num (cd, hwnum)
288 CGEN_CPU_DESC cd;
289 unsigned int hwnum;
291 unsigned int i;
292 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
294 /* ??? This can be speeded up. */
295 for (i = 0; i < cd->hw_table.num_entries; ++i)
296 if (hw[i] && hwnum == hw[i]->type)
297 return hw[i];
299 return NULL;
302 /* Operand support. */
304 /* Lookup an operand by its name.
305 Returns NULL if NAME is not supported by the currently selected
306 mach/isa. */
308 const CGEN_OPERAND *
309 cgen_operand_lookup_by_name (cd, name)
310 CGEN_CPU_DESC cd;
311 const char *name;
313 unsigned int i;
314 const CGEN_OPERAND **op = cd->operand_table.entries;
316 for (i = 0; i < cd->operand_table.num_entries; ++i)
317 if (op[i] && strcmp (name, op[i]->name) == 0)
318 return op[i];
320 return NULL;
323 /* Lookup an operand by its number.
324 Operands are enumerated, however it may be possible to add some
325 at runtime, thus OPNUM is not an enum type but rather an int.
326 Returns NULL if OPNUM is not supported by the currently selected
327 mach/isa. */
329 const CGEN_OPERAND *
330 cgen_operand_lookup_by_num (cd, opnum)
331 CGEN_CPU_DESC cd;
332 int opnum;
334 return cd->operand_table.entries[opnum];
337 /* Instruction support. */
339 /* Return number of instructions. This includes any added at runtime. */
342 cgen_insn_count (cd)
343 CGEN_CPU_DESC cd;
345 int count = cd->insn_table.num_init_entries;
346 CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
348 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
349 ++count;
351 return count;
354 /* Return number of macro-instructions.
355 This includes any added at runtime. */
358 cgen_macro_insn_count (cd)
359 CGEN_CPU_DESC cd;
361 int count = cd->macro_insn_table.num_init_entries;
362 CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
364 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
365 ++count;
367 return count;
370 /* Cover function to read and properly byteswap an insn value. */
372 CGEN_INSN_INT
373 cgen_get_insn_value (cd, buf, length)
374 CGEN_CPU_DESC cd;
375 unsigned char *buf;
376 int length;
378 return bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
381 /* Cover function to store an insn value properly byteswapped. */
383 void
384 cgen_put_insn_value (cd, buf, length, value)
385 CGEN_CPU_DESC cd;
386 unsigned char *buf;
387 int length;
388 CGEN_INSN_INT value;
390 bfd_put_bits ((bfd_vma) value, buf, length,
391 cd->insn_endian == CGEN_ENDIAN_BIG);
394 /* Look up instruction INSN_*_VALUE and extract its fields.
395 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
396 Otherwise INSN_BYTES_VALUE is used.
397 INSN, if non-null, is the insn table entry.
398 Otherwise INSN_*_VALUE is examined to compute it.
399 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
400 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
401 If INSN != NULL, LENGTH must be valid.
402 ALIAS_P is non-zero if alias insns are to be included in the search.
404 The result is a pointer to the insn table entry, or NULL if the instruction
405 wasn't recognized. */
407 /* ??? Will need to be revisited for VLIW architectures. */
409 const CGEN_INSN *
410 cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value, length, fields,
411 alias_p)
412 CGEN_CPU_DESC cd;
413 const CGEN_INSN *insn;
414 CGEN_INSN_INT insn_int_value;
415 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
416 unsigned char *insn_bytes_value;
417 int length;
418 CGEN_FIELDS *fields;
419 int alias_p;
421 unsigned char *buf;
422 CGEN_INSN_INT base_insn;
423 CGEN_EXTRACT_INFO ex_info;
424 CGEN_EXTRACT_INFO *info;
426 if (cd->int_insn_p)
428 info = NULL;
429 buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8);
430 cgen_put_insn_value (cd, buf, length, insn_int_value);
431 base_insn = insn_int_value;
433 else
435 info = &ex_info;
436 ex_info.dis_info = NULL;
437 ex_info.insn_bytes = insn_bytes_value;
438 ex_info.valid = -1;
439 buf = insn_bytes_value;
440 base_insn = cgen_get_insn_value (cd, buf, length);
443 if (!insn)
445 const CGEN_INSN_LIST *insn_list;
447 /* The instructions are stored in hash lists.
448 Pick the first one and keep trying until we find the right one. */
450 insn_list = cgen_dis_lookup_insn (cd, buf, base_insn);
451 while (insn_list != NULL)
453 insn = insn_list->insn;
455 if (alias_p
456 /* FIXME: Ensure ALIAS attribute always has same index. */
457 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
459 /* Basic bit mask must be correct. */
460 /* ??? May wish to allow target to defer this check until the
461 extract handler. */
462 if ((base_insn & CGEN_INSN_BASE_MASK (insn))
463 == CGEN_INSN_BASE_VALUE (insn))
465 /* ??? 0 is passed for `pc' */
466 int elength = CGEN_EXTRACT_FN (cd, insn)
467 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
468 if (elength > 0)
470 /* sanity check */
471 if (length != 0 && length != elength)
472 abort ();
473 return insn;
478 insn_list = insn_list->next;
481 else
483 /* Sanity check: can't pass an alias insn if ! alias_p. */
484 if (! alias_p
485 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
486 abort ();
487 /* Sanity check: length must be correct. */
488 if (length != CGEN_INSN_BITSIZE (insn))
489 abort ();
491 /* ??? 0 is passed for `pc' */
492 length = CGEN_EXTRACT_FN (cd, insn)
493 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
494 /* Sanity check: must succeed.
495 Could relax this later if it ever proves useful. */
496 if (length == 0)
497 abort ();
498 return insn;
501 return NULL;
504 /* Fill in the operand instances used by INSN whose operands are FIELDS.
505 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
506 in. */
508 void
509 cgen_get_insn_operands (cd, insn, fields, indices)
510 CGEN_CPU_DESC cd;
511 const CGEN_INSN *insn;
512 const CGEN_FIELDS *fields;
513 int *indices;
515 const CGEN_OPINST *opinst;
516 int i;
518 if (insn->opinst == NULL)
519 abort ();
520 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
522 enum cgen_operand_type op_type = opinst->op_type;
523 if (op_type == CGEN_OPERAND_NIL)
524 indices[i] = opinst->index;
525 else
526 indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
530 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
531 isn't known.
532 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
533 cgen_lookup_insn unchanged.
534 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
535 Otherwise INSN_BYTES_VALUE is used.
537 The result is the insn table entry or NULL if the instruction wasn't
538 recognized. */
540 const CGEN_INSN *
541 cgen_lookup_get_insn_operands (cd, insn, insn_int_value, insn_bytes_value,
542 length, indices, fields)
543 CGEN_CPU_DESC cd;
544 const CGEN_INSN *insn;
545 CGEN_INSN_INT insn_int_value;
546 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
547 unsigned char *insn_bytes_value;
548 int length;
549 int *indices;
550 CGEN_FIELDS *fields;
552 /* Pass non-zero for ALIAS_P only if INSN != NULL.
553 If INSN == NULL, we want a real insn. */
554 insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
555 length, fields, insn != NULL);
556 if (! insn)
557 return NULL;
559 cgen_get_insn_operands (cd, insn, fields, indices);
560 return insn;
563 /* Allow signed overflow of instruction fields. */
564 void
565 cgen_set_signed_overflow_ok (cd)
566 CGEN_CPU_DESC cd;
568 cd->signed_overflow_ok_p = 1;
571 /* Generate an error message if a signed field in an instruction overflows. */
572 void
573 cgen_clear_signed_overflow_ok (cd)
574 CGEN_CPU_DESC cd;
576 cd->signed_overflow_ok_p = 0;
579 /* Will an error message be generated if a signed field in an instruction overflows ? */
580 unsigned int
581 cgen_signed_overflow_ok_p (cd)
582 CGEN_CPU_DESC cd;
584 return cd->signed_overflow_ok_p;