bfd/
[deliverable/binutils-gdb.git] / opcodes / cgen-opc.c
1 /* CGEN generic opcode support.
2
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005, 2007, 2009
4 Free Software Foundation, Inc.
5
6 This file is part of libopcodes.
7
8 This library 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 3, or (at your option)
11 any later version.
12
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.
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 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21
22 #include "alloca-conf.h"
23 #include "sysdep.h"
24 #include <stdio.h>
25 #include "ansidecl.h"
26 #include "libiberty.h"
27 #include "safe-ctype.h"
28 #include "bfd.h"
29 #include "symcat.h"
30 #include "opcode/cgen.h"
31
32 static unsigned int hash_keyword_name
33 (const CGEN_KEYWORD *, const char *, int);
34 static unsigned int hash_keyword_value
35 (const CGEN_KEYWORD *, unsigned int);
36 static void build_keyword_hash_tables
37 (CGEN_KEYWORD *);
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
45 const CGEN_KEYWORD_ENTRY *
46 cgen_keyword_lookup_name (CGEN_KEYWORD *kt, const char *name)
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
67 || (ISALPHA (*p) && (TOLOWER (*p) == TOLOWER (*n)))))
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
84 const CGEN_KEYWORD_ENTRY *
85 cgen_keyword_lookup_value (CGEN_KEYWORD *kt, int value)
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
106 void
107 cgen_keyword_add (CGEN_KEYWORD *kt, CGEN_KEYWORD_ENTRY *ke)
108 {
109 unsigned int hash;
110 size_t i;
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;
125
126 for (i = 1; i < strlen (ke->name); i++)
127 if (! ISALNUM (ke->name[i])
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 }
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
152 CGEN_KEYWORD_SEARCH
153 cgen_keyword_search_init (CGEN_KEYWORD *kt, const char *spec)
154 {
155 CGEN_KEYWORD_SEARCH search;
156
157 /* FIXME: Need to specify format of params. */
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
174 const CGEN_KEYWORD_ENTRY *
175 cgen_keyword_search_next (CGEN_KEYWORD_SEARCH *search)
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
208 static unsigned int
209 hash_keyword_name (const CGEN_KEYWORD *kt,
210 const char *name,
211 int case_sensitive_p)
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)
220 hash = (hash * 97) + (unsigned char) TOLOWER (*name);
221 return hash % kt->hash_table_size;
222 }
223
224 /* Return first entry in hash chain for VALUE. */
225
226 static unsigned int
227 hash_keyword_value (const CGEN_KEYWORD *kt, 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
236 static void
237 build_keyword_hash_tables (CGEN_KEYWORD *kt)
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
264 const CGEN_HW_ENTRY *
265 cgen_hw_lookup_by_name (CGEN_CPU_DESC cd, const char *name)
266 {
267 unsigned int i;
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
282 const CGEN_HW_ENTRY *
283 cgen_hw_lookup_by_num (CGEN_CPU_DESC cd, unsigned int hwnum)
284 {
285 unsigned int i;
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
302 const CGEN_OPERAND *
303 cgen_operand_lookup_by_name (CGEN_CPU_DESC cd, const char *name)
304 {
305 unsigned int i;
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
321 const CGEN_OPERAND *
322 cgen_operand_lookup_by_num (CGEN_CPU_DESC cd, int opnum)
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
331 int
332 cgen_insn_count (CGEN_CPU_DESC cd)
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
346 int
347 cgen_macro_insn_count (CGEN_CPU_DESC cd)
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
360 CGEN_INSN_INT
361 cgen_get_insn_value (CGEN_CPU_DESC cd, unsigned char *buf, int length)
362 {
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 {
379 int index;
380 bfd_vma this_value;
381 index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
382 this_value = bfd_get_bits (& buf[index / 8], insn_chunk_bitsize, big_p);
383 value = (value << insn_chunk_bitsize) | this_value;
384 }
385 }
386 else
387 {
388 value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
389 }
390
391 return value;
392 }
393
394 /* Cover function to store an insn value properly byteswapped. */
395
396 void
397 cgen_put_insn_value (CGEN_CPU_DESC cd,
398 unsigned char *buf,
399 int length,
400 CGEN_INSN_INT value)
401 {
402 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
403 int insn_chunk_bitsize = cd->insn_chunk_bitsize;
404
405 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
406 {
407 /* We need to divide up the incoming value into insn_chunk_bitsize-length
408 segments, and endian-convert them, one at a time. */
409 int i;
410
411 /* Enforce divisibility. */
412 if ((length % insn_chunk_bitsize) != 0)
413 abort ();
414
415 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
416 {
417 int index;
418 index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
419 bfd_put_bits ((bfd_vma) value, & buf[index / 8], insn_chunk_bitsize, big_p);
420 value >>= insn_chunk_bitsize;
421 }
422 }
423 else
424 {
425 bfd_put_bits ((bfd_vma) value, buf, length, big_p);
426 }
427 }
428 \f
429 /* Look up instruction INSN_*_VALUE and extract its fields.
430 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
431 Otherwise INSN_BYTES_VALUE is used.
432 INSN, if non-null, is the insn table entry.
433 Otherwise INSN_*_VALUE is examined to compute it.
434 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
435 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
436 If INSN != NULL, LENGTH must be valid.
437 ALIAS_P is non-zero if alias insns are to be included in the search.
438
439 The result is a pointer to the insn table entry, or NULL if the instruction
440 wasn't recognized. */
441
442 /* ??? Will need to be revisited for VLIW architectures. */
443
444 const CGEN_INSN *
445 cgen_lookup_insn (CGEN_CPU_DESC cd,
446 const CGEN_INSN *insn,
447 CGEN_INSN_INT insn_int_value,
448 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
449 unsigned char *insn_bytes_value,
450 int length,
451 CGEN_FIELDS *fields,
452 int alias_p)
453 {
454 unsigned char *buf;
455 CGEN_INSN_INT base_insn;
456 CGEN_EXTRACT_INFO ex_info;
457 CGEN_EXTRACT_INFO *info;
458
459 if (cd->int_insn_p)
460 {
461 info = NULL;
462 buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8);
463 cgen_put_insn_value (cd, buf, length, insn_int_value);
464 base_insn = insn_int_value;
465 }
466 else
467 {
468 info = &ex_info;
469 ex_info.dis_info = NULL;
470 ex_info.insn_bytes = insn_bytes_value;
471 ex_info.valid = -1;
472 buf = insn_bytes_value;
473 base_insn = cgen_get_insn_value (cd, buf, length);
474 }
475
476 if (!insn)
477 {
478 const CGEN_INSN_LIST *insn_list;
479
480 /* The instructions are stored in hash lists.
481 Pick the first one and keep trying until we find the right one. */
482
483 insn_list = cgen_dis_lookup_insn (cd, (char *) buf, base_insn);
484 while (insn_list != NULL)
485 {
486 insn = insn_list->insn;
487
488 if (alias_p
489 /* FIXME: Ensure ALIAS attribute always has same index. */
490 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
491 {
492 /* Basic bit mask must be correct. */
493 /* ??? May wish to allow target to defer this check until the
494 extract handler. */
495 if ((base_insn & CGEN_INSN_BASE_MASK (insn))
496 == CGEN_INSN_BASE_VALUE (insn))
497 {
498 /* ??? 0 is passed for `pc' */
499 int elength = CGEN_EXTRACT_FN (cd, insn)
500 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
501 if (elength > 0)
502 {
503 /* sanity check */
504 if (length != 0 && length != elength)
505 abort ();
506 return insn;
507 }
508 }
509 }
510
511 insn_list = insn_list->next;
512 }
513 }
514 else
515 {
516 /* Sanity check: can't pass an alias insn if ! alias_p. */
517 if (! alias_p
518 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
519 abort ();
520 /* Sanity check: length must be correct. */
521 if (length != CGEN_INSN_BITSIZE (insn))
522 abort ();
523
524 /* ??? 0 is passed for `pc' */
525 length = CGEN_EXTRACT_FN (cd, insn)
526 (cd, insn, info, base_insn, fields, (bfd_vma) 0);
527 /* Sanity check: must succeed.
528 Could relax this later if it ever proves useful. */
529 if (length == 0)
530 abort ();
531 return insn;
532 }
533
534 return NULL;
535 }
536
537 /* Fill in the operand instances used by INSN whose operands are FIELDS.
538 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
539 in. */
540
541 void
542 cgen_get_insn_operands (CGEN_CPU_DESC cd,
543 const CGEN_INSN *insn,
544 const CGEN_FIELDS *fields,
545 int *indices)
546 {
547 const CGEN_OPINST *opinst;
548 int i;
549
550 if (insn->opinst == NULL)
551 abort ();
552 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
553 {
554 enum cgen_operand_type op_type = opinst->op_type;
555 if (op_type == CGEN_OPERAND_NIL)
556 indices[i] = opinst->index;
557 else
558 indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
559 }
560 }
561
562 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
563 isn't known.
564 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
565 cgen_lookup_insn unchanged.
566 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
567 Otherwise INSN_BYTES_VALUE is used.
568
569 The result is the insn table entry or NULL if the instruction wasn't
570 recognized. */
571
572 const CGEN_INSN *
573 cgen_lookup_get_insn_operands (CGEN_CPU_DESC cd,
574 const CGEN_INSN *insn,
575 CGEN_INSN_INT insn_int_value,
576 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
577 unsigned char *insn_bytes_value,
578 int length,
579 int *indices,
580 CGEN_FIELDS *fields)
581 {
582 /* Pass non-zero for ALIAS_P only if INSN != NULL.
583 If INSN == NULL, we want a real insn. */
584 insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
585 length, fields, insn != NULL);
586 if (! insn)
587 return NULL;
588
589 cgen_get_insn_operands (cd, insn, fields, indices);
590 return insn;
591 }
592
593 /* Allow signed overflow of instruction fields. */
594 void
595 cgen_set_signed_overflow_ok (CGEN_CPU_DESC cd)
596 {
597 cd->signed_overflow_ok_p = 1;
598 }
599
600 /* Generate an error message if a signed field in an instruction overflows. */
601 void
602 cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd)
603 {
604 cd->signed_overflow_ok_p = 0;
605 }
606
607 /* Will an error message be generated if a signed field in an instruction overflows ? */
608 unsigned int
609 cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd)
610 {
611 return cd->signed_overflow_ok_p;
612 }
This page took 0.049149 seconds and 5 git commands to generate.