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