]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/cgen-opc.c
Change source files over to GPLv3.
[thirdparty/binutils-gdb.git] / opcodes / cgen-opc.c
CommitLineData
252b5132
RH
1/* CGEN generic opcode support.
2
9b201bb5 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005, 2007
060d22b0 4 Free Software Foundation, Inc.
252b5132 5
9b201bb5 6 This file is part of libopcodes.
252b5132 7
9b201bb5 8 This library is free software; you can redistribute it and/or modify
252b5132 9 it under the terms of the GNU General Public License as published by
9b201bb5 10 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
11 any later version.
12
9b201bb5
NC
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
252b5132
RH
17
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.,
f4321104 20 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252b5132
RH
21
22#include "sysdep.h"
252b5132
RH
23#include <stdio.h>
24#include "ansidecl.h"
25#include "libiberty.h"
3882b010 26#include "safe-ctype.h"
252b5132
RH
27#include "bfd.h"
28#include "symcat.h"
29#include "opcode/cgen.h"
30
a6cff3e3
NC
31#ifdef HAVE_ALLOCA_H
32#include <alloca.h>
33#endif
34
252b5132 35static unsigned int hash_keyword_name
10e05405 36 (const CGEN_KEYWORD *, const char *, int);
252b5132 37static unsigned int hash_keyword_value
10e05405 38 (const CGEN_KEYWORD *, unsigned int);
252b5132 39static void build_keyword_hash_tables
10e05405 40 (CGEN_KEYWORD *);
252b5132
RH
41
42/* Return number of hash table entries to use for N elements. */
43#define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
44
45/* Look up *NAMEP in the keyword table KT.
46 The result is the keyword entry or NULL if not found. */
47
48const CGEN_KEYWORD_ENTRY *
10e05405 49cgen_keyword_lookup_name (CGEN_KEYWORD *kt, const char *name)
252b5132
RH
50{
51 const CGEN_KEYWORD_ENTRY *ke;
52 const char *p,*n;
53
54 if (kt->name_hash_table == NULL)
55 build_keyword_hash_tables (kt);
56
57 ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)];
58
59 /* We do case insensitive comparisons.
60 If that ever becomes a problem, add an attribute that denotes
61 "do case sensitive comparisons". */
62
63 while (ke != NULL)
64 {
65 n = name;
66 p = ke->name;
67
68 while (*p
69 && (*p == *n
3882b010 70 || (ISALPHA (*p) && (TOLOWER (*p) == TOLOWER (*n)))))
252b5132
RH
71 ++n, ++p;
72
73 if (!*p && !*n)
74 return ke;
75
76 ke = ke->next_name;
77 }
78
79 if (kt->null_entry)
80 return kt->null_entry;
81 return NULL;
82}
83
84/* Look up VALUE in the keyword table KT.
85 The result is the keyword entry or NULL if not found. */
86
87const CGEN_KEYWORD_ENTRY *
10e05405 88cgen_keyword_lookup_value (CGEN_KEYWORD *kt, int value)
252b5132
RH
89{
90 const CGEN_KEYWORD_ENTRY *ke;
91
92 if (kt->name_hash_table == NULL)
93 build_keyword_hash_tables (kt);
94
95 ke = kt->value_hash_table[hash_keyword_value (kt, value)];
96
97 while (ke != NULL)
98 {
99 if (value == ke->value)
100 return ke;
101 ke = ke->next_value;
102 }
103
104 return NULL;
105}
106
107/* Add an entry to a keyword table. */
108
109void
10e05405 110cgen_keyword_add (CGEN_KEYWORD *kt, CGEN_KEYWORD_ENTRY *ke)
252b5132
RH
111{
112 unsigned int hash;
3e890047 113 size_t i;
252b5132
RH
114
115 if (kt->name_hash_table == NULL)
116 build_keyword_hash_tables (kt);
117
118 hash = hash_keyword_name (kt, ke->name, 0);
119 ke->next_name = kt->name_hash_table[hash];
120 kt->name_hash_table[hash] = ke;
121
122 hash = hash_keyword_value (kt, ke->value);
123 ke->next_value = kt->value_hash_table[hash];
124 kt->value_hash_table[hash] = ke;
125
126 if (ke->name[0] == 0)
127 kt->null_entry = ke;
3e890047 128
5e91c3b4 129 for (i = 1; i < strlen (ke->name); i++)
3882b010 130 if (! ISALNUM (ke->name[i])
3e890047
GK
131 && ! strchr (kt->nonalpha_chars, ke->name[i]))
132 {
133 size_t idx = strlen (kt->nonalpha_chars);
134
135 /* If you hit this limit, please don't just
136 increase the size of the field, instead
137 look for a better algorithm. */
138 if (idx >= sizeof (kt->nonalpha_chars) - 1)
139 abort ();
140 kt->nonalpha_chars[idx] = ke->name[i];
141 kt->nonalpha_chars[idx+1] = 0;
142 }
252b5132
RH
143}
144
145/* FIXME: Need function to return count of keywords. */
146
147/* Initialize a keyword table search.
148 SPEC is a specification of what to search for.
149 A value of NULL means to find every keyword.
150 Currently NULL is the only acceptable value [further specification
151 deferred].
152 The result is an opaque data item used to record the search status.
153 It is passed to each call to cgen_keyword_search_next. */
154
155CGEN_KEYWORD_SEARCH
10e05405 156cgen_keyword_search_init (CGEN_KEYWORD *kt, const char *spec)
252b5132
RH
157{
158 CGEN_KEYWORD_SEARCH search;
159
47b0e7ad 160 /* FIXME: Need to specify format of params. */
252b5132
RH
161 if (spec != NULL)
162 abort ();
163
164 if (kt->name_hash_table == NULL)
165 build_keyword_hash_tables (kt);
166
167 search.table = kt;
168 search.spec = spec;
169 search.current_hash = 0;
170 search.current_entry = NULL;
171 return search;
172}
173
174/* Return the next keyword specified by SEARCH.
175 The result is the next entry or NULL if there are no more. */
176
177const CGEN_KEYWORD_ENTRY *
10e05405 178cgen_keyword_search_next (CGEN_KEYWORD_SEARCH *search)
252b5132
RH
179{
180 /* Has search finished? */
181 if (search->current_hash == search->table->hash_table_size)
182 return NULL;
183
184 /* Search in progress? */
185 if (search->current_entry != NULL
186 /* Anything left on this hash chain? */
187 && search->current_entry->next_name != NULL)
188 {
189 search->current_entry = search->current_entry->next_name;
190 return search->current_entry;
191 }
192
193 /* Move to next hash chain [unless we haven't started yet]. */
194 if (search->current_entry != NULL)
195 ++search->current_hash;
196
197 while (search->current_hash < search->table->hash_table_size)
198 {
199 search->current_entry = search->table->name_hash_table[search->current_hash];
200 if (search->current_entry != NULL)
201 return search->current_entry;
202 ++search->current_hash;
203 }
204
205 return NULL;
206}
207
208/* Return first entry in hash chain for NAME.
209 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
210
211static unsigned int
10e05405
MM
212hash_keyword_name (const CGEN_KEYWORD *kt,
213 const char *name,
214 int case_sensitive_p)
252b5132
RH
215{
216 unsigned int hash;
217
218 if (case_sensitive_p)
219 for (hash = 0; *name; ++name)
220 hash = (hash * 97) + (unsigned char) *name;
221 else
222 for (hash = 0; *name; ++name)
3882b010 223 hash = (hash * 97) + (unsigned char) TOLOWER (*name);
252b5132
RH
224 return hash % kt->hash_table_size;
225}
226
227/* Return first entry in hash chain for VALUE. */
228
229static unsigned int
10e05405 230hash_keyword_value (const CGEN_KEYWORD *kt, unsigned int value)
252b5132
RH
231{
232 return value % kt->hash_table_size;
233}
234
235/* Build a keyword table's hash tables.
236 We probably needn't build the value hash table for the assembler when
237 we're using the disassembler, but we keep things simple. */
238
239static void
10e05405 240build_keyword_hash_tables (CGEN_KEYWORD *kt)
252b5132
RH
241{
242 int i;
243 /* Use the number of compiled in entries as an estimate for the
244 typical sized table [not too many added at runtime]. */
245 unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);
246
247 kt->hash_table_size = size;
248 kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
249 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
250 memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
251 kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
252 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
253 memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
254
255 /* The table is scanned backwards as we want keywords appearing earlier to
256 be prefered over later ones. */
257 for (i = kt->num_init_entries - 1; i >= 0; --i)
258 cgen_keyword_add (kt, &kt->init_entries[i]);
259}
260\f
261/* Hardware support. */
262
263/* Lookup a hardware element by its name.
264 Returns NULL if NAME is not supported by the currently selected
265 mach/isa. */
266
267const CGEN_HW_ENTRY *
10e05405 268cgen_hw_lookup_by_name (CGEN_CPU_DESC cd, const char *name)
252b5132 269{
510925d3 270 unsigned int i;
252b5132
RH
271 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
272
273 for (i = 0; i < cd->hw_table.num_entries; ++i)
274 if (hw[i] && strcmp (name, hw[i]->name) == 0)
275 return hw[i];
276
277 return NULL;
278}
279
280/* Lookup a hardware element by its number.
281 Hardware elements are enumerated, however it may be possible to add some
282 at runtime, thus HWNUM is not an enum type but rather an int.
283 Returns NULL if HWNUM is not supported by the currently selected mach. */
284
285const CGEN_HW_ENTRY *
10e05405 286cgen_hw_lookup_by_num (CGEN_CPU_DESC cd, unsigned int hwnum)
252b5132 287{
510925d3 288 unsigned int i;
252b5132
RH
289 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
290
291 /* ??? This can be speeded up. */
292 for (i = 0; i < cd->hw_table.num_entries; ++i)
293 if (hw[i] && hwnum == hw[i]->type)
294 return hw[i];
295
296 return NULL;
297}
298\f
299/* Operand support. */
300
301/* Lookup an operand by its name.
302 Returns NULL if NAME is not supported by the currently selected
303 mach/isa. */
304
305const CGEN_OPERAND *
10e05405 306cgen_operand_lookup_by_name (CGEN_CPU_DESC cd, const char *name)
252b5132 307{
510925d3 308 unsigned int i;
252b5132
RH
309 const CGEN_OPERAND **op = cd->operand_table.entries;
310
311 for (i = 0; i < cd->operand_table.num_entries; ++i)
312 if (op[i] && strcmp (name, op[i]->name) == 0)
313 return op[i];
314
315 return NULL;
316}
317
318/* Lookup an operand by its number.
319 Operands are enumerated, however it may be possible to add some
320 at runtime, thus OPNUM is not an enum type but rather an int.
321 Returns NULL if OPNUM is not supported by the currently selected
322 mach/isa. */
323
324const CGEN_OPERAND *
10e05405 325cgen_operand_lookup_by_num (CGEN_CPU_DESC cd, int opnum)
252b5132
RH
326{
327 return cd->operand_table.entries[opnum];
328}
329\f
330/* Instruction support. */
331
332/* Return number of instructions. This includes any added at runtime. */
333
334int
10e05405 335cgen_insn_count (CGEN_CPU_DESC cd)
252b5132
RH
336{
337 int count = cd->insn_table.num_init_entries;
338 CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
339
340 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
341 ++count;
342
343 return count;
344}
345
346/* Return number of macro-instructions.
347 This includes any added at runtime. */
348
349int
10e05405 350cgen_macro_insn_count (CGEN_CPU_DESC cd)
252b5132
RH
351{
352 int count = cd->macro_insn_table.num_init_entries;
353 CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
354
355 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
356 ++count;
357
358 return count;
359}
360
361/* Cover function to read and properly byteswap an insn value. */
362
363CGEN_INSN_INT
10e05405 364cgen_get_insn_value (CGEN_CPU_DESC cd, unsigned char *buf, int length)
252b5132 365{
81f6038f
FCE
366 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
367 int insn_chunk_bitsize = cd->insn_chunk_bitsize;
368 CGEN_INSN_INT value = 0;
369
370 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
371 {
372 /* We need to divide up the incoming value into insn_chunk_bitsize-length
373 segments, and endian-convert them, one at a time. */
374 int i;
375
376 /* Enforce divisibility. */
377 if ((length % insn_chunk_bitsize) != 0)
378 abort ();
379
380 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
381 {
382 int index;
383 bfd_vma this_value;
384 index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
385 this_value = bfd_get_bits (& buf[index / 8], insn_chunk_bitsize, big_p);
386 value = (value << insn_chunk_bitsize) | this_value;
387 }
388 }
389 else
390 {
391 value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
392 }
393
394 return value;
252b5132
RH
395}
396
397/* Cover function to store an insn value properly byteswapped. */
398
399void
10e05405
MM
400cgen_put_insn_value (CGEN_CPU_DESC cd,
401 unsigned char *buf,
402 int length,
403 CGEN_INSN_INT value)
252b5132 404{
81f6038f
FCE
405 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
406 int insn_chunk_bitsize = cd->insn_chunk_bitsize;
407
408 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
409 {
410 /* We need to divide up the incoming value into insn_chunk_bitsize-length
411 segments, and endian-convert them, one at a time. */
412 int i;
413
414 /* Enforce divisibility. */
415 if ((length % insn_chunk_bitsize) != 0)
416 abort ();
417
418 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
419 {
420 int index;
421 index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
422 bfd_put_bits ((bfd_vma) value, & buf[index / 8], insn_chunk_bitsize, big_p);
423 value >>= insn_chunk_bitsize;
424 }
425 }
426 else
427 {
428 bfd_put_bits ((bfd_vma) value, buf, length, big_p);
429 }
252b5132
RH
430}
431\f
432/* Look up instruction INSN_*_VALUE and extract its fields.
433 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
434 Otherwise INSN_BYTES_VALUE is used.
435 INSN, if non-null, is the insn table entry.
436 Otherwise INSN_*_VALUE is examined to compute it.
437 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
438 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
439 If INSN != NULL, LENGTH must be valid.
440 ALIAS_P is non-zero if alias insns are to be included in the search.
441
442 The result is a pointer to the insn table entry, or NULL if the instruction
443 wasn't recognized. */
444
445/* ??? Will need to be revisited for VLIW architectures. */
446
447const CGEN_INSN *
10e05405
MM
448cgen_lookup_insn (CGEN_CPU_DESC cd,
449 const CGEN_INSN *insn,
450 CGEN_INSN_INT insn_int_value,
451 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
452 unsigned char *insn_bytes_value,
453 int length,
454 CGEN_FIELDS *fields,
455 int alias_p)
252b5132
RH
456{
457 unsigned char *buf;
458 CGEN_INSN_INT base_insn;
459 CGEN_EXTRACT_INFO ex_info;
460 CGEN_EXTRACT_INFO *info;
461
462 if (cd->int_insn_p)
463 {
464 info = NULL;
465 buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8);
466 cgen_put_insn_value (cd, buf, length, insn_int_value);
467 base_insn = insn_int_value;
468 }
469 else
470 {
471 info = &ex_info;
472 ex_info.dis_info = NULL;
473 ex_info.insn_bytes = insn_bytes_value;
474 ex_info.valid = -1;
475 buf = insn_bytes_value;
476 base_insn = cgen_get_insn_value (cd, buf, length);
477 }
478
479 if (!insn)
480 {
481 const CGEN_INSN_LIST *insn_list;
482
483 /* The instructions are stored in hash lists.
484 Pick the first one and keep trying until we find the right one. */
485
53c9ebc5 486 insn_list = cgen_dis_lookup_insn (cd, (char *) buf, base_insn);
252b5132
RH
487 while (insn_list != NULL)
488 {
489 insn = insn_list->insn;
490
491 if (alias_p
492 /* FIXME: Ensure ALIAS attribute always has same index. */
493 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
494 {
495 /* Basic bit mask must be correct. */
496 /* ??? May wish to allow target to defer this check until the
497 extract handler. */
498 if ((base_insn & CGEN_INSN_BASE_MASK (insn))
499 == CGEN_INSN_BASE_VALUE (insn))
500 {
501 /* ??? 0 is passed for `pc' */
502 int elength = CGEN_EXTRACT_FN (cd, insn)
503 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
504 if (elength > 0)
505 {
506 /* sanity check */
507 if (length != 0 && length != elength)
508 abort ();
509 return insn;
510 }
511 }
512 }
513
514 insn_list = insn_list->next;
515 }
516 }
517 else
518 {
519 /* Sanity check: can't pass an alias insn if ! alias_p. */
520 if (! alias_p
521 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
522 abort ();
523 /* Sanity check: length must be correct. */
524 if (length != CGEN_INSN_BITSIZE (insn))
525 abort ();
526
527 /* ??? 0 is passed for `pc' */
528 length = CGEN_EXTRACT_FN (cd, insn)
529 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
530 /* Sanity check: must succeed.
531 Could relax this later if it ever proves useful. */
532 if (length == 0)
533 abort ();
534 return insn;
535 }
536
537 return NULL;
538}
539
540/* Fill in the operand instances used by INSN whose operands are FIELDS.
541 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
542 in. */
543
544void
10e05405
MM
545cgen_get_insn_operands (CGEN_CPU_DESC cd,
546 const CGEN_INSN *insn,
547 const CGEN_FIELDS *fields,
548 int *indices)
252b5132
RH
549{
550 const CGEN_OPINST *opinst;
551 int i;
552
553 if (insn->opinst == NULL)
554 abort ();
555 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
556 {
557 enum cgen_operand_type op_type = opinst->op_type;
558 if (op_type == CGEN_OPERAND_NIL)
559 indices[i] = opinst->index;
560 else
561 indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
562 }
563}
564
565/* Cover function to cgen_get_insn_operands when either INSN or FIELDS
566 isn't known.
567 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
568 cgen_lookup_insn unchanged.
569 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
570 Otherwise INSN_BYTES_VALUE is used.
571
572 The result is the insn table entry or NULL if the instruction wasn't
573 recognized. */
574
575const CGEN_INSN *
10e05405
MM
576cgen_lookup_get_insn_operands (CGEN_CPU_DESC cd,
577 const CGEN_INSN *insn,
578 CGEN_INSN_INT insn_int_value,
579 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
580 unsigned char *insn_bytes_value,
581 int length,
582 int *indices,
583 CGEN_FIELDS *fields)
252b5132
RH
584{
585 /* Pass non-zero for ALIAS_P only if INSN != NULL.
586 If INSN == NULL, we want a real insn. */
587 insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
588 length, fields, insn != NULL);
589 if (! insn)
590 return NULL;
591
592 cgen_get_insn_operands (cd, insn, fields, indices);
593 return insn;
594}
fa7928ca
NC
595
596/* Allow signed overflow of instruction fields. */
597void
10e05405 598cgen_set_signed_overflow_ok (CGEN_CPU_DESC cd)
fa7928ca
NC
599{
600 cd->signed_overflow_ok_p = 1;
601}
602
603/* Generate an error message if a signed field in an instruction overflows. */
604void
10e05405 605cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd)
fa7928ca
NC
606{
607 cd->signed_overflow_ok_p = 0;
608}
609
610/* Will an error message be generated if a signed field in an instruction overflows ? */
611unsigned int
10e05405 612cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd)
fa7928ca
NC
613{
614 return cd->signed_overflow_ok_p;
615}