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