daily update
[deliverable/binutils-gdb.git] / opcodes / cgen-opc.c
1 /* CGEN generic opcode support.
2
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001
4 Free Software Foundation, Inc.
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 <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"
30
31 #ifdef HAVE_ALLOCA_H
32 #include <alloca.h>
33 #endif
34
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 *));
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
48 const CGEN_KEYWORD_ENTRY *
49 cgen_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 (*p) && (TOLOWER (*p) == TOLOWER (*n)))))
73 ++n, ++p;
74
75 if (!*p && !*n)
76 return ke;
77
78 ke = ke->next_name;
79 }
80
81 if (kt->null_entry)
82 return kt->null_entry;
83 return NULL;
84 }
85
86 /* Look up VALUE in the keyword table KT.
87 The result is the keyword entry or NULL if not found. */
88
89 const CGEN_KEYWORD_ENTRY *
90 cgen_keyword_lookup_value (kt, value)
91 CGEN_KEYWORD *kt;
92 int value;
93 {
94 const CGEN_KEYWORD_ENTRY *ke;
95
96 if (kt->name_hash_table == NULL)
97 build_keyword_hash_tables (kt);
98
99 ke = kt->value_hash_table[hash_keyword_value (kt, value)];
100
101 while (ke != NULL)
102 {
103 if (value == ke->value)
104 return ke;
105 ke = ke->next_value;
106 }
107
108 return NULL;
109 }
110
111 /* Add an entry to a keyword table. */
112
113 void
114 cgen_keyword_add (kt, ke)
115 CGEN_KEYWORD *kt;
116 CGEN_KEYWORD_ENTRY *ke;
117 {
118 unsigned int hash;
119 size_t i;
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 for (i = 1; i < strlen (ke->name); i++)
136 if (! ISALNUM (ke->name[i])
137 && ! strchr (kt->nonalpha_chars, ke->name[i]))
138 {
139 size_t idx = strlen (kt->nonalpha_chars);
140
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;
148 }
149 }
150
151 /* FIXME: Need function to return count of keywords. */
152
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. */
160
161 CGEN_KEYWORD_SEARCH
162 cgen_keyword_search_init (kt, spec)
163 CGEN_KEYWORD *kt;
164 const char *spec;
165 {
166 CGEN_KEYWORD_SEARCH search;
167
168 /* FIXME: Need to specify format of PARAMS. */
169 if (spec != NULL)
170 abort ();
171
172 if (kt->name_hash_table == NULL)
173 build_keyword_hash_tables (kt);
174
175 search.table = kt;
176 search.spec = spec;
177 search.current_hash = 0;
178 search.current_entry = NULL;
179 return search;
180 }
181
182 /* Return the next keyword specified by SEARCH.
183 The result is the next entry or NULL if there are no more. */
184
185 const CGEN_KEYWORD_ENTRY *
186 cgen_keyword_search_next (search)
187 CGEN_KEYWORD_SEARCH *search;
188 {
189 /* Has search finished? */
190 if (search->current_hash == search->table->hash_table_size)
191 return NULL;
192
193 /* Search in progress? */
194 if (search->current_entry != NULL
195 /* Anything left on this hash chain? */
196 && search->current_entry->next_name != NULL)
197 {
198 search->current_entry = search->current_entry->next_name;
199 return search->current_entry;
200 }
201
202 /* Move to next hash chain [unless we haven't started yet]. */
203 if (search->current_entry != NULL)
204 ++search->current_hash;
205
206 while (search->current_hash < search->table->hash_table_size)
207 {
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;
212 }
213
214 return NULL;
215 }
216
217 /* Return first entry in hash chain for NAME.
218 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
219
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;
225 {
226 unsigned int hash;
227
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;
235 }
236
237 /* Return first entry in hash chain for VALUE. */
238
239 static unsigned int
240 hash_keyword_value (kt, value)
241 const CGEN_KEYWORD *kt;
242 unsigned int value;
243 {
244 return value % kt->hash_table_size;
245 }
246
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. */
250
251 static void
252 build_keyword_hash_tables (kt)
253 CGEN_KEYWORD *kt;
254 {
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);
259
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 *));
267
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]);
272 }
273 \f
274 /* Hardware support. */
275
276 /* Lookup a hardware element by its name.
277 Returns NULL if NAME is not supported by the currently selected
278 mach/isa. */
279
280 const CGEN_HW_ENTRY *
281 cgen_hw_lookup_by_name (cd, name)
282 CGEN_CPU_DESC cd;
283 const char *name;
284 {
285 unsigned int i;
286 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
287
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];
291
292 return NULL;
293 }
294
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. */
299
300 const CGEN_HW_ENTRY *
301 cgen_hw_lookup_by_num (cd, hwnum)
302 CGEN_CPU_DESC cd;
303 unsigned int hwnum;
304 {
305 unsigned int i;
306 const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
307
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];
312
313 return NULL;
314 }
315 \f
316 /* Operand support. */
317
318 /* Lookup an operand by its name.
319 Returns NULL if NAME is not supported by the currently selected
320 mach/isa. */
321
322 const CGEN_OPERAND *
323 cgen_operand_lookup_by_name (cd, name)
324 CGEN_CPU_DESC cd;
325 const char *name;
326 {
327 unsigned int i;
328 const CGEN_OPERAND **op = cd->operand_table.entries;
329
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];
333
334 return NULL;
335 }
336
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. */
342
343 const CGEN_OPERAND *
344 cgen_operand_lookup_by_num (cd, opnum)
345 CGEN_CPU_DESC cd;
346 int opnum;
347 {
348 return cd->operand_table.entries[opnum];
349 }
350 \f
351 /* Instruction support. */
352
353 /* Return number of instructions. This includes any added at runtime. */
354
355 int
356 cgen_insn_count (cd)
357 CGEN_CPU_DESC cd;
358 {
359 int count = cd->insn_table.num_init_entries;
360 CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
361
362 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
363 ++count;
364
365 return count;
366 }
367
368 /* Return number of macro-instructions.
369 This includes any added at runtime. */
370
371 int
372 cgen_macro_insn_count (cd)
373 CGEN_CPU_DESC cd;
374 {
375 int count = cd->macro_insn_table.num_init_entries;
376 CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
377
378 for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
379 ++count;
380
381 return count;
382 }
383
384 /* Cover function to read and properly byteswap an insn value. */
385
386 CGEN_INSN_INT
387 cgen_get_insn_value (cd, buf, length)
388 CGEN_CPU_DESC cd;
389 unsigned char *buf;
390 int length;
391 {
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;
395
396 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
397 {
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;
401
402 /* Enforce divisibility. */
403 if ((length % insn_chunk_bitsize) != 0)
404 abort ();
405
406 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
407 {
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;
413 }
414 }
415 else
416 {
417 value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
418 }
419
420 return value;
421 }
422
423 /* Cover function to store an insn value properly byteswapped. */
424
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;
431 {
432 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
433 int insn_chunk_bitsize = cd->insn_chunk_bitsize;
434
435 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
436 {
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;
440
441 /* Enforce divisibility. */
442 if ((length % insn_chunk_bitsize) != 0)
443 abort ();
444
445 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
446 {
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;
451 }
452 }
453 else
454 {
455 bfd_put_bits ((bfd_vma) value, buf, length, big_p);
456 }
457 }
458 \f
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.
468
469 The result is a pointer to the insn table entry, or NULL if the instruction
470 wasn't recognized. */
471
472 /* ??? Will need to be revisited for VLIW architectures. */
473
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;
485 {
486 unsigned char *buf;
487 CGEN_INSN_INT base_insn;
488 CGEN_EXTRACT_INFO ex_info;
489 CGEN_EXTRACT_INFO *info;
490
491 if (cd->int_insn_p)
492 {
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;
497 }
498 else
499 {
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);
506 }
507
508 if (!insn)
509 {
510 const CGEN_INSN_LIST *insn_list;
511
512 /* The instructions are stored in hash lists.
513 Pick the first one and keep trying until we find the right one. */
514
515 insn_list = cgen_dis_lookup_insn (cd, buf, base_insn);
516 while (insn_list != NULL)
517 {
518 insn = insn_list->insn;
519
520 if (alias_p
521 /* FIXME: Ensure ALIAS attribute always has same index. */
522 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
523 {
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))
529 {
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)
534 {
535 /* sanity check */
536 if (length != 0 && length != elength)
537 abort ();
538 return insn;
539 }
540 }
541 }
542
543 insn_list = insn_list->next;
544 }
545 }
546 else
547 {
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 ();
555
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;
564 }
565
566 return NULL;
567 }
568
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. */
572
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;
579 {
580 const CGEN_OPINST *opinst;
581 int i;
582
583 if (insn->opinst == NULL)
584 abort ();
585 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
586 {
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);
592 }
593 }
594
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.
601
602 The result is the insn table entry or NULL if the instruction wasn't
603 recognized. */
604
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;
616 {
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;
623
624 cgen_get_insn_operands (cd, insn, fields, indices);
625 return insn;
626 }
627
628 /* Allow signed overflow of instruction fields. */
629 void
630 cgen_set_signed_overflow_ok (cd)
631 CGEN_CPU_DESC cd;
632 {
633 cd->signed_overflow_ok_p = 1;
634 }
635
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;
640 {
641 cd->signed_overflow_ok_p = 0;
642 }
643
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;
648 {
649 return cd->signed_overflow_ok_p;
650 }
This page took 0.051318 seconds and 4 git commands to generate.