/* ia64-opc.c -- Functions to access the compacted opcode table
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
This file is part of GDB, GAS, and the GNU binutils.
#include "ia64-asmtab.h"
#include "ia64-asmtab.c"
+static void get_opc_prefix PARAMS ((const char **, char *));
+static short int find_string_ent PARAMS ((const char *));
+static short int find_main_ent PARAMS ((short int));
+static short int find_completer PARAMS ((short int, short int, const char *));
+static ia64_insn apply_completer PARAMS ((ia64_insn, int));
+static int extract_op_bits PARAMS ((int, int, int));
+static int extract_op PARAMS ((int, int *, unsigned int *));
+static int opcode_verify PARAMS ((ia64_insn, int, enum ia64_insn_type));
+static int locate_opcode_ent PARAMS ((ia64_insn, enum ia64_insn_type));
+static struct ia64_opcode *make_ia64_opcode
+ PARAMS ((ia64_insn, const char *, int, int));
+static struct ia64_opcode *ia64_find_matching_opcode
+ PARAMS ((const char *, short int));
+
const struct ia64_templ_desc ia64_templ_desc[16] =
{
{ 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" }, /* 0 */
MAIN_ENT (starting from PREV_COMPLETER) that matches NAME, or
return -1 if one does not exist. */
-static short
+static short
find_completer (main_ent, prev_completer, name)
short main_ent;
short prev_completer;
{
return 0;
}
- if (main_table[place].flags
+ if (main_table[place].flags
& (IA64_OPCODE_F2_EQ_F3 | IA64_OPCODE_LEN_EQ_64MCNT))
{
const struct ia64_operand *o1, *o2;
/* Find an instruction entry in the ia64_dis_names array that matches
opcode OPCODE and is of type TYPE. Returns either a positive index
into the array, or a negative value if an entry for OPCODE could
- not be found. */
+ not be found. Checks all matches and returns the one with the highest
+ priority. */
static int
locate_opcode_ent (opcode, type)
int bitpos[41];
int op_ptr[41];
int currstatenum = 0;
+ short found_disent = -1;
+ short found_priority = -1;
currtest[currstatenum] = 0;
op_ptr[currstatenum] = 0;
if ((next_op >= 0) && (next_op & 32768))
{
short disent = next_op & 32767;
+ short priority = -1;
if (next_op > 65535)
{
{
int place = ia64_dis_names[disent].insn_index;
- if (opcode_verify (opcode, place, type))
+ priority = ia64_dis_names[disent].priority;
+
+ if (opcode_verify (opcode, place, type)
+ && priority > found_priority)
{
break;
}
if (disent >= 0)
{
- return disent;
- }
- else
- {
- /* Failed to match; try the next test in this state. */
- next_op = -2;
+ found_disent = disent;
+ found_priority = priority;
}
+ /* Try the next test in this state, regardless of whether a match
+ was found. */
+ next_op = -2;
}
/* next_op == -1 is "back up to the previous state".
currstatenum--;
if (currstatenum < 0)
{
- return -1;
+ return found_disent;
}
}
else if (next_op >= 0)
{
abort ();
}
- return make_ia64_opcode (insn, name, place,
+ return make_ia64_opcode (insn, name, place,
completer_table[ci].dependencies);
}
}
short completer = -1;
do {
- if (suffix[0] == '\0')
+ if (suffix[0] == '\0')
{
completer = find_completer (place, completer, suffix);
}
{
index = DEP(index);
- if (index < 0 || index >= sizeof(dependencies) / sizeof(dependencies[0]))
+ if (index < 0
+ || index >= (int)(sizeof(dependencies) / sizeof(dependencies[0])))
return NULL;
return &dependencies[index];