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)
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. */
26 #include "libiberty.h"
29 #include "opcode/cgen.h"
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)
53 const CGEN_KEYWORD_ENTRY *ke;
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". */
72 || (isalpha ((unsigned char) *p)
73 && (tolower ((unsigned char) *p)
74 == tolower ((unsigned char) *n)))))
84 return kt->null_entry;
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)
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)];
105 if (value == ke->value)
113 /* Add an entry to a keyword table. */
116 cgen_keyword_add (kt, ke)
118 CGEN_KEYWORD_ENTRY *ke;
123 if (kt->name_hash_table == NULL)
124 build_keyword_hash_tables (kt);
126 hash = hash_keyword_name (kt, ke->name, 0);
127 ke->next_name = kt->name_hash_table[hash];
128 kt->name_hash_table[hash] = ke;
130 hash = hash_keyword_value (kt, ke->value);
131 ke->next_value = kt->value_hash_table[hash];
132 kt->value_hash_table[hash] = ke;
134 if (ke->name[0] == 0)
137 for (i = 1; i < strlen (ke->name); i++)
138 if (! isalnum ((unsigned char) ke->name[i])
139 && ! strchr (kt->nonalpha_chars, ke->name[i]))
141 size_t idx = strlen (kt->nonalpha_chars);
143 /* If you hit this limit, please don't just
144 increase the size of the field, instead
145 look for a better algorithm. */
146 if (idx >= sizeof (kt->nonalpha_chars) - 1)
148 kt->nonalpha_chars[idx] = ke->name[i];
149 kt->nonalpha_chars[idx+1] = 0;
153 /* FIXME: Need function to return count of keywords. */
155 /* Initialize a keyword table search.
156 SPEC is a specification of what to search for.
157 A value of NULL means to find every keyword.
158 Currently NULL is the only acceptable value [further specification
160 The result is an opaque data item used to record the search status.
161 It is passed to each call to cgen_keyword_search_next. */
164 cgen_keyword_search_init (kt, spec)
168 CGEN_KEYWORD_SEARCH search;
170 /* FIXME: Need to specify format of PARAMS. */
174 if (kt->name_hash_table == NULL)
175 build_keyword_hash_tables (kt);
179 search.current_hash = 0;
180 search.current_entry = NULL;
184 /* Return the next keyword specified by SEARCH.
185 The result is the next entry or NULL if there are no more. */
187 const CGEN_KEYWORD_ENTRY *
188 cgen_keyword_search_next (search)
189 CGEN_KEYWORD_SEARCH *search;
191 /* Has search finished? */
192 if (search->current_hash == search->table->hash_table_size)
195 /* Search in progress? */
196 if (search->current_entry != NULL
197 /* Anything left on this hash chain? */
198 && search->current_entry->next_name != NULL)
200 search->current_entry = search->current_entry->next_name;
201 return search->current_entry;
204 /* Move to next hash chain [unless we haven't started yet]. */
205 if (search->current_entry != NULL)
206 ++search->current_hash;
208 while (search->current_hash < search->table->hash_table_size)
210 search->current_entry = search->table->name_hash_table[search->current_hash];
211 if (search->current_entry != NULL)
212 return search->current_entry;
213 ++search->current_hash;
219 /* Return first entry in hash chain for NAME.
220 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
223 hash_keyword_name (kt, name, case_sensitive_p)
224 const CGEN_KEYWORD *kt;
226 int case_sensitive_p;
230 if (case_sensitive_p)
231 for (hash = 0; *name; ++name)
232 hash = (hash * 97) + (unsigned char) *name;
234 for (hash = 0; *name; ++name)
235 hash = (hash * 97) + (unsigned char) tolower (*name);
236 return hash % kt->hash_table_size;
239 /* Return first entry in hash chain for VALUE. */
242 hash_keyword_value (kt, value)
243 const CGEN_KEYWORD *kt;
246 return value % kt->hash_table_size;
249 /* Build a keyword table's hash tables.
250 We probably needn't build the value hash table for the assembler when
251 we're using the disassembler, but we keep things simple. */
254 build_keyword_hash_tables (kt)
258 /* Use the number of compiled in entries as an estimate for the
259 typical sized table [not too many added at runtime]. */
260 unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);
262 kt->hash_table_size = size;
263 kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
264 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
265 memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
266 kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
267 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
268 memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
270 /* The table is scanned backwards as we want keywords appearing earlier to
271 be prefered over later ones. */
272 for (i = kt->num_init_entries - 1; i >= 0; --i)
273 cgen_keyword_add (kt, &kt->init_entries[i]);
276 /* Hardware support. */
278 /* Lookup a hardware element by its name.
279 Returns NULL if NAME is not supported by the currently selected
282 const CGEN_HW_ENTRY *
283 cgen_hw_lookup_by_name (cd, name)
288 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
290 for (i = 0; i < cd->hw_table.num_entries; ++i)
291 if (hw[i] && strcmp (name, hw[i]->name) == 0)
297 /* Lookup a hardware element by its number.
298 Hardware elements are enumerated, however it may be possible to add some
299 at runtime, thus HWNUM is not an enum type but rather an int.
300 Returns NULL if HWNUM is not supported by the currently selected mach. */
302 const CGEN_HW_ENTRY *
303 cgen_hw_lookup_by_num (cd, hwnum)
308 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
310 /* ??? This can be speeded up. */
311 for (i = 0; i < cd->hw_table.num_entries; ++i)
312 if (hw[i] && hwnum == hw[i]->type)
318 /* Operand support. */
320 /* Lookup an operand by its name.
321 Returns NULL if NAME is not supported by the currently selected
325 cgen_operand_lookup_by_name (cd, name)
330 const CGEN_OPERAND **op = cd->operand_table.entries;
332 for (i = 0; i < cd->operand_table.num_entries; ++i)
333 if (op[i] && strcmp (name, op[i]->name) == 0)
339 /* Lookup an operand by its number.
340 Operands are enumerated, however it may be possible to add some
341 at runtime, thus OPNUM is not an enum type but rather an int.
342 Returns NULL if OPNUM is not supported by the currently selected
346 cgen_operand_lookup_by_num (cd, opnum)
350 return cd->operand_table.entries[opnum];
353 /* Instruction support. */
355 /* Return number of instructions. This includes any added at runtime. */
361 int count = cd->insn_table.num_init_entries;
362 CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
364 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
370 /* Return number of macro-instructions.
371 This includes any added at runtime. */
374 cgen_macro_insn_count (cd)
377 int count = cd->macro_insn_table.num_init_entries;
378 CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
380 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
386 /* Cover function to read and properly byteswap an insn value. */
389 cgen_get_insn_value (cd, buf, length)
394 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
395 int insn_chunk_bitsize = cd->insn_chunk_bitsize;
396 CGEN_INSN_INT value = 0;
398 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
400 /* We need to divide up the incoming value into insn_chunk_bitsize-length
401 segments, and endian-convert them, one at a time. */
404 /* Enforce divisibility. */
405 if ((length % insn_chunk_bitsize) != 0)
408 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
412 index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
413 this_value = bfd_get_bits (& buf[index / 8], insn_chunk_bitsize, big_p);
414 value = (value << insn_chunk_bitsize) | this_value;
419 value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
425 /* Cover function to store an insn value properly byteswapped. */
428 cgen_put_insn_value (cd, buf, length, value)
434 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
435 int insn_chunk_bitsize = cd->insn_chunk_bitsize;
437 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
439 /* We need to divide up the incoming value into insn_chunk_bitsize-length
440 segments, and endian-convert them, one at a time. */
443 /* Enforce divisibility. */
444 if ((length % insn_chunk_bitsize) != 0)
447 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
450 index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
451 bfd_put_bits ((bfd_vma) value, & buf[index / 8], insn_chunk_bitsize, big_p);
452 value >>= insn_chunk_bitsize;
457 bfd_put_bits ((bfd_vma) value, buf, length, big_p);
461 /* Look up instruction INSN_*_VALUE and extract its fields.
462 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
463 Otherwise INSN_BYTES_VALUE is used.
464 INSN, if non-null, is the insn table entry.
465 Otherwise INSN_*_VALUE is examined to compute it.
466 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
467 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
468 If INSN != NULL, LENGTH must be valid.
469 ALIAS_P is non-zero if alias insns are to be included in the search.
471 The result is a pointer to the insn table entry, or NULL if the instruction
472 wasn't recognized. */
474 /* ??? Will need to be revisited for VLIW architectures. */
477 cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value, length, fields,
480 const CGEN_INSN *insn;
481 CGEN_INSN_INT insn_int_value;
482 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
483 unsigned char *insn_bytes_value;
489 CGEN_INSN_INT base_insn;
490 CGEN_EXTRACT_INFO ex_info;
491 CGEN_EXTRACT_INFO *info;
496 buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8);
497 cgen_put_insn_value (cd, buf, length, insn_int_value);
498 base_insn = insn_int_value;
503 ex_info.dis_info = NULL;
504 ex_info.insn_bytes = insn_bytes_value;
506 buf = insn_bytes_value;
507 base_insn = cgen_get_insn_value (cd, buf, length);
512 const CGEN_INSN_LIST *insn_list;
514 /* The instructions are stored in hash lists.
515 Pick the first one and keep trying until we find the right one. */
517 insn_list = cgen_dis_lookup_insn (cd, buf, base_insn);
518 while (insn_list != NULL)
520 insn = insn_list->insn;
523 /* FIXME: Ensure ALIAS attribute always has same index. */
524 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
526 /* Basic bit mask must be correct. */
527 /* ??? May wish to allow target to defer this check until the
529 if ((base_insn & CGEN_INSN_BASE_MASK (insn))
530 == CGEN_INSN_BASE_VALUE (insn))
532 /* ??? 0 is passed for `pc' */
533 int elength = CGEN_EXTRACT_FN (cd, insn)
534 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
538 if (length != 0 && length != elength)
545 insn_list = insn_list->next;
550 /* Sanity check: can't pass an alias insn if ! alias_p. */
552 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
554 /* Sanity check: length must be correct. */
555 if (length != CGEN_INSN_BITSIZE (insn))
558 /* ??? 0 is passed for `pc' */
559 length = CGEN_EXTRACT_FN (cd, insn)
560 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
561 /* Sanity check: must succeed.
562 Could relax this later if it ever proves useful. */
571 /* Fill in the operand instances used by INSN whose operands are FIELDS.
572 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
576 cgen_get_insn_operands (cd, insn, fields, indices)
578 const CGEN_INSN *insn;
579 const CGEN_FIELDS *fields;
582 const CGEN_OPINST *opinst;
585 if (insn->opinst == NULL)
587 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
589 enum cgen_operand_type op_type = opinst->op_type;
590 if (op_type == CGEN_OPERAND_NIL)
591 indices[i] = opinst->index;
593 indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
597 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
599 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
600 cgen_lookup_insn unchanged.
601 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
602 Otherwise INSN_BYTES_VALUE is used.
604 The result is the insn table entry or NULL if the instruction wasn't
608 cgen_lookup_get_insn_operands (cd, insn, insn_int_value, insn_bytes_value,
609 length, indices, fields)
611 const CGEN_INSN *insn;
612 CGEN_INSN_INT insn_int_value;
613 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
614 unsigned char *insn_bytes_value;
619 /* Pass non-zero for ALIAS_P only if INSN != NULL.
620 If INSN == NULL, we want a real insn. */
621 insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
622 length, fields, insn != NULL);
626 cgen_get_insn_operands (cd, insn, fields, indices);
630 /* Allow signed overflow of instruction fields. */
632 cgen_set_signed_overflow_ok (cd)
635 cd->signed_overflow_ok_p = 1;
638 /* Generate an error message if a signed field in an instruction overflows. */
640 cgen_clear_signed_overflow_ok (cd)
643 cd->signed_overflow_ok_p = 0;
646 /* Will an error message be generated if a signed field in an instruction overflows ? */
648 cgen_signed_overflow_ok_p (cd)
651 return cd->signed_overflow_ok_p;