Updated Translations
[binutils.git] / opcodes / cgen-opc.c
blob06544ca057d0c1e2d4e0dad07a5e42b2c30df677
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 <stdio.h>
24 #include "ansidecl.h"
25 #include "libiberty.h"
26 #include "safe-ctype.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 (*p) && (TOLOWER (*p) == TOLOWER (*n)))))
73 ++n, ++p;
75 if (!*p && !*n)
76 return ke;
78 ke = ke->next_name;
81 if (kt->null_entry)
82 return kt->null_entry;
83 return NULL;
86 /* Look up VALUE in the keyword table KT.
87 The result is the keyword entry or NULL if not found. */
89 const CGEN_KEYWORD_ENTRY *
90 cgen_keyword_lookup_value (kt, value)
91 CGEN_KEYWORD *kt;
92 int value;
94 const CGEN_KEYWORD_ENTRY *ke;
96 if (kt->name_hash_table == NULL)
97 build_keyword_hash_tables (kt);
99 ke = kt->value_hash_table[hash_keyword_value (kt, value)];
101 while (ke != NULL)
103 if (value == ke->value)
104 return ke;
105 ke = ke->next_value;
108 return NULL;
111 /* Add an entry to a keyword table. */
113 void
114 cgen_keyword_add (kt, ke)
115 CGEN_KEYWORD *kt;
116 CGEN_KEYWORD_ENTRY *ke;
118 unsigned int hash;
119 size_t i;
121 if (kt->name_hash_table == NULL)
122 build_keyword_hash_tables (kt);
124 hash = hash_keyword_name (kt, ke->name, 0);
125 ke->next_name = kt->name_hash_table[hash];
126 kt->name_hash_table[hash] = ke;
128 hash = hash_keyword_value (kt, ke->value);
129 ke->next_value = kt->value_hash_table[hash];
130 kt->value_hash_table[hash] = ke;
132 if (ke->name[0] == 0)
133 kt->null_entry = ke;
135 for (i = 1; i < strlen (ke->name); i++)
136 if (! ISALNUM (ke->name[i])
137 && ! strchr (kt->nonalpha_chars, ke->name[i]))
139 size_t idx = strlen (kt->nonalpha_chars);
141 /* If you hit this limit, please don't just
142 increase the size of the field, instead
143 look for a better algorithm. */
144 if (idx >= sizeof (kt->nonalpha_chars) - 1)
145 abort ();
146 kt->nonalpha_chars[idx] = ke->name[i];
147 kt->nonalpha_chars[idx+1] = 0;
151 /* FIXME: Need function to return count of keywords. */
153 /* Initialize a keyword table search.
154 SPEC is a specification of what to search for.
155 A value of NULL means to find every keyword.
156 Currently NULL is the only acceptable value [further specification
157 deferred].
158 The result is an opaque data item used to record the search status.
159 It is passed to each call to cgen_keyword_search_next. */
161 CGEN_KEYWORD_SEARCH
162 cgen_keyword_search_init (kt, spec)
163 CGEN_KEYWORD *kt;
164 const char *spec;
166 CGEN_KEYWORD_SEARCH search;
168 /* FIXME: Need to specify format of PARAMS. */
169 if (spec != NULL)
170 abort ();
172 if (kt->name_hash_table == NULL)
173 build_keyword_hash_tables (kt);
175 search.table = kt;
176 search.spec = spec;
177 search.current_hash = 0;
178 search.current_entry = NULL;
179 return search;
182 /* Return the next keyword specified by SEARCH.
183 The result is the next entry or NULL if there are no more. */
185 const CGEN_KEYWORD_ENTRY *
186 cgen_keyword_search_next (search)
187 CGEN_KEYWORD_SEARCH *search;
189 /* Has search finished? */
190 if (search->current_hash == search->table->hash_table_size)
191 return NULL;
193 /* Search in progress? */
194 if (search->current_entry != NULL
195 /* Anything left on this hash chain? */
196 && search->current_entry->next_name != NULL)
198 search->current_entry = search->current_entry->next_name;
199 return search->current_entry;
202 /* Move to next hash chain [unless we haven't started yet]. */
203 if (search->current_entry != NULL)
204 ++search->current_hash;
206 while (search->current_hash < search->table->hash_table_size)
208 search->current_entry = search->table->name_hash_table[search->current_hash];
209 if (search->current_entry != NULL)
210 return search->current_entry;
211 ++search->current_hash;
214 return NULL;
217 /* Return first entry in hash chain for NAME.
218 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
220 static unsigned int
221 hash_keyword_name (kt, name, case_sensitive_p)
222 const CGEN_KEYWORD *kt;
223 const char *name;
224 int case_sensitive_p;
226 unsigned int hash;
228 if (case_sensitive_p)
229 for (hash = 0; *name; ++name)
230 hash = (hash * 97) + (unsigned char) *name;
231 else
232 for (hash = 0; *name; ++name)
233 hash = (hash * 97) + (unsigned char) TOLOWER (*name);
234 return hash % kt->hash_table_size;
237 /* Return first entry in hash chain for VALUE. */
239 static unsigned int
240 hash_keyword_value (kt, value)
241 const CGEN_KEYWORD *kt;
242 unsigned int value;
244 return value % kt->hash_table_size;
247 /* Build a keyword table's hash tables.
248 We probably needn't build the value hash table for the assembler when
249 we're using the disassembler, but we keep things simple. */
251 static void
252 build_keyword_hash_tables (kt)
253 CGEN_KEYWORD *kt;
255 int i;
256 /* Use the number of compiled in entries as an estimate for the
257 typical sized table [not too many added at runtime]. */
258 unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);
260 kt->hash_table_size = size;
261 kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
262 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
263 memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
264 kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
265 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
266 memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
268 /* The table is scanned backwards as we want keywords appearing earlier to
269 be prefered over later ones. */
270 for (i = kt->num_init_entries - 1; i >= 0; --i)
271 cgen_keyword_add (kt, &kt->init_entries[i]);
274 /* Hardware support. */
276 /* Lookup a hardware element by its name.
277 Returns NULL if NAME is not supported by the currently selected
278 mach/isa. */
280 const CGEN_HW_ENTRY *
281 cgen_hw_lookup_by_name (cd, name)
282 CGEN_CPU_DESC cd;
283 const char *name;
285 unsigned int i;
286 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
288 for (i = 0; i < cd->hw_table.num_entries; ++i)
289 if (hw[i] && strcmp (name, hw[i]->name) == 0)
290 return hw[i];
292 return NULL;
295 /* Lookup a hardware element by its number.
296 Hardware elements are enumerated, however it may be possible to add some
297 at runtime, thus HWNUM is not an enum type but rather an int.
298 Returns NULL if HWNUM is not supported by the currently selected mach. */
300 const CGEN_HW_ENTRY *
301 cgen_hw_lookup_by_num (cd, hwnum)
302 CGEN_CPU_DESC cd;
303 unsigned int hwnum;
305 unsigned int i;
306 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
308 /* ??? This can be speeded up. */
309 for (i = 0; i < cd->hw_table.num_entries; ++i)
310 if (hw[i] && hwnum == hw[i]->type)
311 return hw[i];
313 return NULL;
316 /* Operand support. */
318 /* Lookup an operand by its name.
319 Returns NULL if NAME is not supported by the currently selected
320 mach/isa. */
322 const CGEN_OPERAND *
323 cgen_operand_lookup_by_name (cd, name)
324 CGEN_CPU_DESC cd;
325 const char *name;
327 unsigned int i;
328 const CGEN_OPERAND **op = cd->operand_table.entries;
330 for (i = 0; i < cd->operand_table.num_entries; ++i)
331 if (op[i] && strcmp (name, op[i]->name) == 0)
332 return op[i];
334 return NULL;
337 /* Lookup an operand by its number.
338 Operands are enumerated, however it may be possible to add some
339 at runtime, thus OPNUM is not an enum type but rather an int.
340 Returns NULL if OPNUM is not supported by the currently selected
341 mach/isa. */
343 const CGEN_OPERAND *
344 cgen_operand_lookup_by_num (cd, opnum)
345 CGEN_CPU_DESC cd;
346 int opnum;
348 return cd->operand_table.entries[opnum];
351 /* Instruction support. */
353 /* Return number of instructions. This includes any added at runtime. */
356 cgen_insn_count (cd)
357 CGEN_CPU_DESC cd;
359 int count = cd->insn_table.num_init_entries;
360 CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
362 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
363 ++count;
365 return count;
368 /* Return number of macro-instructions.
369 This includes any added at runtime. */
372 cgen_macro_insn_count (cd)
373 CGEN_CPU_DESC cd;
375 int count = cd->macro_insn_table.num_init_entries;
376 CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
378 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
379 ++count;
381 return count;
384 /* Cover function to read and properly byteswap an insn value. */
386 CGEN_INSN_INT
387 cgen_get_insn_value (cd, buf, length)
388 CGEN_CPU_DESC cd;
389 unsigned char *buf;
390 int length;
392 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
393 int insn_chunk_bitsize = cd->insn_chunk_bitsize;
394 CGEN_INSN_INT value = 0;
396 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
398 /* We need to divide up the incoming value into insn_chunk_bitsize-length
399 segments, and endian-convert them, one at a time. */
400 int i;
402 /* Enforce divisibility. */
403 if ((length % insn_chunk_bitsize) != 0)
404 abort ();
406 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
408 int index;
409 bfd_vma this_value;
410 index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
411 this_value = bfd_get_bits (& buf[index / 8], insn_chunk_bitsize, big_p);
412 value = (value << insn_chunk_bitsize) | this_value;
415 else
417 value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
420 return value;
423 /* Cover function to store an insn value properly byteswapped. */
425 void
426 cgen_put_insn_value (cd, buf, length, value)
427 CGEN_CPU_DESC cd;
428 unsigned char *buf;
429 int length;
430 CGEN_INSN_INT value;
432 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
433 int insn_chunk_bitsize = cd->insn_chunk_bitsize;
435 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
437 /* We need to divide up the incoming value into insn_chunk_bitsize-length
438 segments, and endian-convert them, one at a time. */
439 int i;
441 /* Enforce divisibility. */
442 if ((length % insn_chunk_bitsize) != 0)
443 abort ();
445 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
447 int index;
448 index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
449 bfd_put_bits ((bfd_vma) value, & buf[index / 8], insn_chunk_bitsize, big_p);
450 value >>= insn_chunk_bitsize;
453 else
455 bfd_put_bits ((bfd_vma) value, buf, length, big_p);
459 /* Look up instruction INSN_*_VALUE and extract its fields.
460 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
461 Otherwise INSN_BYTES_VALUE is used.
462 INSN, if non-null, is the insn table entry.
463 Otherwise INSN_*_VALUE is examined to compute it.
464 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
465 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
466 If INSN != NULL, LENGTH must be valid.
467 ALIAS_P is non-zero if alias insns are to be included in the search.
469 The result is a pointer to the insn table entry, or NULL if the instruction
470 wasn't recognized. */
472 /* ??? Will need to be revisited for VLIW architectures. */
474 const CGEN_INSN *
475 cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value, length, fields,
476 alias_p)
477 CGEN_CPU_DESC cd;
478 const CGEN_INSN *insn;
479 CGEN_INSN_INT insn_int_value;
480 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
481 unsigned char *insn_bytes_value;
482 int length;
483 CGEN_FIELDS *fields;
484 int alias_p;
486 unsigned char *buf;
487 CGEN_INSN_INT base_insn;
488 CGEN_EXTRACT_INFO ex_info;
489 CGEN_EXTRACT_INFO *info;
491 if (cd->int_insn_p)
493 info = NULL;
494 buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8);
495 cgen_put_insn_value (cd, buf, length, insn_int_value);
496 base_insn = insn_int_value;
498 else
500 info = &ex_info;
501 ex_info.dis_info = NULL;
502 ex_info.insn_bytes = insn_bytes_value;
503 ex_info.valid = -1;
504 buf = insn_bytes_value;
505 base_insn = cgen_get_insn_value (cd, buf, length);
508 if (!insn)
510 const CGEN_INSN_LIST *insn_list;
512 /* The instructions are stored in hash lists.
513 Pick the first one and keep trying until we find the right one. */
515 insn_list = cgen_dis_lookup_insn (cd, buf, base_insn);
516 while (insn_list != NULL)
518 insn = insn_list->insn;
520 if (alias_p
521 /* FIXME: Ensure ALIAS attribute always has same index. */
522 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
524 /* Basic bit mask must be correct. */
525 /* ??? May wish to allow target to defer this check until the
526 extract handler. */
527 if ((base_insn & CGEN_INSN_BASE_MASK (insn))
528 == CGEN_INSN_BASE_VALUE (insn))
530 /* ??? 0 is passed for `pc' */
531 int elength = CGEN_EXTRACT_FN (cd, insn)
532 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
533 if (elength > 0)
535 /* sanity check */
536 if (length != 0 && length != elength)
537 abort ();
538 return insn;
543 insn_list = insn_list->next;
546 else
548 /* Sanity check: can't pass an alias insn if ! alias_p. */
549 if (! alias_p
550 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
551 abort ();
552 /* Sanity check: length must be correct. */
553 if (length != CGEN_INSN_BITSIZE (insn))
554 abort ();
556 /* ??? 0 is passed for `pc' */
557 length = CGEN_EXTRACT_FN (cd, insn)
558 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
559 /* Sanity check: must succeed.
560 Could relax this later if it ever proves useful. */
561 if (length == 0)
562 abort ();
563 return insn;
566 return NULL;
569 /* Fill in the operand instances used by INSN whose operands are FIELDS.
570 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
571 in. */
573 void
574 cgen_get_insn_operands (cd, insn, fields, indices)
575 CGEN_CPU_DESC cd;
576 const CGEN_INSN *insn;
577 const CGEN_FIELDS *fields;
578 int *indices;
580 const CGEN_OPINST *opinst;
581 int i;
583 if (insn->opinst == NULL)
584 abort ();
585 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
587 enum cgen_operand_type op_type = opinst->op_type;
588 if (op_type == CGEN_OPERAND_NIL)
589 indices[i] = opinst->index;
590 else
591 indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
595 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
596 isn't known.
597 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
598 cgen_lookup_insn unchanged.
599 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
600 Otherwise INSN_BYTES_VALUE is used.
602 The result is the insn table entry or NULL if the instruction wasn't
603 recognized. */
605 const CGEN_INSN *
606 cgen_lookup_get_insn_operands (cd, insn, insn_int_value, insn_bytes_value,
607 length, indices, fields)
608 CGEN_CPU_DESC cd;
609 const CGEN_INSN *insn;
610 CGEN_INSN_INT insn_int_value;
611 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
612 unsigned char *insn_bytes_value;
613 int length;
614 int *indices;
615 CGEN_FIELDS *fields;
617 /* Pass non-zero for ALIAS_P only if INSN != NULL.
618 If INSN == NULL, we want a real insn. */
619 insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
620 length, fields, insn != NULL);
621 if (! insn)
622 return NULL;
624 cgen_get_insn_operands (cd, insn, fields, indices);
625 return insn;
628 /* Allow signed overflow of instruction fields. */
629 void
630 cgen_set_signed_overflow_ok (cd)
631 CGEN_CPU_DESC cd;
633 cd->signed_overflow_ok_p = 1;
636 /* Generate an error message if a signed field in an instruction overflows. */
637 void
638 cgen_clear_signed_overflow_ok (cd)
639 CGEN_CPU_DESC cd;
641 cd->signed_overflow_ok_p = 0;
644 /* Will an error message be generated if a signed field in an instruction overflows ? */
645 unsigned int
646 cgen_signed_overflow_ok_p (cd)
647 CGEN_CPU_DESC cd;
649 return cd->signed_overflow_ok_p;