1/* ia64-opc.c -- Functions to access the compacted opcode table
2   Copyright (C) 1999-2017 Free Software Foundation, Inc.
3   Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
4
5   This file is part of the GNU opcodes library.
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
18   along with this file; see the file COPYING.  If not, write to the
19   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20   MA 02110-1301, USA.  */
21
22#include "sysdep.h"
23#include "libiberty.h"
24#include "ia64-asmtab.h"
25#include "ia64-asmtab.c"
26
27static void get_opc_prefix (const char **, char *);
28static short int find_string_ent (const char *);
29static short int find_main_ent (short int);
30static short int find_completer (short int, short int, const char *);
31static ia64_insn apply_completer (ia64_insn, int);
32static int extract_op_bits (int, int, int);
33static int extract_op (int, int *, unsigned int *);
34static int opcode_verify (ia64_insn, int, enum ia64_insn_type);
35static int locate_opcode_ent (ia64_insn, enum ia64_insn_type);
36static struct ia64_opcode *make_ia64_opcode
37  (ia64_insn, const char *, int, int);
38static struct ia64_opcode *ia64_find_matching_opcode
39  (const char *, short int);
40
41const struct ia64_templ_desc ia64_templ_desc[16] =
42  {
43    { 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" },	/* 0 */
44    { 2, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" },
45    { 0, { IA64_UNIT_M, IA64_UNIT_L, IA64_UNIT_X }, "MLX" },
46    { 0, { 0, },				    "-3-" },
47    { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" },	/* 4 */
48    { 1, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" },
49    { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_I }, "MFI" },
50    { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_F }, "MMF" },
51    { 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_B }, "MIB" },	/* 8 */
52    { 0, { IA64_UNIT_M, IA64_UNIT_B, IA64_UNIT_B }, "MBB" },
53    { 0, { 0, },				    "-a-" },
54    { 0, { IA64_UNIT_B, IA64_UNIT_B, IA64_UNIT_B }, "BBB" },
55    { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_B }, "MMB" },	/* c */
56    { 0, { 0, },				    "-d-" },
57    { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_B }, "MFB" },
58    { 0, { 0, },				    "-f-" },
59  };
60
61
62/* Copy the prefix contained in *PTR (up to a '.' or a NUL) to DEST.
63   PTR will be adjusted to point to the start of the next portion
64   of the opcode, or at the NUL character. */
65
66static void
67get_opc_prefix (const char **ptr, char *dest)
68{
69  char *c = strchr (*ptr, '.');
70  if (c != NULL)
71    {
72      memcpy (dest, *ptr, c - *ptr);
73      dest[c - *ptr] = '\0';
74      *ptr = c + 1;
75    }
76  else
77    {
78      int l = strlen (*ptr);
79      memcpy (dest, *ptr, l);
80      dest[l] = '\0';
81      *ptr += l;
82    }
83}
84
85/* Find the index of the entry in the string table corresponding to
86   STR; return -1 if one does not exist. */
87
88static short
89find_string_ent (const char *str)
90{
91  short start = 0;
92  short end = sizeof (ia64_strings) / sizeof (const char *);
93  short i = (start + end) / 2;
94
95  if (strcmp (str, ia64_strings[end - 1]) > 0)
96    {
97      return -1;
98    }
99  while (start <= end)
100    {
101      int c = strcmp (str, ia64_strings[i]);
102      if (c < 0)
103	{
104	  end = i - 1;
105	}
106      else if (c == 0)
107	{
108	  return i;
109	}
110      else
111	{
112	  start = i + 1;
113	}
114      i = (start + end) / 2;
115    }
116  return -1;
117}
118
119/* Find the opcode in the main opcode table whose name is STRINGINDEX, or
120   return -1 if one does not exist. */
121
122static short
123find_main_ent (short nameindex)
124{
125  short start = 0;
126  short end = sizeof (main_table) / sizeof (struct ia64_main_table);
127  short i = (start + end) / 2;
128
129  if (nameindex < main_table[0].name_index
130      || nameindex > main_table[end - 1].name_index)
131    {
132      return -1;
133    }
134  while (start <= end)
135    {
136      if (nameindex < main_table[i].name_index)
137	{
138	  end = i - 1;
139	}
140      else if (nameindex == main_table[i].name_index)
141	{
142	  while (i > 0 && main_table[i - 1].name_index == nameindex)
143	    {
144	      i--;
145	    }
146	  return i;
147	}
148      else
149	{
150	  start = i + 1;
151	}
152      i = (start + end) / 2;
153    }
154  return -1;
155}
156
157/* Find the index of the entry in the completer table that is part of
158   MAIN_ENT (starting from PREV_COMPLETER) that matches NAME, or
159   return -1 if one does not exist. */
160
161static short
162find_completer (short main_ent, short prev_completer, const char *name)
163{
164  short name_index = find_string_ent (name);
165
166  if (name_index < 0)
167    {
168      return -1;
169    }
170
171  if (prev_completer == -1)
172    {
173      prev_completer = main_table[main_ent].completers;
174    }
175  else
176    {
177      prev_completer = completer_table[prev_completer].subentries;
178    }
179
180  while (prev_completer != -1)
181    {
182      if (completer_table[prev_completer].name_index == name_index)
183	{
184	  return prev_completer;
185	}
186      prev_completer = completer_table[prev_completer].alternative;
187    }
188  return -1;
189}
190
191/* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
192   return the result. */
193
194static ia64_insn
195apply_completer (ia64_insn opcode, int completer_index)
196{
197  ia64_insn mask = completer_table[completer_index].mask;
198  ia64_insn bits = completer_table[completer_index].bits;
199  int shiftamt = (completer_table[completer_index].offset & 63);
200
201  mask = mask << shiftamt;
202  bits = bits << shiftamt;
203  opcode = (opcode & ~mask) | bits;
204  return opcode;
205}
206
207/* Extract BITS number of bits starting from OP_POINTER + BITOFFSET in
208   the dis_table array, and return its value.  (BITOFFSET is numbered
209   starting from MSB to LSB, so a BITOFFSET of 0 indicates the MSB of the
210   first byte in OP_POINTER.) */
211
212static int
213extract_op_bits (int op_pointer, int bitoffset, int bits)
214{
215  int res = 0;
216
217  op_pointer += (bitoffset / 8);
218
219  if (bitoffset % 8)
220    {
221      unsigned int op = dis_table[op_pointer++];
222      int numb = 8 - (bitoffset % 8);
223      int mask = (1 << numb) - 1;
224      int bata = (bits < numb) ? bits : numb;
225      int delta = numb - bata;
226
227      res = (res << bata) | ((op & mask) >> delta);
228      bitoffset += bata;
229      bits -= bata;
230    }
231  while (bits >= 8)
232    {
233      res = (res << 8) | (dis_table[op_pointer++] & 255);
234      bits -= 8;
235    }
236  if (bits > 0)
237    {
238      unsigned int op = (dis_table[op_pointer++] & 255);
239      res = (res << bits) | (op >> (8 - bits));
240    }
241  return res;
242}
243
244/* Examine the state machine entry at OP_POINTER in the dis_table
245   array, and extract its values into OPVAL and OP.  The length of the
246   state entry in bits is returned. */
247
248static int
249extract_op (int op_pointer, int *opval, unsigned int *op)
250{
251  int oplen = 5;
252
253  *op = dis_table[op_pointer];
254
255  if ((*op) & 0x40)
256    {
257      opval[0] = extract_op_bits (op_pointer, oplen, 5);
258      oplen += 5;
259    }
260  switch ((*op) & 0x30)
261    {
262    case 0x10:
263      {
264	opval[1] = extract_op_bits (op_pointer, oplen, 8);
265	oplen += 8;
266	opval[1] += op_pointer;
267	break;
268      }
269    case 0x20:
270      {
271	opval[1] = extract_op_bits (op_pointer, oplen, 16);
272	if (! (opval[1] & 32768))
273	  {
274	    opval[1] += op_pointer;
275	  }
276	oplen += 16;
277	break;
278      }
279    case 0x30:
280      {
281	oplen--;
282	opval[2] = extract_op_bits (op_pointer, oplen, 12);
283	oplen += 12;
284	opval[2] |= 32768;
285	break;
286      }
287    }
288  if (((*op) & 0x08) && (((*op) & 0x30) != 0x30))
289    {
290      opval[2] = extract_op_bits (op_pointer, oplen, 16);
291      oplen += 16;
292      if (! (opval[2] & 32768))
293	{
294	  opval[2] += op_pointer;
295	}
296    }
297  return oplen;
298}
299
300/* Returns a non-zero value if the opcode in the main_table list at
301   PLACE matches OPCODE and is of type TYPE. */
302
303static int
304opcode_verify (ia64_insn opcode, int place, enum ia64_insn_type type)
305{
306  if (main_table[place].opcode_type != type)
307    {
308      return 0;
309    }
310  if (main_table[place].flags
311      & (IA64_OPCODE_F2_EQ_F3 | IA64_OPCODE_LEN_EQ_64MCNT))
312    {
313      const struct ia64_operand *o1, *o2;
314      ia64_insn f2, f3;
315
316      if (main_table[place].flags & IA64_OPCODE_F2_EQ_F3)
317	{
318	  o1 = elf64_ia64_operands + IA64_OPND_F2;
319	  o2 = elf64_ia64_operands + IA64_OPND_F3;
320	  (*o1->extract) (o1, opcode, &f2);
321	  (*o2->extract) (o2, opcode, &f3);
322	  if (f2 != f3)
323	    return 0;
324	}
325      else
326	{
327	  ia64_insn len, count;
328
329	  /* length must equal 64-count: */
330	  o1 = elf64_ia64_operands + IA64_OPND_LEN6;
331	  o2 = elf64_ia64_operands + main_table[place].operands[2];
332	  (*o1->extract) (o1, opcode, &len);
333	  (*o2->extract) (o2, opcode, &count);
334	  if (len != 64 - count)
335	    return 0;
336	}
337    }
338  return 1;
339}
340
341/* Find an instruction entry in the ia64_dis_names array that matches
342   opcode OPCODE and is of type TYPE.  Returns either a positive index
343   into the array, or a negative value if an entry for OPCODE could
344   not be found.  Checks all matches and returns the one with the highest
345   priority. */
346
347static int
348locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type)
349{
350  int currtest[41];
351  int bitpos[41];
352  int op_ptr[41];
353  int currstatenum = 0;
354  short found_disent = -1;
355  short found_priority = -1;
356
357  currtest[currstatenum] = 0;
358  op_ptr[currstatenum] = 0;
359  bitpos[currstatenum] = 40;
360
361  while (1)
362    {
363      int op_pointer = op_ptr[currstatenum];
364      unsigned int op;
365      int currbitnum = bitpos[currstatenum];
366      int oplen;
367      int opval[3] = {0};
368      int next_op;
369      int currbit;
370
371      oplen = extract_op (op_pointer, opval, &op);
372
373      bitpos[currstatenum] = currbitnum;
374
375      /* Skip opval[0] bits in the instruction. */
376      if (op & 0x40)
377	{
378	  currbitnum -= opval[0];
379	}
380
381      /* The value of the current bit being tested. */
382      currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0;
383      next_op = -1;
384
385      /* We always perform the tests specified in the current state in
386	 a particular order, falling through to the next test if the
387	 previous one failed. */
388      switch (currtest[currstatenum])
389	{
390	case 0:
391	  currtest[currstatenum]++;
392	  if (currbit == 0 && (op & 0x80))
393	    {
394	      /* Check for a zero bit.  If this test solely checks for
395		 a zero bit, we can check for up to 8 consecutive zero
396		 bits (the number to check is specified by the lower 3
397		 bits in the state code.)
398
399		 If the state instruction matches, we go to the very
400		 next state instruction; otherwise, try the next test. */
401
402	      if ((op & 0xf8) == 0x80)
403		{
404		  int count = op & 0x7;
405		  int x;
406
407		  for (x = 0; x <= count; x++)
408		    {
409		      int i =
410			opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0;
411		      if (i)
412			{
413			  break;
414			}
415		    }
416		  if (x > count)
417		    {
418		      next_op = op_pointer + ((oplen + 7) / 8);
419		      currbitnum -= count;
420		      break;
421		    }
422		}
423	      else if (! currbit)
424		{
425		  next_op = op_pointer + ((oplen + 7) / 8);
426		  break;
427		}
428	    }
429	  /* FALLTHROUGH */
430	case 1:
431	  /* If the bit in the instruction is one, go to the state
432	     instruction specified by opval[1]. */
433	  currtest[currstatenum]++;
434	  if (currbit && (op & 0x30) != 0 && ((op & 0x30) != 0x30))
435	    {
436	      next_op = opval[1];
437	      break;
438	    }
439	  /* FALLTHROUGH */
440	case 2:
441	  /* Don't care.  Skip the current bit and go to the state
442	     instruction specified by opval[2].
443
444	     An encoding of 0x30 is special; this means that a 12-bit
445	     offset into the ia64_dis_names[] array is specified.  */
446	  currtest[currstatenum]++;
447	  if ((op & 0x08) || ((op & 0x30) == 0x30))
448	    {
449	      next_op = opval[2];
450	      break;
451	    }
452	}
453
454      /* If bit 15 is set in the address of the next state, an offset
455	 in the ia64_dis_names array was specified instead.  We then
456	 check to see if an entry in the list of opcodes matches the
457	 opcode we were given; if so, we have succeeded.  */
458
459      if ((next_op >= 0) && (next_op & 32768))
460	{
461	  short disent = next_op & 32767;
462          short priority = -1;
463
464	  if (next_op > 65535)
465	    {
466	      abort ();
467	    }
468
469	  /* Run through the list of opcodes to check, trying to find
470	     one that matches.  */
471	  while (disent >= 0)
472	    {
473	      int place = ia64_dis_names[disent].insn_index;
474
475              priority = ia64_dis_names[disent].priority;
476
477	      if (opcode_verify (opcode, place, type)
478                  && priority > found_priority)
479		{
480		  break;
481		}
482	      if (ia64_dis_names[disent].next_flag)
483		{
484		  disent++;
485		}
486	      else
487		{
488		  disent = -1;
489		}
490	    }
491
492	  if (disent >= 0)
493	    {
494              found_disent = disent;
495              found_priority = priority;
496	    }
497          /* Try the next test in this state, regardless of whether a match
498             was found. */
499          next_op = -2;
500	}
501
502      /* next_op == -1 is "back up to the previous state".
503	 next_op == -2 is "stay in this state and try the next test".
504	 Otherwise, transition to the state indicated by next_op. */
505
506      if (next_op == -1)
507	{
508	  currstatenum--;
509	  if (currstatenum < 0)
510	    {
511              return found_disent;
512	    }
513	}
514      else if (next_op >= 0)
515	{
516	  currstatenum++;
517	  bitpos[currstatenum] = currbitnum - 1;
518	  op_ptr[currstatenum] = next_op;
519	  currtest[currstatenum] = 0;
520	}
521    }
522}
523
524/* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
525
526static struct ia64_opcode *
527make_ia64_opcode (ia64_insn opcode, const char *name, int place, int depind)
528{
529  struct ia64_opcode *res =
530    (struct ia64_opcode *) xmalloc (sizeof (struct ia64_opcode));
531  res->name = xstrdup (name);
532  res->type = main_table[place].opcode_type;
533  res->num_outputs = main_table[place].num_outputs;
534  res->opcode = opcode;
535  res->mask = main_table[place].mask;
536  res->operands[0] = main_table[place].operands[0];
537  res->operands[1] = main_table[place].operands[1];
538  res->operands[2] = main_table[place].operands[2];
539  res->operands[3] = main_table[place].operands[3];
540  res->operands[4] = main_table[place].operands[4];
541  res->flags = main_table[place].flags;
542  res->ent_index = place;
543  res->dependencies = &op_dependencies[depind];
544  return res;
545}
546
547/* Determine the ia64_opcode entry for the opcode specified by INSN
548   and TYPE.  If a valid entry is not found, return NULL. */
549struct ia64_opcode *
550ia64_dis_opcode (ia64_insn insn, enum ia64_insn_type type)
551{
552  int disent = locate_opcode_ent (insn, type);
553
554  if (disent < 0)
555    {
556      return NULL;
557    }
558  else
559    {
560      unsigned int cb = ia64_dis_names[disent].completer_index;
561      static char name[128];
562      int place = ia64_dis_names[disent].insn_index;
563      int ci = main_table[place].completers;
564      ia64_insn tinsn = main_table[place].opcode;
565
566      strcpy (name, ia64_strings [main_table[place].name_index]);
567
568      while (cb)
569	{
570	  if (cb & 1)
571	    {
572	      int cname = completer_table[ci].name_index;
573
574	      tinsn = apply_completer (tinsn, ci);
575
576	      if (ia64_strings[cname][0] != '\0')
577		{
578		  strcat (name, ".");
579		  strcat (name, ia64_strings[cname]);
580		}
581	      if (cb != 1)
582		{
583		  ci = completer_table[ci].subentries;
584		}
585	    }
586	  else
587	    {
588	      ci = completer_table[ci].alternative;
589	    }
590	  if (ci < 0)
591	    {
592	      abort ();
593	    }
594	  cb = cb >> 1;
595	}
596      if (tinsn != (insn & main_table[place].mask))
597	{
598	  abort ();
599	}
600      return make_ia64_opcode (insn, name, place,
601                               completer_table[ci].dependencies);
602    }
603}
604
605/* Search the main_opcode table starting from PLACE for an opcode that
606   matches NAME.  Return NULL if one is not found. */
607
608static struct ia64_opcode *
609ia64_find_matching_opcode (const char *name, short place)
610{
611  char op[129];
612  const char *suffix;
613  short name_index;
614
615  if (strlen (name) > 128)
616    {
617      return NULL;
618    }
619  suffix = name;
620  get_opc_prefix (&suffix, op);
621  name_index = find_string_ent (op);
622  if (name_index < 0)
623    {
624      return NULL;
625    }
626
627  while (main_table[place].name_index == name_index)
628    {
629      const char *curr_suffix = suffix;
630      ia64_insn curr_insn = main_table[place].opcode;
631      short completer = -1;
632
633      do {
634	if (suffix[0] == '\0')
635	  {
636	    completer = find_completer (place, completer, suffix);
637	  }
638	else
639	  {
640	    get_opc_prefix (&curr_suffix, op);
641	    completer = find_completer (place, completer, op);
642	  }
643	if (completer != -1)
644	  {
645	    curr_insn = apply_completer (curr_insn, completer);
646	  }
647      } while (completer != -1 && curr_suffix[0] != '\0');
648
649      if (completer != -1 && curr_suffix[0] == '\0'
650	  && completer_table[completer].terminal_completer)
651	{
652          int depind = completer_table[completer].dependencies;
653	  return make_ia64_opcode (curr_insn, name, place, depind);
654	}
655      else
656	{
657	  place++;
658	}
659    }
660  return NULL;
661}
662
663/* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
664   if one does not exist.
665
666   It is the caller's responsibility to invoke ia64_free_opcode () to
667   release any resources used by the returned entry. */
668
669struct ia64_opcode *
670ia64_find_next_opcode (struct ia64_opcode *prev_ent)
671{
672  return ia64_find_matching_opcode (prev_ent->name,
673				    prev_ent->ent_index + 1);
674}
675
676/* Find the first opcode that matches NAME, or return NULL if it does
677   not exist.
678
679   It is the caller's responsibility to invoke ia64_free_opcode () to
680   release any resources used by the returned entry. */
681
682struct ia64_opcode *
683ia64_find_opcode (const char *name)
684{
685  char op[129];
686  const char *suffix;
687  short place;
688  short name_index;
689
690  if (strlen (name) > 128)
691    {
692      return NULL;
693    }
694  suffix = name;
695  get_opc_prefix (&suffix, op);
696  name_index = find_string_ent (op);
697  if (name_index < 0)
698    {
699      return NULL;
700    }
701
702  place = find_main_ent (name_index);
703
704  if (place < 0)
705    {
706      return NULL;
707    }
708  return ia64_find_matching_opcode (name, place);
709}
710
711/* Free any resources used by ENT. */
712void
713ia64_free_opcode (struct ia64_opcode *ent)
714{
715  free ((void *)ent->name);
716  free (ent);
717}
718
719const struct ia64_dependency *
720ia64_find_dependency (int dep_index)
721{
722  dep_index = DEP(dep_index);
723
724  if (dep_index < 0
725      || dep_index >= (int) ARRAY_SIZE (dependencies))
726    return NULL;
727
728  return &dependencies[dep_index];
729}
730