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