Eliminate ia64 compiler warnings. Fix ia64 gas testsuite again.
[external/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.  Checks all matches and returns the one with the highest
350    priority. */
351
352 static int
353 locate_opcode_ent (opcode, type)
354      ia64_insn opcode;
355      enum ia64_insn_type type;
356 {
357   int currtest[41];
358   int bitpos[41];
359   int op_ptr[41];
360   int currstatenum = 0;
361   short found_disent = -1;
362   short found_priority = -1;
363
364   currtest[currstatenum] = 0;
365   op_ptr[currstatenum] = 0;
366   bitpos[currstatenum] = 40;
367
368   while (1)
369     {
370       int op_pointer = op_ptr[currstatenum];
371       unsigned int op;
372       int currbitnum = bitpos[currstatenum];
373       int oplen;
374       int opval[3];
375       int next_op;
376       int currbit;
377
378       oplen = extract_op (op_pointer, opval, &op);
379
380       bitpos[currstatenum] = currbitnum;
381
382       /* Skip opval[0] bits in the instruction. */
383       if (op & 0x40)
384         {
385           currbitnum -= opval[0];
386         }
387
388       /* The value of the current bit being tested. */
389       currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0;
390       next_op = -1;
391
392       /* We always perform the tests specified in the current state in
393          a particular order, falling through to the next test if the
394          previous one failed. */
395       switch (currtest[currstatenum])
396         {
397         case 0:
398           currtest[currstatenum]++;
399           if (currbit == 0 && (op & 0x80))
400             {
401               /* Check for a zero bit.  If this test solely checks for
402                  a zero bit, we can check for up to 8 consecutive zero
403                  bits (the number to check is specified by the lower 3
404                  bits in the state code.)
405
406                  If the state instruction matches, we go to the very
407                  next state instruction; otherwise, try the next test. */
408
409               if ((op & 0xf8) == 0x80)
410                 {
411                   int count = op & 0x7;
412                   int x;
413
414                   for (x = 0; x <= count; x++)
415                     {
416                       int i =
417                         opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0;
418                       if (i)
419                         {
420                           break;
421                         }
422                     }
423                   if (x > count)
424                     {
425                       next_op = op_pointer + ((oplen + 7) / 8);
426                       currbitnum -= count;
427                       break;
428                     }
429                 }
430               else if (! currbit)
431                 {
432                   next_op = op_pointer + ((oplen + 7) / 8);
433                   break;
434                 }
435             }
436           /* FALLTHROUGH */
437         case 1:
438           /* If the bit in the instruction is one, go to the state
439              instruction specified by opval[1]. */
440           currtest[currstatenum]++;
441           if (currbit && (op & 0x30) != 0 && ((op & 0x30) != 0x30))
442             {
443               next_op = opval[1];
444               break;
445             }
446           /* FALLTHROUGH */
447         case 2:
448           /* Don't care.  Skip the current bit and go to the state
449              instruction specified by opval[2].
450
451              An encoding of 0x30 is special; this means that a 12-bit
452              offset into the ia64_dis_names[] array is specified.  */
453           currtest[currstatenum]++;
454           if ((op & 0x08) || ((op & 0x30) == 0x30))
455             {
456               next_op = opval[2];
457               break;
458             }
459         }
460
461       /* If bit 15 is set in the address of the next state, an offset
462          in the ia64_dis_names array was specified instead.  We then
463          check to see if an entry in the list of opcodes matches the
464          opcode we were given; if so, we have succeeded.  */
465
466       if ((next_op >= 0) && (next_op & 32768))
467         {
468           short disent = next_op & 32767;
469           short priority = -1;
470
471           if (next_op > 65535)
472             {
473               abort ();
474             }
475
476           /* Run through the list of opcodes to check, trying to find
477              one that matches.  */
478           while (disent >= 0)
479             {
480               int place = ia64_dis_names[disent].insn_index;
481
482               priority = ia64_dis_names[disent].priority;
483
484               if (opcode_verify (opcode, place, type) 
485                   && priority > found_priority)
486                 {
487                   break;
488                 }
489               if (ia64_dis_names[disent].next_flag)
490                 {
491                   disent++;
492                 }
493               else
494                 {
495                   disent = -1;
496                 }
497             }
498
499           if (disent >= 0)
500             {
501               found_disent = disent;
502               found_priority = priority;
503             }
504           /* Try the next test in this state, regardless of whether a match
505              was found. */
506           next_op = -2;
507         }
508
509       /* next_op == -1 is "back up to the previous state".
510          next_op == -2 is "stay in this state and try the next test".
511          Otherwise, transition to the state indicated by next_op. */
512
513       if (next_op == -1)
514         {
515           currstatenum--;
516           if (currstatenum < 0)
517             {
518               return found_disent;
519             }
520         }
521       else if (next_op >= 0)
522         {
523           currstatenum++;
524           bitpos[currstatenum] = currbitnum - 1;
525           op_ptr[currstatenum] = next_op;
526           currtest[currstatenum] = 0;
527         }
528     }
529 }
530 \f
531 /* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
532
533 static struct ia64_opcode *
534 make_ia64_opcode (opcode, name, place, depind)
535      ia64_insn opcode;
536      const char *name;
537      int place;
538      int depind;
539 {
540   struct ia64_opcode *res =
541     (struct ia64_opcode *) xmalloc (sizeof (struct ia64_opcode));
542   res->name = xstrdup (name);
543   res->type = main_table[place].opcode_type;
544   res->num_outputs = main_table[place].num_outputs;
545   res->opcode = opcode;
546   res->mask = main_table[place].mask;
547   res->operands[0] = main_table[place].operands[0];
548   res->operands[1] = main_table[place].operands[1];
549   res->operands[2] = main_table[place].operands[2];
550   res->operands[3] = main_table[place].operands[3];
551   res->operands[4] = main_table[place].operands[4];
552   res->flags = main_table[place].flags;
553   res->ent_index = place;
554   res->dependencies = &op_dependencies[depind];
555   return res;
556 }
557 \f
558 /* Determine the ia64_opcode entry for the opcode specified by INSN
559    and TYPE.  If a valid entry is not found, return NULL. */
560 struct ia64_opcode *
561 ia64_dis_opcode (insn, type)
562      ia64_insn insn;
563      enum ia64_insn_type type;
564 {
565   int disent = locate_opcode_ent (insn, type);
566
567   if (disent < 0)
568     {
569       return NULL;
570     }
571   else
572     {
573       unsigned int cb = ia64_dis_names[disent].completer_index;
574       static char name[128];
575       int place = ia64_dis_names[disent].insn_index;
576       int ci = main_table[place].completers;
577       ia64_insn tinsn = main_table[place].opcode;
578
579       strcpy (name, ia64_strings [main_table[place].name_index]);
580
581       while (cb)
582         {
583           if (cb & 1)
584             {
585               int cname = completer_table[ci].name_index;
586
587               tinsn = apply_completer (tinsn, ci);
588
589               if (ia64_strings[cname][0] != '\0')
590                 {
591                   strcat (name, ".");
592                   strcat (name, ia64_strings[cname]);
593                 }
594               if (cb != 1)
595                 {
596                   ci = completer_table[ci].subentries;
597                 }
598             }
599           else
600             {
601               ci = completer_table[ci].alternative;
602             }
603           if (ci < 0)
604             {
605               abort ();
606             }
607           cb = cb >> 1;
608         }
609       if (tinsn != (insn & main_table[place].mask))
610         {
611           abort ();
612         }
613       return make_ia64_opcode (insn, name, place, 
614                                completer_table[ci].dependencies);
615     }
616 }
617 \f
618 /* Search the main_opcode table starting from PLACE for an opcode that
619    matches NAME.  Return NULL if one is not found. */
620
621 static struct ia64_opcode *
622 ia64_find_matching_opcode (name, place)
623      const char *name;
624      short place;
625 {
626   char op[129];
627   const char *suffix;
628   short name_index;
629
630   if (strlen (name) > 128)
631     {
632       return NULL;
633     }
634   suffix = name;
635   get_opc_prefix (&suffix, op);
636   name_index = find_string_ent (op);
637   if (name_index < 0)
638     {
639       return NULL;
640     }
641
642   while (main_table[place].name_index == name_index)
643     {
644       const char *curr_suffix = suffix;
645       ia64_insn curr_insn = main_table[place].opcode;
646       short completer = -1;
647
648       do {
649         if (suffix[0] == '\0')
650           {
651             completer = find_completer (place, completer, suffix);
652           }
653         else
654           {
655             get_opc_prefix (&curr_suffix, op);
656             completer = find_completer (place, completer, op);
657           }
658         if (completer != -1)
659           {
660             curr_insn = apply_completer (curr_insn, completer);
661           }
662       } while (completer != -1 && curr_suffix[0] != '\0');
663
664       if (completer != -1 && curr_suffix[0] == '\0'
665           && completer_table[completer].terminal_completer)
666         {
667           int depind = completer_table[completer].dependencies;
668           return make_ia64_opcode (curr_insn, name, place, depind);
669         }
670       else
671         {
672           place++;
673         }
674     }
675   return NULL;
676 }
677 \f
678 /* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
679    if one does not exist.
680
681    It is the caller's responsibility to invoke ia64_free_opcode () to
682    release any resources used by the returned entry. */
683
684 struct ia64_opcode *
685 ia64_find_next_opcode (prev_ent)
686      struct ia64_opcode *prev_ent;
687 {
688   return ia64_find_matching_opcode (prev_ent->name,
689                                     prev_ent->ent_index + 1);
690 }
691
692 /* Find the first opcode that matches NAME, or return NULL if it does
693    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_opcode (name)
700      const char *name;
701 {
702   char op[129];
703   const char *suffix;
704   short place;
705   short name_index;
706
707   if (strlen (name) > 128)
708     {
709       return NULL;
710     }
711   suffix = name;
712   get_opc_prefix (&suffix, op);
713   name_index = find_string_ent (op);
714   if (name_index < 0)
715     {
716       return NULL;
717     }
718
719   place = find_main_ent (name_index);
720
721   if (place < 0)
722     {
723       return NULL;
724     }
725   return ia64_find_matching_opcode (name, place);
726 }
727
728 /* Free any resources used by ENT. */
729 void
730 ia64_free_opcode (ent)
731      struct ia64_opcode *ent;
732 {
733   free ((void *)ent->name);
734   free (ent);
735 }
736
737 const struct ia64_dependency *
738 ia64_find_dependency (index)
739   int index;
740 {
741   index = DEP(index);
742
743   if (index < 0
744       || index >= (int)(sizeof(dependencies) / sizeof(dependencies[0])))
745     return NULL;
746
747   return &dependencies[index];
748 }