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