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 
28 static void get_opc_prefix (const char **, char *);
29 static short int find_string_ent (const char *);
30 static short int find_main_ent (short int);
31 static short int find_completer (short int, short int, const char *);
32 static ia64_insn apply_completer (ia64_insn, int);
33 static int extract_op_bits (int, int, int);
34 static int extract_op (int, int *, unsigned int *);
35 static int opcode_verify (ia64_insn, int, enum ia64_insn_type);
36 static int locate_opcode_ent (ia64_insn, enum ia64_insn_type);
37 static struct ia64_opcode *make_ia64_opcode
38   (ia64_insn, const char *, int, int);
39 static struct ia64_opcode *ia64_find_matching_opcode
40   (const char *, short int);
41 
42 const 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 
67 static void
get_opc_prefix(const char ** ptr,char * dest)68 get_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 
89 static short
find_string_ent(const char * str)90 find_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 
123 static short
find_main_ent(short nameindex)124 find_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 
162 static short
find_completer(short main_ent,short prev_completer,const char * name)163 find_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 
195 static ia64_insn
apply_completer(ia64_insn opcode,int completer_index)196 apply_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 
213 static int
extract_op_bits(int op_pointer,int bitoffset,int bits)214 extract_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 
249 static int
extract_op(int op_pointer,int * opval,unsigned int * op)250 extract_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 
304 static int
opcode_verify(ia64_insn opcode,int place,enum ia64_insn_type type)305 opcode_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 
348 static int
locate_opcode_ent(ia64_insn opcode,enum ia64_insn_type type)349 locate_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 
527 static struct ia64_opcode *
make_ia64_opcode(ia64_insn opcode,const char * name,int place,int depind)528 make_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. */
550 struct ia64_opcode *
ia64_dis_opcode(ia64_insn insn,enum ia64_insn_type type)551 ia64_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 
609 static struct ia64_opcode *
ia64_find_matching_opcode(const char * name,short place)610 ia64_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 
670 struct ia64_opcode *
ia64_find_next_opcode(struct ia64_opcode * prev_ent)671 ia64_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 
683 struct ia64_opcode *
ia64_find_opcode(const char * name)684 ia64_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. */
713 void
ia64_free_opcode(struct ia64_opcode * ent)714 ia64_free_opcode (struct ia64_opcode *ent)
715 {
716   free ((void *)ent->name);
717   free (ent);
718 }
719 
720 const struct ia64_dependency *
ia64_find_dependency(int index)721 ia64_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