x86: fold Size{16,32,64} template attributes
[external/binutils.git] / opcodes / cgen-opc.c
1 /* CGEN generic opcode support.
2
3    Copyright (C) 1996-2018 Free Software Foundation, Inc.
4
5    This file is part of libopcodes.
6
7    This library 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 3, or (at your option)
10    any later version.
11
12    It is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    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    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20
21 #include "sysdep.h"
22 #include "alloca-conf.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 static unsigned int hash_keyword_name
32   (const CGEN_KEYWORD *, const char *, int);
33 static unsigned int hash_keyword_value
34   (const CGEN_KEYWORD *, unsigned int);
35 static void build_keyword_hash_tables
36   (CGEN_KEYWORD *);
37
38 /* Return number of hash table entries to use for N elements.  */
39 #define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
40
41 /* Look up *NAMEP in the keyword table KT.
42    The result is the keyword entry or NULL if not found.  */
43
44 const CGEN_KEYWORD_ENTRY *
45 cgen_keyword_lookup_name (CGEN_KEYWORD *kt, const char *name)
46 {
47   const CGEN_KEYWORD_ENTRY *ke;
48   const char *p,*n;
49
50   if (kt->name_hash_table == NULL)
51     build_keyword_hash_tables (kt);
52
53   ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)];
54
55   /* We do case insensitive comparisons.
56      If that ever becomes a problem, add an attribute that denotes
57      "do case sensitive comparisons".  */
58
59   while (ke != NULL)
60     {
61       n = name;
62       p = ke->name;
63
64       while (*p
65              && (*p == *n
66                  || (ISALPHA (*p) && (TOLOWER (*p) == TOLOWER (*n)))))
67         ++n, ++p;
68
69       if (!*p && !*n)
70         return ke;
71
72       ke = ke->next_name;
73     }
74
75   if (kt->null_entry)
76     return kt->null_entry;
77   return NULL;
78 }
79
80 /* Look up VALUE in the keyword table KT.
81    The result is the keyword entry or NULL if not found.  */
82
83 const CGEN_KEYWORD_ENTRY *
84 cgen_keyword_lookup_value (CGEN_KEYWORD *kt, int value)
85 {
86   const CGEN_KEYWORD_ENTRY *ke;
87
88   if (kt->name_hash_table == NULL)
89     build_keyword_hash_tables (kt);
90
91   ke = kt->value_hash_table[hash_keyword_value (kt, value)];
92
93   while (ke != NULL)
94     {
95       if (value == ke->value)
96         return ke;
97       ke = ke->next_value;
98     }
99
100   return NULL;
101 }
102
103 /* Add an entry to a keyword table.  */
104
105 void
106 cgen_keyword_add (CGEN_KEYWORD *kt, CGEN_KEYWORD_ENTRY *ke)
107 {
108   unsigned int hash;
109   size_t i;
110
111   if (kt->name_hash_table == NULL)
112     build_keyword_hash_tables (kt);
113
114   hash = hash_keyword_name (kt, ke->name, 0);
115   ke->next_name = kt->name_hash_table[hash];
116   kt->name_hash_table[hash] = ke;
117
118   hash = hash_keyword_value (kt, ke->value);
119   ke->next_value = kt->value_hash_table[hash];
120   kt->value_hash_table[hash] = ke;
121
122   if (ke->name[0] == 0)
123     kt->null_entry = ke;
124
125   for (i = 1; i < strlen (ke->name); i++)
126     if (! ISALNUM (ke->name[i])
127         && ! strchr (kt->nonalpha_chars, ke->name[i]))
128       {
129         size_t idx = strlen (kt->nonalpha_chars);
130
131         /* If you hit this limit, please don't just
132            increase the size of the field, instead
133            look for a better algorithm.  */
134         if (idx >= sizeof (kt->nonalpha_chars) - 1)
135           abort ();
136         kt->nonalpha_chars[idx] = ke->name[i];
137         kt->nonalpha_chars[idx+1] = 0;
138       }
139 }
140
141 /* FIXME: Need function to return count of keywords.  */
142
143 /* Initialize a keyword table search.
144    SPEC is a specification of what to search for.
145    A value of NULL means to find every keyword.
146    Currently NULL is the only acceptable value [further specification
147    deferred].
148    The result is an opaque data item used to record the search status.
149    It is passed to each call to cgen_keyword_search_next.  */
150
151 CGEN_KEYWORD_SEARCH
152 cgen_keyword_search_init (CGEN_KEYWORD *kt, const char *spec)
153 {
154   CGEN_KEYWORD_SEARCH search;
155
156   /* FIXME: Need to specify format of params.  */
157   if (spec != NULL)
158     abort ();
159
160   if (kt->name_hash_table == NULL)
161     build_keyword_hash_tables (kt);
162
163   search.table = kt;
164   search.spec = spec;
165   search.current_hash = 0;
166   search.current_entry = NULL;
167   return search;
168 }
169
170 /* Return the next keyword specified by SEARCH.
171    The result is the next entry or NULL if there are no more.  */
172
173 const CGEN_KEYWORD_ENTRY *
174 cgen_keyword_search_next (CGEN_KEYWORD_SEARCH *search)
175 {
176   /* Has search finished?  */
177   if (search->current_hash == search->table->hash_table_size)
178     return NULL;
179
180   /* Search in progress?  */
181   if (search->current_entry != NULL
182       /* Anything left on this hash chain?  */
183       && search->current_entry->next_name != NULL)
184     {
185       search->current_entry = search->current_entry->next_name;
186       return search->current_entry;
187     }
188
189   /* Move to next hash chain [unless we haven't started yet].  */
190   if (search->current_entry != NULL)
191     ++search->current_hash;
192
193   while (search->current_hash < search->table->hash_table_size)
194     {
195       search->current_entry = search->table->name_hash_table[search->current_hash];
196       if (search->current_entry != NULL)
197         return search->current_entry;
198       ++search->current_hash;
199     }
200
201   return NULL;
202 }
203
204 /* Return first entry in hash chain for NAME.
205    If CASE_SENSITIVE_P is non-zero, return a case sensitive hash.  */
206
207 static unsigned int
208 hash_keyword_name (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
225 static unsigned int
226 hash_keyword_value (const CGEN_KEYWORD *kt, unsigned int value)
227 {
228   return value % kt->hash_table_size;
229 }
230
231 /* Build a keyword table's hash tables.
232    We probably needn't build the value hash table for the assembler when
233    we're using the disassembler, but we keep things simple.  */
234
235 static void
236 build_keyword_hash_tables (CGEN_KEYWORD *kt)
237 {
238   int i;
239   /* Use the number of compiled in entries as an estimate for the
240      typical sized table [not too many added at runtime].  */
241   unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);
242
243   kt->hash_table_size = size;
244   kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
245     xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
246   memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
247   kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
248     xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
249   memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
250
251   /* The table is scanned backwards as we want keywords appearing earlier to
252      be prefered over later ones.  */
253   for (i = kt->num_init_entries - 1; i >= 0; --i)
254     cgen_keyword_add (kt, &kt->init_entries[i]);
255 }
256 \f
257 /* Hardware support.  */
258
259 /* Lookup a hardware element by its name.
260    Returns NULL if NAME is not supported by the currently selected
261    mach/isa.  */
262
263 const CGEN_HW_ENTRY *
264 cgen_hw_lookup_by_name (CGEN_CPU_DESC cd, const char *name)
265 {
266   unsigned int i;
267   const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
268
269   for (i = 0; i < cd->hw_table.num_entries; ++i)
270     if (hw[i] && strcmp (name, hw[i]->name) == 0)
271       return hw[i];
272
273   return NULL;
274 }
275
276 /* Lookup a hardware element by its number.
277    Hardware elements are enumerated, however it may be possible to add some
278    at runtime, thus HWNUM is not an enum type but rather an int.
279    Returns NULL if HWNUM is not supported by the currently selected mach.  */
280
281 const CGEN_HW_ENTRY *
282 cgen_hw_lookup_by_num (CGEN_CPU_DESC cd, unsigned int hwnum)
283 {
284   unsigned int i;
285   const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
286
287   /* ??? This can be speeded up.  */
288   for (i = 0; i < cd->hw_table.num_entries; ++i)
289     if (hw[i] && hwnum == hw[i]->type)
290       return hw[i];
291
292   return NULL;
293 }
294 \f
295 /* Operand support.  */
296
297 /* Lookup an operand by its name.
298    Returns NULL if NAME is not supported by the currently selected
299    mach/isa.  */
300
301 const CGEN_OPERAND *
302 cgen_operand_lookup_by_name (CGEN_CPU_DESC cd, const char *name)
303 {
304   unsigned int i;
305   const CGEN_OPERAND **op = cd->operand_table.entries;
306
307   for (i = 0; i < cd->operand_table.num_entries; ++i)
308     if (op[i] && strcmp (name, op[i]->name) == 0)
309       return op[i];
310
311   return NULL;
312 }
313
314 /* Lookup an operand by its number.
315    Operands are enumerated, however it may be possible to add some
316    at runtime, thus OPNUM is not an enum type but rather an int.
317    Returns NULL if OPNUM is not supported by the currently selected
318    mach/isa.  */
319
320 const CGEN_OPERAND *
321 cgen_operand_lookup_by_num (CGEN_CPU_DESC cd, int opnum)
322 {
323   return cd->operand_table.entries[opnum];
324 }
325 \f
326 /* Instruction support.  */
327
328 /* Return number of instructions.  This includes any added at runtime.  */
329
330 int
331 cgen_insn_count (CGEN_CPU_DESC cd)
332 {
333   int count = cd->insn_table.num_init_entries;
334   CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
335
336   for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
337     ++count;
338
339   return count;
340 }
341
342 /* Return number of macro-instructions.
343    This includes any added at runtime.  */
344
345 int
346 cgen_macro_insn_count (CGEN_CPU_DESC cd)
347 {
348   int count = cd->macro_insn_table.num_init_entries;
349   CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
350
351   for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
352     ++count;
353
354   return count;
355 }
356
357 /* Cover function to read and properly byteswap an insn value.  */
358
359 CGEN_INSN_INT
360 cgen_get_insn_value (CGEN_CPU_DESC cd, unsigned char *buf, int length)
361 {
362   int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
363   int insn_chunk_bitsize = cd->insn_chunk_bitsize;
364   CGEN_INSN_INT value = 0;
365
366   if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
367     {
368       /* We need to divide up the incoming value into insn_chunk_bitsize-length
369          segments, and endian-convert them, one at a time. */
370       int i;
371
372       /* Enforce divisibility. */
373       if ((length % insn_chunk_bitsize) != 0)
374         abort ();
375
376       for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
377         {
378           int bit_index;
379           bfd_vma this_value;
380
381           bit_index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
382           this_value = bfd_get_bits (& buf[bit_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 bit_index;
418
419           bit_index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
420           bfd_put_bits ((bfd_vma) value, & buf[bit_index / 8], insn_chunk_bitsize, big_p);
421           value >>= insn_chunk_bitsize;
422         }
423     }
424   else
425     {
426       bfd_put_bits ((bfd_vma) value, buf, length, big_p);
427     }
428 }
429 \f
430 /* Look up instruction INSN_*_VALUE and extract its fields.
431    INSN_INT_VALUE is used if CGEN_INT_INSN_P.
432    Otherwise INSN_BYTES_VALUE is used.
433    INSN, if non-null, is the insn table entry.
434    Otherwise INSN_*_VALUE is examined to compute it.
435    LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
436    0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
437    If INSN != NULL, LENGTH must be valid.
438    ALIAS_P is non-zero if alias insns are to be included in the search.
439
440    The result is a pointer to the insn table entry, or NULL if the instruction
441    wasn't recognized.  */
442
443 /* ??? Will need to be revisited for VLIW architectures.  */
444
445 const CGEN_INSN *
446 cgen_lookup_insn (CGEN_CPU_DESC cd,
447                   const CGEN_INSN *insn,
448                   CGEN_INSN_INT insn_int_value,
449                   /* ??? CGEN_INSN_BYTES would be a nice type name to use here.  */
450                   unsigned char *insn_bytes_value,
451                   int length,
452                   CGEN_FIELDS *fields,
453                   int alias_p)
454 {
455   CGEN_EXTRACT_INFO ex_info;
456   CGEN_EXTRACT_INFO *info;
457
458   if (cd->int_insn_p)
459     {
460       info = NULL;
461       insn_bytes_value = (unsigned char *) xmalloc (cd->max_insn_bitsize / 8);
462       cgen_put_insn_value (cd, insn_bytes_value, length, insn_int_value);
463     }
464   else
465     {
466       info = &ex_info;
467       ex_info.dis_info = NULL;
468       ex_info.insn_bytes = insn_bytes_value;
469       ex_info.valid = -1;
470       insn_int_value = cgen_get_insn_value (cd, insn_bytes_value, length);
471     }
472
473   if (!insn)
474     {
475       const CGEN_INSN_LIST *insn_list;
476
477       /* The instructions are stored in hash lists.
478          Pick the first one and keep trying until we find the right one.  */
479
480       insn_list = cgen_dis_lookup_insn (cd, (char *) insn_bytes_value,
481                                         insn_int_value);
482       while (insn_list != NULL)
483         {
484           insn = insn_list->insn;
485
486           if (alias_p
487               /* FIXME: Ensure ALIAS attribute always has same index.  */
488               || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
489             {
490               /* Basic bit mask must be correct.  */
491               /* ??? May wish to allow target to defer this check until the
492                  extract handler.  */
493               if ((insn_int_value & CGEN_INSN_BASE_MASK (insn))
494                   == CGEN_INSN_BASE_VALUE (insn))
495                 {
496                   /* ??? 0 is passed for `pc' */
497                   int elength = CGEN_EXTRACT_FN (cd, insn)
498                     (cd, insn, info, insn_int_value, fields, (bfd_vma) 0);
499                   if (elength > 0)
500                     {
501                       /* sanity check */
502                       if (length != 0 && length != elength)
503                         abort ();
504                       break;
505                     }
506                 }
507             }
508
509           insn_list = insn_list->next;
510         }
511     }
512   else
513     {
514       /* Sanity check: can't pass an alias insn if ! alias_p.  */
515       if (! alias_p
516           && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
517         abort ();
518       /* Sanity check: length must be correct.  */
519       if (length != CGEN_INSN_BITSIZE (insn))
520         abort ();
521
522       /* ??? 0 is passed for `pc' */
523       length = CGEN_EXTRACT_FN (cd, insn)
524         (cd, insn, info, insn_int_value, fields, (bfd_vma) 0);
525       /* Sanity check: must succeed.
526          Could relax this later if it ever proves useful.  */
527       if (length == 0)
528         abort ();
529     }
530
531   if (cd->int_insn_p)
532     free (insn_bytes_value);
533
534   return insn;
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 }