Home | History | Annotate | Download | only in opcodes
      1 /* CGEN generic opcode support.
      2 
      3    Copyright (C) 1996-2016 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 
    257 /* 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 
    296 /* 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 (CGEN_CPU_DESC cd, const char *name)
    305 {
    306   unsigned int i;
    307   const CGEN_OPERAND **op = cd->operand_table.entries;
    308 
    309   for (i = 0; i < cd->operand_table.num_entries; ++i)
    310     if (op[i] && strcmp (name, op[i]->name) == 0)
    311       return op[i];
    312 
    313   return NULL;
    314 }
    315 
    316 /* Lookup an operand by its number.
    317    Operands are enumerated, however it may be possible to add some
    318    at runtime, thus OPNUM is not an enum type but rather an int.
    319    Returns NULL if OPNUM is not supported by the currently selected
    320    mach/isa.  */
    321 
    322 const CGEN_OPERAND *
    323 cgen_operand_lookup_by_num (CGEN_CPU_DESC cd, int opnum)
    324 {
    325   return cd->operand_table.entries[opnum];
    326 }
    327 
    328 /* Instruction support.  */
    330 
    331 /* Return number of instructions.  This includes any added at runtime.  */
    332 
    333 int
    334 cgen_insn_count (CGEN_CPU_DESC cd)
    335 {
    336   int count = cd->insn_table.num_init_entries;
    337   CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
    338 
    339   for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
    340     ++count;
    341 
    342   return count;
    343 }
    344 
    345 /* Return number of macro-instructions.
    346    This includes any added at runtime.  */
    347 
    348 int
    349 cgen_macro_insn_count (CGEN_CPU_DESC cd)
    350 {
    351   int count = cd->macro_insn_table.num_init_entries;
    352   CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
    353 
    354   for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
    355     ++count;
    356 
    357   return count;
    358 }
    359 
    360 /* Cover function to read and properly byteswap an insn value.  */
    361 
    362 CGEN_INSN_INT
    363 cgen_get_insn_value (CGEN_CPU_DESC cd, unsigned char *buf, int length)
    364 {
    365   int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
    366   int insn_chunk_bitsize = cd->insn_chunk_bitsize;
    367   CGEN_INSN_INT value = 0;
    368 
    369   if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
    370     {
    371       /* We need to divide up the incoming value into insn_chunk_bitsize-length
    372 	 segments, and endian-convert them, one at a time. */
    373       int i;
    374 
    375       /* Enforce divisibility. */
    376       if ((length % insn_chunk_bitsize) != 0)
    377 	abort ();
    378 
    379       for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
    380 	{
    381 	  int bit_index;
    382 	  bfd_vma this_value;
    383 
    384 	  bit_index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
    385 	  this_value = bfd_get_bits (& buf[bit_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
    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 bit_index;
    421 
    422 	  bit_index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
    423 	  bfd_put_bits ((bfd_vma) value, & buf[bit_index / 8], insn_chunk_bitsize, big_p);
    424 	  value >>= insn_chunk_bitsize;
    425 	}
    426     }
    427   else
    428     {
    429       bfd_put_bits ((bfd_vma) value, buf, length, big_p);
    430     }
    431 }
    432 
    433 /* Look up instruction INSN_*_VALUE and extract its fields.
    435    INSN_INT_VALUE is used if CGEN_INT_INSN_P.
    436    Otherwise INSN_BYTES_VALUE is used.
    437    INSN, if non-null, is the insn table entry.
    438    Otherwise INSN_*_VALUE is examined to compute it.
    439    LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
    440    0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
    441    If INSN != NULL, LENGTH must be valid.
    442    ALIAS_P is non-zero if alias insns are to be included in the search.
    443 
    444    The result is a pointer to the insn table entry, or NULL if the instruction
    445    wasn't recognized.  */
    446 
    447 /* ??? Will need to be revisited for VLIW architectures.  */
    448 
    449 const CGEN_INSN *
    450 cgen_lookup_insn (CGEN_CPU_DESC cd,
    451 		  const CGEN_INSN *insn,
    452 		  CGEN_INSN_INT insn_int_value,
    453 		  /* ??? CGEN_INSN_BYTES would be a nice type name to use here.  */
    454 		  unsigned char *insn_bytes_value,
    455 		  int length,
    456 		  CGEN_FIELDS *fields,
    457 		  int alias_p)
    458 {
    459   unsigned char *buf;
    460   CGEN_INSN_INT base_insn;
    461   CGEN_EXTRACT_INFO ex_info;
    462   CGEN_EXTRACT_INFO *info;
    463 
    464   if (cd->int_insn_p)
    465     {
    466       info = NULL;
    467       buf = (unsigned char *) xmalloc (cd->max_insn_bitsize / 8);
    468       cgen_put_insn_value (cd, buf, length, insn_int_value);
    469       base_insn = insn_int_value;
    470       free (buf);
    471     }
    472   else
    473     {
    474       info = &ex_info;
    475       ex_info.dis_info = NULL;
    476       ex_info.insn_bytes = insn_bytes_value;
    477       ex_info.valid = -1;
    478       buf = insn_bytes_value;
    479       base_insn = cgen_get_insn_value (cd, buf, length);
    480     }
    481 
    482   if (!insn)
    483     {
    484       const CGEN_INSN_LIST *insn_list;
    485 
    486       /* The instructions are stored in hash lists.
    487 	 Pick the first one and keep trying until we find the right one.  */
    488 
    489       insn_list = cgen_dis_lookup_insn (cd, (char *) buf, base_insn);
    490       while (insn_list != NULL)
    491 	{
    492 	  insn = insn_list->insn;
    493 
    494 	  if (alias_p
    495 	      /* FIXME: Ensure ALIAS attribute always has same index.  */
    496 	      || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
    497 	    {
    498 	      /* Basic bit mask must be correct.  */
    499 	      /* ??? May wish to allow target to defer this check until the
    500 		 extract handler.  */
    501 	      if ((base_insn & CGEN_INSN_BASE_MASK (insn))
    502 		  == CGEN_INSN_BASE_VALUE (insn))
    503 		{
    504 		  /* ??? 0 is passed for `pc' */
    505 		  int elength = CGEN_EXTRACT_FN (cd, insn)
    506 		    (cd, insn, info, base_insn, fields, (bfd_vma) 0);
    507 		  if (elength > 0)
    508 		    {
    509 		      /* sanity check */
    510 		      if (length != 0 && length != elength)
    511 			abort ();
    512 		      return insn;
    513 		    }
    514 		}
    515 	    }
    516 
    517 	  insn_list = insn_list->next;
    518 	}
    519     }
    520   else
    521     {
    522       /* Sanity check: can't pass an alias insn if ! alias_p.  */
    523       if (! alias_p
    524 	  && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
    525 	abort ();
    526       /* Sanity check: length must be correct.  */
    527       if (length != CGEN_INSN_BITSIZE (insn))
    528 	abort ();
    529 
    530       /* ??? 0 is passed for `pc' */
    531       length = CGEN_EXTRACT_FN (cd, insn)
    532 	(cd, insn, info, base_insn, fields, (bfd_vma) 0);
    533       /* Sanity check: must succeed.
    534 	 Could relax this later if it ever proves useful.  */
    535       if (length == 0)
    536 	abort ();
    537       return insn;
    538     }
    539 
    540   return NULL;
    541 }
    542 
    543 /* Fill in the operand instances used by INSN whose operands are FIELDS.
    544    INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
    545    in.  */
    546 
    547 void
    548 cgen_get_insn_operands (CGEN_CPU_DESC cd,
    549 			const CGEN_INSN *insn,
    550 			const CGEN_FIELDS *fields,
    551 			int *indices)
    552 {
    553   const CGEN_OPINST *opinst;
    554   int i;
    555 
    556   if (insn->opinst == NULL)
    557     abort ();
    558   for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
    559     {
    560       enum cgen_operand_type op_type = opinst->op_type;
    561       if (op_type == CGEN_OPERAND_NIL)
    562 	indices[i] = opinst->index;
    563       else
    564 	indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
    565     }
    566 }
    567 
    568 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
    569    isn't known.
    570    The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
    571    cgen_lookup_insn unchanged.
    572    INSN_INT_VALUE is used if CGEN_INT_INSN_P.
    573    Otherwise INSN_BYTES_VALUE is used.
    574 
    575    The result is the insn table entry or NULL if the instruction wasn't
    576    recognized.  */
    577 
    578 const CGEN_INSN *
    579 cgen_lookup_get_insn_operands (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 (CGEN_CPU_DESC cd)
    602 {
    603   cd->signed_overflow_ok_p = 1;
    604 }
    605 
    606 /* Generate an error message if a signed field in an instruction overflows.  */
    607 void
    608 cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd)
    609 {
    610   cd->signed_overflow_ok_p = 0;
    611 }
    612 
    613 /* Will an error message be generated if a signed field in an instruction overflows ? */
    614 unsigned int
    615 cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd)
    616 {
    617   return cd->signed_overflow_ok_p;
    618 }
    619