Varobj support for Ada.
[deliverable/binutils-gdb.git] / opcodes / ia64-opc.c
1 /* ia64-opc.c -- Functions to access the compacted opcode table
2 Copyright 1999, 2000, 2001, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
3 Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
4
5 This file is part of the GNU opcodes library.
6
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 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,
20 MA 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 dep_index)
722 {
723 dep_index = DEP(dep_index);
724
725 if (dep_index < 0
726 || dep_index >= (int) ARRAY_SIZE (dependencies))
727 return NULL;
728
729 return &dependencies[dep_index];
730 }
This page took 0.045417 seconds and 4 git commands to generate.