(root)/
binutils-2.41/
opcodes/
ia64-opc.c
       1  /* ia64-opc.c -- Functions to access the compacted opcode table
       2     Copyright (C) 1999-2023 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 "sysdep.h"
      23  #include "libiberty.h"
      24  #include "ia64-asmtab.h"
      25  #include "ia64-asmtab.c"
      26  
      27  static void get_opc_prefix (const char **, char *);
      28  static short int find_string_ent (const char *);
      29  static short int find_main_ent (short int);
      30  static short int find_completer (short int, short int, const char *);
      31  static ia64_insn apply_completer (ia64_insn, int);
      32  static int extract_op_bits (int, int, int);
      33  static int extract_op (int, int *, unsigned int *);
      34  static int opcode_verify (ia64_insn, int, enum ia64_insn_type);
      35  static int locate_opcode_ent (ia64_insn, enum ia64_insn_type);
      36  static struct ia64_opcode *make_ia64_opcode
      37    (ia64_insn, const char *, int, int);
      38  static struct ia64_opcode *ia64_find_matching_opcode
      39    (const char *, short int);
      40  
      41  const 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  
      66  static void
      67  get_opc_prefix (const char **ptr, char *dest)
      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  
      85  /* Find the index of the entry in the string table corresponding to
      86     STR; return -1 if one does not exist. */
      87  
      88  static short
      89  find_string_ent (const char *str)
      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  
     119  /* Find the opcode in the main opcode table whose name is STRINGINDEX, or
     120     return -1 if one does not exist. */
     121  
     122  static short
     123  find_main_ent (short nameindex)
     124  {
     125    short start = 0;
     126    short end = ARRAY_SIZE (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  
     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  
     161  static short
     162  find_completer (short main_ent, short prev_completer, const char *name)
     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  
     191  /* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
     192     return the result. */
     193  
     194  static ia64_insn
     195  apply_completer (ia64_insn opcode, int completer_index)
     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  
     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  
     212  static int
     213  extract_op_bits (int op_pointer, int bitoffset, int bits)
     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  
     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  
     248  static int
     249  extract_op (int op_pointer, int *opval, unsigned int *op)
     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  
     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  
     303  static int
     304  opcode_verify (ia64_insn opcode, int place, enum ia64_insn_type type)
     305  {
     306    if (main_table[place].opcode_type != type)
     307      {
     308        return 0;
     309      }
     310    if (main_table[place].flags
     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  
     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
     344     not be found.  Checks all matches and returns the one with the highest
     345     priority. */
     346  
     347  static int
     348  locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type)
     349  {
     350    int currtest[41];
     351    int bitpos[41];
     352    int op_ptr[41];
     353    int currstatenum = 0;
     354    short found_disent = -1;
     355    short found_priority = -1;
     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;
     367        int opval[3] = {0};
     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        if (currbitnum < 0)
     382  	currbitnum = 0;
     383  
     384        /* The value of the current bit being tested.  */
     385        currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0;
     386        next_op = -1;
     387  
     388        /* We always perform the tests specified in the current state in
     389  	 a particular order, falling through to the next test if the
     390  	 previous one failed. */
     391        switch (currtest[currstatenum])
     392  	{
     393  	case 0:
     394  	  currtest[currstatenum]++;
     395  	  if (currbit == 0 && (op & 0x80))
     396  	    {
     397  	      /* Check for a zero bit.  If this test solely checks for
     398  		 a zero bit, we can check for up to 8 consecutive zero
     399  		 bits (the number to check is specified by the lower 3
     400  		 bits in the state code.)
     401  
     402  		 If the state instruction matches, we go to the very
     403  		 next state instruction; otherwise, try the next test. */
     404  
     405  	      if ((op & 0xf8) == 0x80)
     406  		{
     407  		  int count = op & 0x7;
     408  		  int x;
     409  
     410  		  for (x = 0; x <= count; x++)
     411  		    {
     412  		      int i =
     413  			opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0;
     414  		      if (i)
     415  			{
     416  			  break;
     417  			}
     418  		    }
     419  		  if (x > count)
     420  		    {
     421  		      next_op = op_pointer + ((oplen + 7) / 8);
     422  		      currbitnum -= count;
     423  		      break;
     424  		    }
     425  		}
     426  	      else if (! currbit)
     427  		{
     428  		  next_op = op_pointer + ((oplen + 7) / 8);
     429  		  break;
     430  		}
     431  	    }
     432  	  /* FALLTHROUGH */
     433  	case 1:
     434  	  /* If the bit in the instruction is one, go to the state
     435  	     instruction specified by opval[1]. */
     436  	  currtest[currstatenum]++;
     437  	  if (currbit && (op & 0x30) != 0 && ((op & 0x30) != 0x30))
     438  	    {
     439  	      next_op = opval[1];
     440  	      break;
     441  	    }
     442  	  /* FALLTHROUGH */
     443  	case 2:
     444  	  /* Don't care.  Skip the current bit and go to the state
     445  	     instruction specified by opval[2].
     446  
     447  	     An encoding of 0x30 is special; this means that a 12-bit
     448  	     offset into the ia64_dis_names[] array is specified.  */
     449  	  currtest[currstatenum]++;
     450  	  if ((op & 0x08) || ((op & 0x30) == 0x30))
     451  	    {
     452  	      next_op = opval[2];
     453  	      break;
     454  	    }
     455  	}
     456  
     457        /* If bit 15 is set in the address of the next state, an offset
     458  	 in the ia64_dis_names array was specified instead.  We then
     459  	 check to see if an entry in the list of opcodes matches the
     460  	 opcode we were given; if so, we have succeeded.  */
     461  
     462        if ((next_op >= 0) && (next_op & 32768))
     463  	{
     464  	  short disent = next_op & 32767;
     465            short priority = -1;
     466  
     467  	  if (next_op > 65535)
     468  	    {
     469  	      return -1;
     470  	    }
     471  
     472  	  /* Run through the list of opcodes to check, trying to find
     473  	     one that matches.  */
     474  	  while (disent >= 0)
     475  	    {
     476  	      int place = ia64_dis_names[disent].insn_index;
     477  
     478                priority = ia64_dis_names[disent].priority;
     479  
     480  	      if (opcode_verify (opcode, place, type)
     481                    && priority > found_priority)
     482  		{
     483  		  break;
     484  		}
     485  	      if (ia64_dis_names[disent].next_flag)
     486  		{
     487  		  disent++;
     488  		}
     489  	      else
     490  		{
     491  		  disent = -1;
     492  		}
     493  	    }
     494  
     495  	  if (disent >= 0)
     496  	    {
     497                found_disent = disent;
     498                found_priority = priority;
     499  	    }
     500            /* Try the next test in this state, regardless of whether a match
     501               was found. */
     502            next_op = -2;
     503  	}
     504  
     505        /* next_op == -1 is "back up to the previous state".
     506  	 next_op == -2 is "stay in this state and try the next test".
     507  	 Otherwise, transition to the state indicated by next_op. */
     508  
     509        if (next_op == -1)
     510  	{
     511  	  currstatenum--;
     512  	  if (currstatenum < 0)
     513  	    {
     514                return found_disent;
     515  	    }
     516  	}
     517        else if (next_op >= 0)
     518  	{
     519  	  currstatenum++;
     520  	  bitpos[currstatenum] = currbitnum - 1;
     521  	  op_ptr[currstatenum] = next_op;
     522  	  currtest[currstatenum] = 0;
     523  	}
     524      }
     525  }
     526  
     527  /* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
     528  
     529  static struct ia64_opcode *
     530  make_ia64_opcode (ia64_insn opcode, const char *name, int place, int depind)
     531  {
     532    struct ia64_opcode *res =
     533      (struct ia64_opcode *) xmalloc (sizeof (struct ia64_opcode));
     534    res->name = xstrdup (name);
     535    res->type = main_table[place].opcode_type;
     536    res->num_outputs = main_table[place].num_outputs;
     537    res->opcode = opcode;
     538    res->mask = main_table[place].mask;
     539    res->operands[0] = main_table[place].operands[0];
     540    res->operands[1] = main_table[place].operands[1];
     541    res->operands[2] = main_table[place].operands[2];
     542    res->operands[3] = main_table[place].operands[3];
     543    res->operands[4] = main_table[place].operands[4];
     544    res->flags = main_table[place].flags;
     545    res->ent_index = place;
     546    res->dependencies = &op_dependencies[depind];
     547    return res;
     548  }
     549  
     550  /* Determine the ia64_opcode entry for the opcode specified by INSN
     551     and TYPE.  If a valid entry is not found, return NULL. */
     552  struct ia64_opcode *
     553  ia64_dis_opcode (ia64_insn insn, enum ia64_insn_type type)
     554  {
     555    int disent = locate_opcode_ent (insn, type);
     556  
     557    if (disent < 0)
     558      {
     559        return NULL;
     560      }
     561    else
     562      {
     563        unsigned int cb = ia64_dis_names[disent].completer_index;
     564        static char name[128];
     565        int place = ia64_dis_names[disent].insn_index;
     566        int ci = main_table[place].completers;
     567        ia64_insn tinsn = main_table[place].opcode;
     568  
     569        strcpy (name, ia64_strings [main_table[place].name_index]);
     570  
     571        while (cb)
     572  	{
     573  	  if (cb & 1)
     574  	    {
     575  	      int cname = completer_table[ci].name_index;
     576  
     577  	      tinsn = apply_completer (tinsn, ci);
     578  
     579  	      if (ia64_strings[cname][0] != '\0')
     580  		{
     581  		  strcat (name, ".");
     582  		  strcat (name, ia64_strings[cname]);
     583  		}
     584  	      if (cb != 1)
     585  		{
     586  		  ci = completer_table[ci].subentries;
     587  		}
     588  	    }
     589  	  else
     590  	    {
     591  	      ci = completer_table[ci].alternative;
     592  	    }
     593  	  if (ci < 0)
     594  	    {
     595  	      abort ();
     596  	    }
     597  	  cb = cb >> 1;
     598  	}
     599        if (tinsn != (insn & main_table[place].mask))
     600  	{
     601  	  abort ();
     602  	}
     603        return make_ia64_opcode (insn, name, place,
     604                                 completer_table[ci].dependencies);
     605      }
     606  }
     607  
     608  /* Search the main_opcode table starting from PLACE for an opcode that
     609     matches NAME.  Return NULL if one is not found. */
     610  
     611  static struct ia64_opcode *
     612  ia64_find_matching_opcode (const char *name, short place)
     613  {
     614    char op[129];
     615    const char *suffix;
     616    short name_index;
     617  
     618    if ((unsigned) place >= ARRAY_SIZE (main_table))
     619      return NULL;
     620  
     621    if (strlen (name) > 128)
     622      {
     623        return NULL;
     624      }
     625    suffix = name;
     626    get_opc_prefix (&suffix, op);
     627    name_index = find_string_ent (op);
     628    if (name_index < 0)
     629      {
     630        return NULL;
     631      }
     632  
     633    while (main_table[place].name_index == name_index)
     634      {
     635        const char *curr_suffix = suffix;
     636        ia64_insn curr_insn = main_table[place].opcode;
     637        short completer = -1;
     638  
     639        do {
     640  	if (suffix[0] == '\0')
     641  	  {
     642  	    completer = find_completer (place, completer, suffix);
     643  	  }
     644  	else
     645  	  {
     646  	    get_opc_prefix (&curr_suffix, op);
     647  	    completer = find_completer (place, completer, op);
     648  	  }
     649  	if (completer != -1)
     650  	  {
     651  	    curr_insn = apply_completer (curr_insn, completer);
     652  	  }
     653        } while (completer != -1 && curr_suffix[0] != '\0');
     654  
     655        if (completer != -1 && curr_suffix[0] == '\0'
     656  	  && completer_table[completer].terminal_completer)
     657  	{
     658            int depind = completer_table[completer].dependencies;
     659  	  return make_ia64_opcode (curr_insn, name, place, depind);
     660  	}
     661        else
     662  	{
     663  	  place++;
     664  	}
     665      }
     666    return NULL;
     667  }
     668  
     669  /* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
     670     if one does not exist.
     671  
     672     It is the caller's responsibility to invoke ia64_free_opcode () to
     673     release any resources used by the returned entry. */
     674  
     675  struct ia64_opcode *
     676  ia64_find_next_opcode (struct ia64_opcode *prev_ent)
     677  {
     678    return ia64_find_matching_opcode (prev_ent->name,
     679  				    prev_ent->ent_index + 1);
     680  }
     681  
     682  /* Find the first opcode that matches NAME, or return NULL if it does
     683     not exist.
     684  
     685     It is the caller's responsibility to invoke ia64_free_opcode () to
     686     release any resources used by the returned entry. */
     687  
     688  struct ia64_opcode *
     689  ia64_find_opcode (const char *name)
     690  {
     691    char op[129];
     692    const char *suffix;
     693    short place;
     694    short name_index;
     695  
     696    if (strlen (name) > 128)
     697      {
     698        return NULL;
     699      }
     700    suffix = name;
     701    get_opc_prefix (&suffix, op);
     702    name_index = find_string_ent (op);
     703    if (name_index < 0)
     704      {
     705        return NULL;
     706      }
     707  
     708    place = find_main_ent (name_index);
     709  
     710    if (place < 0)
     711      {
     712        return NULL;
     713      }
     714    return ia64_find_matching_opcode (name, place);
     715  }
     716  
     717  /* Free any resources used by ENT. */
     718  void
     719  ia64_free_opcode (struct ia64_opcode *ent)
     720  {
     721    free ((void *)ent->name);
     722    free (ent);
     723  }
     724  
     725  const struct ia64_dependency *
     726  ia64_find_dependency (int dep_index)
     727  {
     728    dep_index = DEP(dep_index);
     729  
     730    if (dep_index < 0
     731        || dep_index >= (int) ARRAY_SIZE (dependencies))
     732      return NULL;
     733  
     734    return &dependencies[dep_index];
     735  }