1 /* ia64-opc.c -- Functions to access the compacted opcode table
2    Copyright 1999, 2000, 2001, 2003, 2005, 2007, 2009, 2012
3    Free Software Foundation, Inc.
4    Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
5 
6    This file is part of the GNU opcodes library.
7 
8    This library is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3, or (at your option)
11    any later version.
12 
13    It is distributed in the hope that it will be useful, but WITHOUT
14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16    License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this file; see the file COPYING.  If not, write to the
20    Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22 
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 dep_index)721 ia64_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