OSDN Git Service

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