1/* ia64-opc.c -- Functions to access the compacted opcode table
2   Copyright 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
3   Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
4
5   This file is part of GDB, GAS, and the GNU binutils.
6
7   GDB, GAS, and the GNU binutils are free software; you can redistribute
8   them and/or modify them under the terms of the GNU General Public
9   License as published by the Free Software Foundation; either version
10   2, or (at your option) any later version.
11
12   GDB, GAS, and the GNU binutils are distributed in the hope that they
13   will be useful, but WITHOUT ANY WARRANTY; without even the implied
14   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15   the GNU General Public 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, MA
20   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 index)
722{
723  index = DEP(index);
724
725  if (index < 0
726      || index >= (int)(sizeof(dependencies) / sizeof(dependencies[0])))
727    return NULL;
728
729  return &dependencies[index];
730}
731