ede3adde1153146e1c7398e237bd593d20159cf6
[external/binutils.git] / opcodes / cgen-opc.c
1 /* CGEN generic opcode support.
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
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
30 static unsigned int hash_keyword_name
31   PARAMS ((const CGEN_KEYWORD *, const char *, int));
32 static unsigned int hash_keyword_value
33   PARAMS ((const CGEN_KEYWORD *, unsigned int));
34 static void build_keyword_hash_tables
35   PARAMS ((CGEN_KEYWORD *));
36
37 /* Return number of hash table entries to use for N elements.  */
38 #define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
39
40 /* Look up *NAMEP in the keyword table KT.
41    The result is the keyword entry or NULL if not found.  */
42
43 const CGEN_KEYWORD_ENTRY *
44 cgen_keyword_lookup_name (kt, name)
45      CGEN_KEYWORD *kt;
46      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 ((unsigned char) *p)
68                      && (tolower ((unsigned char) *p)
69                          == tolower ((unsigned char) *n)))))
70         ++n, ++p;
71
72       if (!*p && !*n)
73         return ke;
74
75       ke = ke->next_name;
76     }
77
78   if (kt->null_entry)
79     return kt->null_entry;
80   return NULL;
81 }
82
83 /* Look up VALUE in the keyword table KT.
84    The result is the keyword entry or NULL if not found.  */
85
86 const CGEN_KEYWORD_ENTRY *
87 cgen_keyword_lookup_value (kt, value)
88      CGEN_KEYWORD *kt;
89      int value;
90 {
91   const CGEN_KEYWORD_ENTRY *ke;
92
93   if (kt->name_hash_table == NULL)
94     build_keyword_hash_tables (kt);
95
96   ke = kt->value_hash_table[hash_keyword_value (kt, value)];
97
98   while (ke != NULL)
99     {
100       if (value == ke->value)
101         return ke;
102       ke = ke->next_value;
103     }
104
105   return NULL;
106 }
107
108 /* Add an entry to a keyword table.  */
109
110 void
111 cgen_keyword_add (kt, ke)
112      CGEN_KEYWORD *kt;
113      CGEN_KEYWORD_ENTRY *ke;
114 {
115   unsigned int hash;
116
117   if (kt->name_hash_table == NULL)
118     build_keyword_hash_tables (kt);
119
120   hash = hash_keyword_name (kt, ke->name, 0);
121   ke->next_name = kt->name_hash_table[hash];
122   kt->name_hash_table[hash] = ke;
123
124   hash = hash_keyword_value (kt, ke->value);
125   ke->next_value = kt->value_hash_table[hash];
126   kt->value_hash_table[hash] = ke;
127
128   if (ke->name[0] == 0)
129     kt->null_entry = ke;
130 }
131
132 /* FIXME: Need function to return count of keywords.  */
133
134 /* Initialize a keyword table search.
135    SPEC is a specification of what to search for.
136    A value of NULL means to find every keyword.
137    Currently NULL is the only acceptable value [further specification
138    deferred].
139    The result is an opaque data item used to record the search status.
140    It is passed to each call to cgen_keyword_search_next.  */
141
142 CGEN_KEYWORD_SEARCH
143 cgen_keyword_search_init (kt, spec)
144      CGEN_KEYWORD *kt;
145      const char *spec;
146 {
147   CGEN_KEYWORD_SEARCH search;
148
149   /* FIXME: Need to specify format of PARAMS.  */
150   if (spec != NULL)
151     abort ();
152
153   if (kt->name_hash_table == NULL)
154     build_keyword_hash_tables (kt);
155
156   search.table = kt;
157   search.spec = spec;
158   search.current_hash = 0;
159   search.current_entry = NULL;
160   return search;
161 }
162
163 /* Return the next keyword specified by SEARCH.
164    The result is the next entry or NULL if there are no more.  */
165
166 const CGEN_KEYWORD_ENTRY *
167 cgen_keyword_search_next (search)
168      CGEN_KEYWORD_SEARCH *search;
169 {
170   /* Has search finished?  */
171   if (search->current_hash == search->table->hash_table_size)
172     return NULL;
173
174   /* Search in progress?  */
175   if (search->current_entry != NULL
176       /* Anything left on this hash chain?  */
177       && search->current_entry->next_name != NULL)
178     {
179       search->current_entry = search->current_entry->next_name;
180       return search->current_entry;
181     }
182
183   /* Move to next hash chain [unless we haven't started yet].  */
184   if (search->current_entry != NULL)
185     ++search->current_hash;
186
187   while (search->current_hash < search->table->hash_table_size)
188     {
189       search->current_entry = search->table->name_hash_table[search->current_hash];
190       if (search->current_entry != NULL)
191         return search->current_entry;
192       ++search->current_hash;
193     }
194
195   return NULL;
196 }
197
198 /* Return first entry in hash chain for NAME.
199    If CASE_SENSITIVE_P is non-zero, return a case sensitive hash.  */
200
201 static unsigned int
202 hash_keyword_name (kt, name, case_sensitive_p)
203      const CGEN_KEYWORD *kt;
204      const char *name;
205      int case_sensitive_p;
206 {
207   unsigned int hash;
208
209   if (case_sensitive_p)
210     for (hash = 0; *name; ++name)
211       hash = (hash * 97) + (unsigned char) *name;
212   else
213     for (hash = 0; *name; ++name)
214       hash = (hash * 97) + (unsigned char) tolower (*name);
215   return hash % kt->hash_table_size;
216 }
217
218 /* Return first entry in hash chain for VALUE.  */
219
220 static unsigned int
221 hash_keyword_value (kt, value)
222      const CGEN_KEYWORD *kt;
223      unsigned int value;
224 {
225   return value % kt->hash_table_size;
226 }
227
228 /* Build a keyword table's hash tables.
229    We probably needn't build the value hash table for the assembler when
230    we're using the disassembler, but we keep things simple.  */
231
232 static void
233 build_keyword_hash_tables (kt)
234      CGEN_KEYWORD *kt;
235 {
236   int i;
237   /* Use the number of compiled in entries as an estimate for the
238      typical sized table [not too many added at runtime].  */
239   unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);
240
241   kt->hash_table_size = size;
242   kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
243     xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
244   memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
245   kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
246     xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
247   memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
248
249   /* The table is scanned backwards as we want keywords appearing earlier to
250      be prefered over later ones.  */
251   for (i = kt->num_init_entries - 1; i >= 0; --i)
252     cgen_keyword_add (kt, &kt->init_entries[i]);
253 }
254 \f
255 /* Hardware support.  */
256
257 /* Lookup a hardware element by its name.
258    Returns NULL if NAME is not supported by the currently selected
259    mach/isa.  */
260
261 const CGEN_HW_ENTRY *
262 cgen_hw_lookup_by_name (cd, name)
263      CGEN_CPU_DESC cd;
264      const char *name;
265 {
266   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 (cd, hwnum)
283      CGEN_CPU_DESC cd;
284      int hwnum;
285 {
286   int i;
287   const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
288
289   /* ??? This can be speeded up.  */
290   for (i = 0; i < cd->hw_table.num_entries; ++i)
291     if (hw[i] && hwnum == hw[i]->type)
292       return hw[i];
293
294   return NULL;
295 }
296 \f
297 /* Operand support.  */
298
299 /* Lookup an operand by its name.
300    Returns NULL if NAME is not supported by the currently selected
301    mach/isa.  */
302
303 const CGEN_OPERAND *
304 cgen_operand_lookup_by_name (cd, name)
305      CGEN_CPU_DESC cd;
306      const char *name;
307 {
308   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 (cd, opnum)
326      CGEN_CPU_DESC cd;
327      int opnum;
328 {
329   return cd->operand_table.entries[opnum];
330 }
331 \f
332 /* Instruction support.  */
333
334 /* Return number of instructions.  This includes any added at runtime.  */
335
336 int
337 cgen_insn_count (cd)
338      CGEN_CPU_DESC cd;
339 {
340   int count = cd->insn_table.num_init_entries;
341   CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
342
343   for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
344     ++count;
345
346   return count;
347 }
348
349 /* Return number of macro-instructions.
350    This includes any added at runtime.  */
351
352 int
353 cgen_macro_insn_count (cd)
354      CGEN_CPU_DESC cd;
355 {
356   int count = cd->macro_insn_table.num_init_entries;
357   CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
358
359   for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
360     ++count;
361
362   return count;
363 }
364
365 /* Cover function to read and properly byteswap an insn value.  */
366
367 CGEN_INSN_INT
368 cgen_get_insn_value (cd, buf, length)
369      CGEN_CPU_DESC cd;
370      unsigned char *buf;
371      int length;
372 {
373   CGEN_INSN_INT value;
374
375   switch (length)
376     {
377     case 8:
378       value = *buf;
379       break;
380     case 16:
381       if (cd->insn_endian == CGEN_ENDIAN_BIG)
382         value = bfd_getb16 (buf);
383       else
384         value = bfd_getl16 (buf);
385       break;
386     case 32:
387       if (cd->insn_endian == CGEN_ENDIAN_BIG)
388         value = bfd_getb32 (buf);
389       else
390         value = bfd_getl32 (buf);
391       break;
392     default:
393       abort ();
394     }
395
396   return value;
397 }
398
399 /* Cover function to store an insn value properly byteswapped.  */
400
401 void
402 cgen_put_insn_value (cd, buf, length, value)
403      CGEN_CPU_DESC cd;
404      unsigned char *buf;
405      int length;
406      CGEN_INSN_INT value;
407 {
408   switch (length)
409     {
410     case 8:
411       buf[0] = value;
412       break;
413     case 16:
414       if (cd->insn_endian == CGEN_ENDIAN_BIG)
415         bfd_putb16 (value, buf);
416       else
417         bfd_putl16 (value, buf);
418       break;
419     case 32:
420       if (cd->insn_endian == CGEN_ENDIAN_BIG)
421         bfd_putb32 (value, buf);
422       else
423         bfd_putl32 (value, buf);
424       break;
425     default:
426       abort ();
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 (cd, insn, insn_int_value, insn_bytes_value, length, fields,
447                   alias_p)
448      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, 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 (cd, insn, fields, indices)
546      CGEN_CPU_DESC cd;
547      const CGEN_INSN *insn;
548      const CGEN_FIELDS *fields;
549      int *indices;
550 {
551   const CGEN_OPINST *opinst;
552   int i;
553
554   if (insn->opinst == NULL)
555     abort ();
556   for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
557     {
558       enum cgen_operand_type op_type = opinst->op_type;
559       if (op_type == CGEN_OPERAND_NIL)
560         indices[i] = opinst->index;
561       else
562         indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
563     }
564 }
565
566 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
567    isn't known.
568    The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
569    cgen_lookup_insn unchanged.
570    INSN_INT_VALUE is used if CGEN_INT_INSN_P.
571    Otherwise INSN_BYTES_VALUE is used.
572
573    The result is the insn table entry or NULL if the instruction wasn't
574    recognized.  */
575
576 const CGEN_INSN *
577 cgen_lookup_get_insn_operands (cd, insn, insn_int_value, insn_bytes_value,
578                                length, indices, fields)
579      CGEN_CPU_DESC cd;
580      const CGEN_INSN *insn;
581      CGEN_INSN_INT insn_int_value;
582      /* ??? CGEN_INSN_BYTES would be a nice type name to use here.  */
583      unsigned char *insn_bytes_value;
584      int length;
585      int *indices;
586      CGEN_FIELDS *fields;
587 {
588   /* Pass non-zero for ALIAS_P only if INSN != NULL.
589      If INSN == NULL, we want a real insn.  */
590   insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
591                            length, fields, insn != NULL);
592   if (! insn)
593     return NULL;
594
595   cgen_get_insn_operands (cd, insn, fields, indices);
596   return insn;
597 }
598
599 /* Allow signed overflow of instruction fields.  */
600 void
601 cgen_set_signed_overflow_ok (cd)
602      CGEN_CPU_DESC cd;
603 {
604   cd->signed_overflow_ok_p = 1;
605 }
606
607 /* Generate an error message if a signed field in an instruction overflows.  */
608 void
609 cgen_clear_signed_overflow_ok (cd)
610      CGEN_CPU_DESC cd;
611 {
612   cd->signed_overflow_ok_p = 0;
613 }
614
615 /* Will an error message be generated if a signed field in an instruction overflows ? */
616 unsigned int
617 cgen_signed_overflow_ok_p (cd)
618      CGEN_CPU_DESC cd;
619 {
620   return cd->signed_overflow_ok_p;
621 }