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