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