OSDN Git Service

opcode/
[pf3gnuchains/pf3gnuchains4x.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 bit_index;
380           bfd_vma this_value;
381
382           bit_index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
383           this_value = bfd_get_bits (& buf[bit_index / 8], insn_chunk_bitsize, big_p);
384           value = (value << insn_chunk_bitsize) | this_value;
385         }
386     }
387   else
388     {
389       value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
390     }
391
392   return value;
393 }
394
395 /* Cover function to store an insn value properly byteswapped.  */
396
397 void
398 cgen_put_insn_value (CGEN_CPU_DESC cd,
399                      unsigned char *buf,
400                      int length,
401                      CGEN_INSN_INT value)
402 {
403   int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
404   int insn_chunk_bitsize = cd->insn_chunk_bitsize;
405
406   if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
407     {
408       /* We need to divide up the incoming value into insn_chunk_bitsize-length
409          segments, and endian-convert them, one at a time. */
410       int i;
411
412       /* Enforce divisibility. */ 
413       if ((length % insn_chunk_bitsize) != 0)
414         abort ();
415
416       for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
417         {
418           int bit_index;
419
420           bit_index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
421           bfd_put_bits ((bfd_vma) value, & buf[bit_index / 8], insn_chunk_bitsize, big_p);
422           value >>= insn_chunk_bitsize;
423         }
424     }
425   else
426     {
427       bfd_put_bits ((bfd_vma) value, buf, length, big_p);
428     }
429 }
430 \f
431 /* Look up instruction INSN_*_VALUE and extract its fields.
432    INSN_INT_VALUE is used if CGEN_INT_INSN_P.
433    Otherwise INSN_BYTES_VALUE is used.
434    INSN, if non-null, is the insn table entry.
435    Otherwise INSN_*_VALUE is examined to compute it.
436    LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
437    0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
438    If INSN != NULL, LENGTH must be valid.
439    ALIAS_P is non-zero if alias insns are to be included in the search.
440
441    The result is a pointer to the insn table entry, or NULL if the instruction
442    wasn't recognized.  */
443
444 /* ??? Will need to be revisited for VLIW architectures.  */
445
446 const CGEN_INSN *
447 cgen_lookup_insn (CGEN_CPU_DESC cd,
448                   const CGEN_INSN *insn,
449                   CGEN_INSN_INT insn_int_value,
450                   /* ??? CGEN_INSN_BYTES would be a nice type name to use here.  */
451                   unsigned char *insn_bytes_value,
452                   int length,
453                   CGEN_FIELDS *fields,
454                   int alias_p)
455 {
456   unsigned char *buf;
457   CGEN_INSN_INT base_insn;
458   CGEN_EXTRACT_INFO ex_info;
459   CGEN_EXTRACT_INFO *info;
460
461   if (cd->int_insn_p)
462     {
463       info = NULL;
464       buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8);
465       cgen_put_insn_value (cd, buf, length, insn_int_value);
466       base_insn = insn_int_value;
467     }
468   else
469     {
470       info = &ex_info;
471       ex_info.dis_info = NULL;
472       ex_info.insn_bytes = insn_bytes_value;
473       ex_info.valid = -1;
474       buf = insn_bytes_value;
475       base_insn = cgen_get_insn_value (cd, buf, length);
476     }
477
478   if (!insn)
479     {
480       const CGEN_INSN_LIST *insn_list;
481
482       /* The instructions are stored in hash lists.
483          Pick the first one and keep trying until we find the right one.  */
484
485       insn_list = cgen_dis_lookup_insn (cd, (char *) buf, base_insn);
486       while (insn_list != NULL)
487         {
488           insn = insn_list->insn;
489
490           if (alias_p
491               /* FIXME: Ensure ALIAS attribute always has same index.  */
492               || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
493             {
494               /* Basic bit mask must be correct.  */
495               /* ??? May wish to allow target to defer this check until the
496                  extract handler.  */
497               if ((base_insn & CGEN_INSN_BASE_MASK (insn))
498                   == CGEN_INSN_BASE_VALUE (insn))
499                 {
500                   /* ??? 0 is passed for `pc' */
501                   int elength = CGEN_EXTRACT_FN (cd, insn)
502                     (cd, insn, info, base_insn, fields, (bfd_vma) 0);
503                   if (elength > 0)
504                     {
505                       /* sanity check */
506                       if (length != 0 && length != elength)
507                         abort ();
508                       return insn;
509                     }
510                 }
511             }
512
513           insn_list = insn_list->next;
514         }
515     }
516   else
517     {
518       /* Sanity check: can't pass an alias insn if ! alias_p.  */
519       if (! alias_p
520           && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
521         abort ();
522       /* Sanity check: length must be correct.  */
523       if (length != CGEN_INSN_BITSIZE (insn))
524         abort ();
525
526       /* ??? 0 is passed for `pc' */
527       length = CGEN_EXTRACT_FN (cd, insn)
528         (cd, insn, info, base_insn, fields, (bfd_vma) 0);
529       /* Sanity check: must succeed.
530          Could relax this later if it ever proves useful.  */
531       if (length == 0)
532         abort ();
533       return insn;
534     }
535
536   return NULL;
537 }
538
539 /* Fill in the operand instances used by INSN whose operands are FIELDS.
540    INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
541    in.  */
542
543 void
544 cgen_get_insn_operands (CGEN_CPU_DESC cd,
545                         const CGEN_INSN *insn,
546                         const CGEN_FIELDS *fields,
547                         int *indices)
548 {
549   const CGEN_OPINST *opinst;
550   int i;
551
552   if (insn->opinst == NULL)
553     abort ();
554   for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
555     {
556       enum cgen_operand_type op_type = opinst->op_type;
557       if (op_type == CGEN_OPERAND_NIL)
558         indices[i] = opinst->index;
559       else
560         indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
561     }
562 }
563
564 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
565    isn't known.
566    The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
567    cgen_lookup_insn unchanged.
568    INSN_INT_VALUE is used if CGEN_INT_INSN_P.
569    Otherwise INSN_BYTES_VALUE is used.
570
571    The result is the insn table entry or NULL if the instruction wasn't
572    recognized.  */
573
574 const CGEN_INSN *
575 cgen_lookup_get_insn_operands (CGEN_CPU_DESC cd,
576                                const CGEN_INSN *insn,
577                                CGEN_INSN_INT insn_int_value,
578                                /* ??? CGEN_INSN_BYTES would be a nice type name to use here.  */
579                                unsigned char *insn_bytes_value,
580                                int length,
581                                int *indices,
582                                CGEN_FIELDS *fields)
583 {
584   /* Pass non-zero for ALIAS_P only if INSN != NULL.
585      If INSN == NULL, we want a real insn.  */
586   insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
587                            length, fields, insn != NULL);
588   if (! insn)
589     return NULL;
590
591   cgen_get_insn_operands (cd, insn, fields, indices);
592   return insn;
593 }
594
595 /* Allow signed overflow of instruction fields.  */
596 void
597 cgen_set_signed_overflow_ok (CGEN_CPU_DESC cd)
598 {
599   cd->signed_overflow_ok_p = 1;
600 }
601
602 /* Generate an error message if a signed field in an instruction overflows.  */
603 void
604 cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd)
605 {
606   cd->signed_overflow_ok_p = 0;
607 }
608
609 /* Will an error message be generated if a signed field in an instruction overflows ? */
610 unsigned int
611 cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd)
612 {
613   return cd->signed_overflow_ok_p;
614 }