]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/binutils/opcodes/ia64-opc.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / binutils / opcodes / ia64-opc.c
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
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 \f
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
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 \f
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
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 \f
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
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 \f
192 /* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
193    return the result. */
194
195 static ia64_insn
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 \f
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
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 \f
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
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 \f
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
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 \f
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
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 \f
525 /* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
526
527 static struct ia64_opcode *
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 \f
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 *
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 \f
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 *
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 \f
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 *
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 *
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
714 ia64_free_opcode (struct ia64_opcode *ent)
715 {
716   free ((void *)ent->name);
717   free (ent);
718 }
719
720 const struct ia64_dependency *
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 }