2001-06-14 Michael Snyder <msnyder@redhat.com>
[deliverable/binutils-gdb.git] / opcodes / cgen-opc.c
CommitLineData
252b5132
RH
1/* CGEN generic opcode support.
2
060d22b0
NC
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001
4 Free Software Foundation, Inc.
252b5132
RH
5
6 This file is part of the GNU Binutils and GDB, the GNU debugger.
7
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.
12
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.
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.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
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"
30
a6cff3e3
NC
31#ifdef HAVE_ALLOCA_H
32#include <alloca.h>
33#endif
34
252b5132
RH
35static unsigned int hash_keyword_name
36 PARAMS ((const CGEN_KEYWORD *, const char *, int));
37static unsigned int hash_keyword_value
38 PARAMS ((const CGEN_KEYWORD *, unsigned int));
39static void build_keyword_hash_tables
40 PARAMS ((CGEN_KEYWORD *));
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 *
49cgen_keyword_lookup_name (kt, name)
50 CGEN_KEYWORD *kt;
51 const char *name;
52{
53 const CGEN_KEYWORD_ENTRY *ke;
54 const char *p,*n;
55
56 if (kt->name_hash_table == NULL)
57 build_keyword_hash_tables (kt);
58
59 ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)];
60
61 /* We do case insensitive comparisons.
62 If that ever becomes a problem, add an attribute that denotes
63 "do case sensitive comparisons". */
64
65 while (ke != NULL)
66 {
67 n = name;
68 p = ke->name;
69
70 while (*p
71 && (*p == *n
72 || (isalpha ((unsigned char) *p)
73 && (tolower ((unsigned char) *p)
74 == tolower ((unsigned char) *n)))))
75 ++n, ++p;
76
77 if (!*p && !*n)
78 return ke;
79
80 ke = ke->next_name;
81 }
82
83 if (kt->null_entry)
84 return kt->null_entry;
85 return NULL;
86}
87
88/* Look up VALUE in the keyword table KT.
89 The result is the keyword entry or NULL if not found. */
90
91const CGEN_KEYWORD_ENTRY *
92cgen_keyword_lookup_value (kt, value)
93 CGEN_KEYWORD *kt;
94 int value;
95{
96 const CGEN_KEYWORD_ENTRY *ke;
97
98 if (kt->name_hash_table == NULL)
99 build_keyword_hash_tables (kt);
100
101 ke = kt->value_hash_table[hash_keyword_value (kt, value)];
102
103 while (ke != NULL)
104 {
105 if (value == ke->value)
106 return ke;
107 ke = ke->next_value;
108 }
109
110 return NULL;
111}
112
113/* Add an entry to a keyword table. */
114
115void
116cgen_keyword_add (kt, ke)
117 CGEN_KEYWORD *kt;
118 CGEN_KEYWORD_ENTRY *ke;
119{
120 unsigned int hash;
121
122 if (kt->name_hash_table == NULL)
123 build_keyword_hash_tables (kt);
124
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;
128
129 hash = hash_keyword_value (kt, ke->value);
130 ke->next_value = kt->value_hash_table[hash];
131 kt->value_hash_table[hash] = ke;
132
133 if (ke->name[0] == 0)
134 kt->null_entry = ke;
135}
136
137/* FIXME: Need function to return count of keywords. */
138
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. */
146
147CGEN_KEYWORD_SEARCH
148cgen_keyword_search_init (kt, spec)
149 CGEN_KEYWORD *kt;
150 const char *spec;
151{
152 CGEN_KEYWORD_SEARCH search;
153
154 /* FIXME: Need to specify format of PARAMS. */
155 if (spec != NULL)
156 abort ();
157
158 if (kt->name_hash_table == NULL)
159 build_keyword_hash_tables (kt);
160
161 search.table = kt;
162 search.spec = spec;
163 search.current_hash = 0;
164 search.current_entry = NULL;
165 return search;
166}
167
168/* Return the next keyword specified by SEARCH.
169 The result is the next entry or NULL if there are no more. */
170
171const CGEN_KEYWORD_ENTRY *
172cgen_keyword_search_next (search)
173 CGEN_KEYWORD_SEARCH *search;
174{
175 /* Has search finished? */
176 if (search->current_hash == search->table->hash_table_size)
177 return NULL;
178
179 /* Search in progress? */
180 if (search->current_entry != NULL
181 /* Anything left on this hash chain? */
182 && search->current_entry->next_name != NULL)
183 {
184 search->current_entry = search->current_entry->next_name;
185 return search->current_entry;
186 }
187
188 /* Move to next hash chain [unless we haven't started yet]. */
189 if (search->current_entry != NULL)
190 ++search->current_hash;
191
192 while (search->current_hash < search->table->hash_table_size)
193 {
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;
198 }
199
200 return NULL;
201}
202
203/* Return first entry in hash chain for NAME.
204 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
205
206static unsigned int
207hash_keyword_name (kt, name, case_sensitive_p)
208 const CGEN_KEYWORD *kt;
209 const char *name;
210 int case_sensitive_p;
211{
212 unsigned int hash;
213
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;
221}
222
223/* Return first entry in hash chain for VALUE. */
224
225static unsigned int
226hash_keyword_value (kt, value)
227 const CGEN_KEYWORD *kt;
228 unsigned int value;
229{
230 return value % kt->hash_table_size;
231}
232
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. */
236
237static void
238build_keyword_hash_tables (kt)
239 CGEN_KEYWORD *kt;
240{
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);
245
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 *));
253
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]);
258}
259\f
260/* Hardware support. */
261
262/* Lookup a hardware element by its name.
263 Returns NULL if NAME is not supported by the currently selected
264 mach/isa. */
265
266const CGEN_HW_ENTRY *
267cgen_hw_lookup_by_name (cd, name)
268 CGEN_CPU_DESC cd;
269 const char *name;
270{
510925d3 271 unsigned int i;
252b5132
RH
272 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
273
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];
277
278 return NULL;
279}
280
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. */
285
286const CGEN_HW_ENTRY *
287cgen_hw_lookup_by_num (cd, hwnum)
288 CGEN_CPU_DESC cd;
510925d3 289 unsigned int hwnum;
252b5132 290{
510925d3 291 unsigned int i;
252b5132
RH
292 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
293
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];
298
299 return NULL;
300}
301\f
302/* Operand support. */
303
304/* Lookup an operand by its name.
305 Returns NULL if NAME is not supported by the currently selected
306 mach/isa. */
307
308const CGEN_OPERAND *
309cgen_operand_lookup_by_name (cd, name)
310 CGEN_CPU_DESC cd;
311 const char *name;
312{
510925d3 313 unsigned int i;
252b5132
RH
314 const CGEN_OPERAND **op = cd->operand_table.entries;
315
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];
319
320 return NULL;
321}
322
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. */
328
329const CGEN_OPERAND *
330cgen_operand_lookup_by_num (cd, opnum)
331 CGEN_CPU_DESC cd;
332 int opnum;
333{
334 return cd->operand_table.entries[opnum];
335}
336\f
337/* Instruction support. */
338
339/* Return number of instructions. This includes any added at runtime. */
340
341int
342cgen_insn_count (cd)
343 CGEN_CPU_DESC cd;
344{
345 int count = cd->insn_table.num_init_entries;
346 CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
347
348 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
349 ++count;
350
351 return count;
352}
353
354/* Return number of macro-instructions.
355 This includes any added at runtime. */
356
357int
358cgen_macro_insn_count (cd)
359 CGEN_CPU_DESC cd;
360{
361 int count = cd->macro_insn_table.num_init_entries;
362 CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
363
364 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
365 ++count;
366
367 return count;
368}
369
370/* Cover function to read and properly byteswap an insn value. */
371
372CGEN_INSN_INT
373cgen_get_insn_value (cd, buf, length)
374 CGEN_CPU_DESC cd;
375 unsigned char *buf;
376 int length;
377{
dd425ada 378 return bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
252b5132
RH
379}
380
381/* Cover function to store an insn value properly byteswapped. */
382
383void
384cgen_put_insn_value (cd, buf, length, value)
385 CGEN_CPU_DESC cd;
386 unsigned char *buf;
387 int length;
388 CGEN_INSN_INT value;
389{
aed80dae
FCE
390 bfd_put_bits ((bfd_vma) value, buf, length,
391 cd->insn_endian == CGEN_ENDIAN_BIG);
252b5132
RH
392}
393\f
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.
403
404 The result is a pointer to the insn table entry, or NULL if the instruction
405 wasn't recognized. */
406
407/* ??? Will need to be revisited for VLIW architectures. */
408
409const CGEN_INSN *
410cgen_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;
420{
421 unsigned char *buf;
422 CGEN_INSN_INT base_insn;
423 CGEN_EXTRACT_INFO ex_info;
424 CGEN_EXTRACT_INFO *info;
425
426 if (cd->int_insn_p)
427 {
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;
432 }
433 else
434 {
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);
441 }
442
443 if (!insn)
444 {
445 const CGEN_INSN_LIST *insn_list;
446
447 /* The instructions are stored in hash lists.
448 Pick the first one and keep trying until we find the right one. */
449
450 insn_list = cgen_dis_lookup_insn (cd, buf, base_insn);
451 while (insn_list != NULL)
452 {
453 insn = insn_list->insn;
454
455 if (alias_p
456 /* FIXME: Ensure ALIAS attribute always has same index. */
457 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
458 {
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))
464 {
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)
469 {
470 /* sanity check */
471 if (length != 0 && length != elength)
472 abort ();
473 return insn;
474 }
475 }
476 }
477
478 insn_list = insn_list->next;
479 }
480 }
481 else
482 {
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 ();
490
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;
499 }
500
501 return NULL;
502}
503
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. */
507
508void
509cgen_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;
514{
515 const CGEN_OPINST *opinst;
516 int i;
517
518 if (insn->opinst == NULL)
519 abort ();
520 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
521 {
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);
527 }
528}
529
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.
536
537 The result is the insn table entry or NULL if the instruction wasn't
538 recognized. */
539
540const CGEN_INSN *
541cgen_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;
551{
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;
558
559 cgen_get_insn_operands (cd, insn, fields, indices);
560 return insn;
561}
fa7928ca
NC
562
563/* Allow signed overflow of instruction fields. */
564void
565cgen_set_signed_overflow_ok (cd)
566 CGEN_CPU_DESC cd;
567{
568 cd->signed_overflow_ok_p = 1;
569}
570
571/* Generate an error message if a signed field in an instruction overflows. */
572void
573cgen_clear_signed_overflow_ok (cd)
574 CGEN_CPU_DESC cd;
575{
576 cd->signed_overflow_ok_p = 0;
577}
578
579/* Will an error message be generated if a signed field in an instruction overflows ? */
580unsigned int
581cgen_signed_overflow_ok_p (cd)
582 CGEN_CPU_DESC cd;
583{
584 return cd->signed_overflow_ok_p;
585}
This page took 0.099971 seconds and 4 git commands to generate.