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