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 *
cgen_keyword_lookup_name(CGEN_KEYWORD * kt,const char * name)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 *
cgen_keyword_lookup_value(CGEN_KEYWORD * kt,int value)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
cgen_keyword_add(CGEN_KEYWORD * kt,CGEN_KEYWORD_ENTRY * ke)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
cgen_keyword_search_init(CGEN_KEYWORD * kt,const char * spec)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 *
cgen_keyword_search_next(CGEN_KEYWORD_SEARCH * search)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
hash_keyword_name(const CGEN_KEYWORD * kt,const char * name,int case_sensitive_p)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
hash_keyword_value(const CGEN_KEYWORD * kt,unsigned int value)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
build_keyword_hash_tables(CGEN_KEYWORD * kt)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 
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 *
cgen_hw_lookup_by_name(CGEN_CPU_DESC cd,const char * name)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 *
cgen_hw_lookup_by_num(CGEN_CPU_DESC cd,unsigned int hwnum)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 
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 *
cgen_operand_lookup_by_name(CGEN_CPU_DESC cd,const char * name)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 *
cgen_operand_lookup_by_num(CGEN_CPU_DESC cd,int opnum)325 cgen_operand_lookup_by_num (CGEN_CPU_DESC cd, int opnum)
326 {
327   return cd->operand_table.entries[opnum];
328 }
329 
330 /* Instruction support.  */
331 
332 /* Return number of instructions.  This includes any added at runtime.  */
333 
334 int
cgen_insn_count(CGEN_CPU_DESC cd)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
cgen_macro_insn_count(CGEN_CPU_DESC cd)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
cgen_get_insn_value(CGEN_CPU_DESC cd,unsigned char * buf,int length)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
cgen_put_insn_value(CGEN_CPU_DESC cd,unsigned char * buf,int length,CGEN_INSN_INT value)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 
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 *
cgen_lookup_insn(CGEN_CPU_DESC cd,const CGEN_INSN * insn,CGEN_INSN_INT insn_int_value,unsigned char * insn_bytes_value,int length,CGEN_FIELDS * fields,int alias_p)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
cgen_get_insn_operands(CGEN_CPU_DESC cd,const CGEN_INSN * insn,const CGEN_FIELDS * fields,int * indices)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 *
cgen_lookup_get_insn_operands(CGEN_CPU_DESC cd,const CGEN_INSN * insn,CGEN_INSN_INT insn_int_value,unsigned char * insn_bytes_value,int length,int * indices,CGEN_FIELDS * fields)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
cgen_set_signed_overflow_ok(CGEN_CPU_DESC cd)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
cgen_clear_signed_overflow_ok(CGEN_CPU_DESC cd)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
cgen_signed_overflow_ok_p(CGEN_CPU_DESC cd)612 cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd)
613 {
614   return cd->signed_overflow_ok_p;
615 }
616