1 /* ia64-opc.c -- Functions to access the compacted opcode table
2 Copyright 1999, 2000, 2001, 2003, 2005, 2007, 2009, 2012
3 Free Software Foundation, Inc.
4 Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
6 This file is part of the GNU opcodes library.
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this file; see the file COPYING. If not, write to the
20 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 #include "libiberty.h"
25 #include "ia64-asmtab.h"
26 #include "ia64-asmtab.c"
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);
42 const struct ia64_templ_desc ia64_templ_desc[16] =
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" },
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" },
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 */
58 { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_B }, "MFB" },
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. */
68 get_opc_prefix (const char **ptr, char *dest)
70 char *c = strchr (*ptr, '.');
73 memcpy (dest, *ptr, c - *ptr);
74 dest[c - *ptr] = '\0';
79 int l = strlen (*ptr);
80 memcpy (dest, *ptr, l);
86 /* Find the index of the entry in the string table corresponding to
87 STR; return -1 if one does not exist. */
90 find_string_ent (const char *str)
93 short end = sizeof (ia64_strings) / sizeof (const char *);
94 short i = (start + end) / 2;
96 if (strcmp (str, ia64_strings[end - 1]) > 0)
102 int c = strcmp (str, ia64_strings[i]);
115 i = (start + end) / 2;
120 /* Find the opcode in the main opcode table whose name is STRINGINDEX, or
121 return -1 if one does not exist. */
124 find_main_ent (short nameindex)
127 short end = sizeof (main_table) / sizeof (struct ia64_main_table);
128 short i = (start + end) / 2;
130 if (nameindex < main_table[0].name_index
131 || nameindex > main_table[end - 1].name_index)
137 if (nameindex < main_table[i].name_index)
141 else if (nameindex == main_table[i].name_index)
143 while (i > 0 && main_table[i - 1].name_index == nameindex)
153 i = (start + end) / 2;
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. */
163 find_completer (short main_ent, short prev_completer, const char *name)
165 short name_index = find_string_ent (name);
172 if (prev_completer == -1)
174 prev_completer = main_table[main_ent].completers;
178 prev_completer = completer_table[prev_completer].subentries;
181 while (prev_completer != -1)
183 if (completer_table[prev_completer].name_index == name_index)
185 return prev_completer;
187 prev_completer = completer_table[prev_completer].alternative;
192 /* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
193 return the result. */
196 apply_completer (ia64_insn opcode, int completer_index)
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);
202 mask = mask << shiftamt;
203 bits = bits << shiftamt;
204 opcode = (opcode & ~mask) | bits;
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.) */
214 extract_op_bits (int op_pointer, int bitoffset, int bits)
218 op_pointer += (bitoffset / 8);
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;
228 res = (res << bata) | ((op & mask) >> delta);
234 res = (res << 8) | (dis_table[op_pointer++] & 255);
239 unsigned int op = (dis_table[op_pointer++] & 255);
240 res = (res << bits) | (op >> (8 - bits));
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. */
250 extract_op (int op_pointer, int *opval, unsigned int *op)
254 *op = dis_table[op_pointer];
258 opval[0] = extract_op_bits (op_pointer, oplen, 5);
261 switch ((*op) & 0x30)
265 opval[1] = extract_op_bits (op_pointer, oplen, 8);
267 opval[1] += op_pointer;
272 opval[1] = extract_op_bits (op_pointer, oplen, 16);
273 if (! (opval[1] & 32768))
275 opval[1] += op_pointer;
283 opval[2] = extract_op_bits (op_pointer, oplen, 12);
289 if (((*op) & 0x08) && (((*op) & 0x30) != 0x30))
291 opval[2] = extract_op_bits (op_pointer, oplen, 16);
293 if (! (opval[2] & 32768))
295 opval[2] += op_pointer;
301 /* Returns a non-zero value if the opcode in the main_table list at
302 PLACE matches OPCODE and is of type TYPE. */
305 opcode_verify (ia64_insn opcode, int place, enum ia64_insn_type type)
307 if (main_table[place].opcode_type != type)
311 if (main_table[place].flags
312 & (IA64_OPCODE_F2_EQ_F3 | IA64_OPCODE_LEN_EQ_64MCNT))
314 const struct ia64_operand *o1, *o2;
317 if (main_table[place].flags & IA64_OPCODE_F2_EQ_F3)
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);
328 ia64_insn len, count;
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)
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
349 locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type)
354 int currstatenum = 0;
355 short found_disent = -1;
356 short found_priority = -1;
358 currtest[currstatenum] = 0;
359 op_ptr[currstatenum] = 0;
360 bitpos[currstatenum] = 40;
364 int op_pointer = op_ptr[currstatenum];
366 int currbitnum = bitpos[currstatenum];
372 oplen = extract_op (op_pointer, opval, &op);
374 bitpos[currstatenum] = currbitnum;
376 /* Skip opval[0] bits in the instruction. */
379 currbitnum -= opval[0];
382 /* The value of the current bit being tested. */
383 currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0;
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])
392 currtest[currstatenum]++;
393 if (currbit == 0 && (op & 0x80))
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.)
400 If the state instruction matches, we go to the very
401 next state instruction; otherwise, try the next test. */
403 if ((op & 0xf8) == 0x80)
405 int count = op & 0x7;
408 for (x = 0; x <= count; x++)
411 opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0;
419 next_op = op_pointer + ((oplen + 7) / 8);
426 next_op = op_pointer + ((oplen + 7) / 8);
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))
442 /* Don't care. Skip the current bit and go to the state
443 instruction specified by opval[2].
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))
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. */
460 if ((next_op >= 0) && (next_op & 32768))
462 short disent = next_op & 32767;
470 /* Run through the list of opcodes to check, trying to find
474 int place = ia64_dis_names[disent].insn_index;
476 priority = ia64_dis_names[disent].priority;
478 if (opcode_verify (opcode, place, type)
479 && priority > found_priority)
483 if (ia64_dis_names[disent].next_flag)
495 found_disent = disent;
496 found_priority = priority;
498 /* Try the next test in this state, regardless of whether a match
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. */
510 if (currstatenum < 0)
515 else if (next_op >= 0)
518 bitpos[currstatenum] = currbitnum - 1;
519 op_ptr[currstatenum] = next_op;
520 currtest[currstatenum] = 0;
525 /* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
527 static struct ia64_opcode *
528 make_ia64_opcode (ia64_insn opcode, const char *name, int place, int depind)
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];
548 /* Determine the ia64_opcode entry for the opcode specified by INSN
549 and TYPE. If a valid entry is not found, return NULL. */
551 ia64_dis_opcode (ia64_insn insn, enum ia64_insn_type type)
553 int disent = locate_opcode_ent (insn, type);
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;
567 strcpy (name, ia64_strings [main_table[place].name_index]);
573 int cname = completer_table[ci].name_index;
575 tinsn = apply_completer (tinsn, ci);
577 if (ia64_strings[cname][0] != '\0')
580 strcat (name, ia64_strings[cname]);
584 ci = completer_table[ci].subentries;
589 ci = completer_table[ci].alternative;
597 if (tinsn != (insn & main_table[place].mask))
601 return make_ia64_opcode (insn, name, place,
602 completer_table[ci].dependencies);
606 /* Search the main_opcode table starting from PLACE for an opcode that
607 matches NAME. Return NULL if one is not found. */
609 static struct ia64_opcode *
610 ia64_find_matching_opcode (const char *name, short place)
616 if (strlen (name) > 128)
621 get_opc_prefix (&suffix, op);
622 name_index = find_string_ent (op);
628 while (main_table[place].name_index == name_index)
630 const char *curr_suffix = suffix;
631 ia64_insn curr_insn = main_table[place].opcode;
632 short completer = -1;
635 if (suffix[0] == '\0')
637 completer = find_completer (place, completer, suffix);
641 get_opc_prefix (&curr_suffix, op);
642 completer = find_completer (place, completer, op);
646 curr_insn = apply_completer (curr_insn, completer);
648 } while (completer != -1 && curr_suffix[0] != '\0');
650 if (completer != -1 && curr_suffix[0] == '\0'
651 && completer_table[completer].terminal_completer)
653 int depind = completer_table[completer].dependencies;
654 return make_ia64_opcode (curr_insn, name, place, depind);
664 /* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
665 if one does not exist.
667 It is the caller's responsibility to invoke ia64_free_opcode () to
668 release any resources used by the returned entry. */
671 ia64_find_next_opcode (struct ia64_opcode *prev_ent)
673 return ia64_find_matching_opcode (prev_ent->name,
674 prev_ent->ent_index + 1);
677 /* Find the first opcode that matches NAME, or return NULL if it does
680 It is the caller's responsibility to invoke ia64_free_opcode () to
681 release any resources used by the returned entry. */
684 ia64_find_opcode (const char *name)
691 if (strlen (name) > 128)
696 get_opc_prefix (&suffix, op);
697 name_index = find_string_ent (op);
703 place = find_main_ent (name_index);
709 return ia64_find_matching_opcode (name, place);
712 /* Free any resources used by ENT. */
714 ia64_free_opcode (struct ia64_opcode *ent)
716 free ((void *)ent->name);
720 const struct ia64_dependency *
721 ia64_find_dependency (int dep_index)
723 dep_index = DEP(dep_index);
726 || dep_index >= (int) ARRAY_SIZE (dependencies))
729 return &dependencies[dep_index];