]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/itbl-ops.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / itbl-ops.c
index a100dbc7f97c33d9f0c115a42d75b32cce608a9d..b0746f01c094f38730f534992cfcc49106415dbf 100644 (file)
@@ -1,11 +1,11 @@
 /* itbl-ops.c
-   Copyright (C) 1997  Free Software Foundation, Inc.
+   Copyright (C) 1997-2021 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
@@ -15,8 +15,8 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 /*======================================================================*/
 /*
  *
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include "as.h"
 #include "itbl-ops.h"
-#include "itbl-parse.h"
+#include <itbl-parse.h>
 
-#define DEBUG
+/* #define DEBUG */
 
 #ifdef DEBUG
 #include <assert.h>
-#define ASSERT(x) assert(x)
+#define ASSERT(x) gas_assert (x)
 #define DBG(x) printf x
 #else
 #define ASSERT(x)
@@ -114,94 +112,80 @@ int itbl_have_entries = 0;
 /*======================================================================*/
 /* structures for keeping itbl format entries */
 
-struct itbl_range
-  {
-    int sbit;                  /* mask starting bit position */
-    int ebit;                  /* mask ending bit position */
-  };
-
-struct itbl_field
-  {
-    e_type type;               /* dreg/creg/greg/immed/symb */
-    struct itbl_range range;   /* field's bitfield range within instruction */
-    unsigned long flags;       /* field flags */
-    struct itbl_field *next;   /* next field in list */
-  };
+struct itbl_range {
+  int sbit;                    /* mask starting bit position */
+  int ebit;                    /* mask ending bit position */
+};
 
+struct itbl_field {
+  e_type type;                 /* dreg/creg/greg/immed/symb */
+  struct itbl_range range;     /* field's bitfield range within instruction */
+  unsigned long flags;         /* field flags */
+  struct itbl_field *next;     /* next field in list */
+};
 
 /* These structures define the instructions and registers for a processor.
  * If the type is an instruction, the structure defines the format of an
  * instruction where the fields are the list of operands.
  * The flags field below uses the same values as those defined in the
- * gnu assembler and are machine specific. */
-struct itbl_entry
-  {
-    e_processor processor;     /* processor number */
-    e_type type;               /* dreg/creg/greg/insn */
-    char *name;                        /* mnemionic name for insn/register */
-    unsigned long value;       /* opcode/instruction mask/register number */
-    unsigned long flags;       /* effects of the instruction */
-    struct itbl_range range;   /* bit range within instruction for value */
-    struct itbl_field *fields; /* list of operand definitions (if any) */
-    struct itbl_entry *next;   /* next entry */
-  };
-
+ * gnu assembler and are machine specific.  */
+struct itbl_entry {
+  e_processor processor;       /* processor number */
+  e_type type;                 /* dreg/creg/greg/insn */
+  char *name;                  /* mnemonic name for insn/register */
+  unsigned long value;         /* opcode/instruction mask/register number */
+  unsigned long flags;         /* effects of the instruction */
+  struct itbl_range range;     /* bit range within instruction for value */
+  struct itbl_field *fields;   /* list of operand definitions (if any) */
+  struct itbl_entry *next;     /* next entry */
+};
 
 /* local data and structures */
 
 static int itbl_num_opcodes = 0;
 /* Array of entries for each processor and entry type */
-static struct itbl_entry *entries[e_nprocs][e_ntypes] =
-{
-  {0, 0, 0, 0, 0, 0},
-  {0, 0, 0, 0, 0, 0},
-  {0, 0, 0, 0, 0, 0},
-  {0, 0, 0, 0, 0, 0}
-};
+static struct itbl_entry *entries[e_nprocs][e_ntypes];
 
 /* local prototypes */
-static unsigned long build_opcode PARAMS ((struct itbl_entry *e));
-static e_type get_type PARAMS ((int yytype));
-static e_processor get_processor PARAMS ((int yyproc));
-static struct itbl_entry **get_entries PARAMS ((e_processor processor, 
-                                               e_type type));
-static struct itbl_entry *find_entry_byname PARAMS ((e_processor processor, 
-                                       e_type type, char *name));
-static struct itbl_entry *find_entry_byval PARAMS ((e_processor processor, 
-                       e_type type, unsigned long val, struct itbl_range *r));
-static struct itbl_entry *alloc_entry PARAMS ((e_processor processor, 
-               e_type type, char *name, unsigned long value));
-static unsigned long apply_range PARAMS ((unsigned long value, 
-                                               struct itbl_range r));
-static unsigned long extract_range PARAMS ((unsigned long value, 
-                                               struct itbl_range r));
-static struct itbl_field *alloc_field PARAMS ((e_type type, int sbit, 
-                                       int ebit, unsigned long flags));
-
+static unsigned long build_opcode (struct itbl_entry *e);
+static e_type get_type (int yytype);
+static e_processor get_processor (int yyproc);
+static struct itbl_entry **get_entries (e_processor processor,
+                                       e_type type);
+static struct itbl_entry *find_entry_byname (e_processor processor,
+                                       e_type type, char *name);
+static struct itbl_entry *find_entry_byval (e_processor processor,
+                       e_type type, unsigned long val, struct itbl_range *r);
+static struct itbl_entry *alloc_entry (e_processor processor,
+               e_type type, char *name, unsigned long value);
+static unsigned long apply_range (unsigned long value, struct itbl_range r);
+static unsigned long extract_range (unsigned long value, struct itbl_range r);
+static struct itbl_field *alloc_field (e_type type, int sbit,
+                                       int ebit, unsigned long flags);
 
 /*======================================================================*/
 /* Interfaces to the parser */
 
-
 /* Open the table and use lex and yacc to parse the entries.
  * Return 1 for failure; 0 for success.  */
 
-int 
+int
 itbl_parse (char *insntbl)
 {
   extern FILE *yyin;
   extern int yyparse (void);
-  yyin = fopen (insntbl, "r");
+
+  yyin = fopen (insntbl, FOPEN_RT);
   if (yyin == 0)
     {
       printf ("Can't open processor instruction specification file \"%s\"\n",
              insntbl);
       return 1;
     }
-  else
-    {
-      while (yyparse ());
-    }
+
+  while (yyparse ())
+    ;
+
   fclose (yyin);
   itbl_have_entries = 1;
   return 0;
@@ -213,18 +197,6 @@ struct itbl_entry *
 itbl_add_reg (int yyprocessor, int yytype, char *regname,
              int regnum)
 {
-#if 0                          
-#include "as.h"
-#include "symbols.h"
-  /* Since register names don't have a prefix, we put them in the symbol table so
-     they can't be used as symbols.  This also simplifies argument parsing as
-     we can let gas parse registers for us.  The recorded register number is
-     regnum.  */
-  /* Use symbol_create here instead of symbol_new so we don't try to
-     output registers into the object file's symbol table.  */
-  symbol_table_insert (symbol_create (regname, reg_section,
-                                     regnum, &zero_address_frag));
-#endif
   return alloc_entry (get_processor (yyprocessor), get_type (yytype), regname,
                      (unsigned long) regnum);
 }
@@ -256,7 +228,7 @@ itbl_add_operand (struct itbl_entry *e, int yytype, int sbit,
   struct itbl_field *f, **last_f;
   if (!e)
     return 0;
-  /* Add to end of fields' list. */
+  /* Add to end of fields' list.  */
   f = alloc_field (get_type (yytype), sbit, ebit, flags);
   if (f)
     {
@@ -269,26 +241,27 @@ itbl_add_operand (struct itbl_entry *e, int yytype, int sbit,
   return f;
 }
 
-
 /*======================================================================*/
 /* Interfaces for assembler and disassembler */
 
 #ifndef STAND_ALONE
-#include "as.h"
-#include "symbols.h"
 static void append_insns_as_macros (void);
 
-/* initialize for gas */
-void 
+/* Initialize for gas.  */
+
+void
 itbl_init (void)
 {
   struct itbl_entry *e, **es;
   e_processor procn;
   e_type type;
 
+  if (!itbl_have_entries)
+    return;
+
   /* Since register names don't have a prefix, put them in the symbol table so
      they can't be used as symbols.  This simplifies argument parsing as
-     we can let gas parse registers for us. */
+     we can let gas parse registers for us.  */
   /* Use symbol_create instead of symbol_new so we don't try to
      output registers into the object file's symbol table.  */
 
@@ -299,22 +272,21 @@ itbl_init (void)
        for (e = *es; e; e = e->next)
          {
            symbol_table_insert (symbol_create (e->name, reg_section,
-                                            e->value, &zero_address_frag));
+                                               &zero_address_frag, e->value));
          }
       }
   append_insns_as_macros ();
 }
 
-
-/* Append insns to opcodes table and increase number of opcodes 
- * Structure of opcodes table: 
+/* Append insns to opcodes table and increase number of opcodes
+ * Structure of opcodes table:
  * struct itbl_opcode
  * {
  *   const char *name;
- *   const char *args;                 - string describing the arguments.  
- *   unsigned long match;      - opcode, or ISA level if pinfo=INSN_MACRO 
- *   unsigned long mask;       - opcode mask, or macro id if pinfo=INSN_MACRO 
- *   unsigned long pinfo;      - insn flags, or INSN_MACRO 
+ *   const char *args;                 - string describing the arguments.
+ *   unsigned long match;      - opcode, or ISA level if pinfo=INSN_MACRO
+ *   unsigned long mask;       - opcode mask, or macro id if pinfo=INSN_MACRO
+ *   unsigned long pinfo;      - insn flags, or INSN_MACRO
  * };
  * examples:
  *     {"li",      "t,i",  0x34000000, 0xffe00000, WR_t    },
@@ -322,12 +294,18 @@ itbl_init (void)
  */
 
 static char *form_args (struct itbl_entry *e);
-static void 
+static void
 append_insns_as_macros (void)
 {
   struct ITBL_OPCODE_STRUCT *new_opcodes, *o;
   struct itbl_entry *e, **es;
-  int n, id, size, new_size, new_num_opcodes;
+  int n, size, new_num_opcodes;
+#ifdef USE_MACROS
+  int id;
+#endif
+
+  if (!itbl_have_entries)
+    return;
 
   if (!itbl_num_opcodes)       /* no new instructions to add! */
     {
@@ -342,24 +320,23 @@ append_insns_as_macros (void)
   ASSERT (size >= 0);
   DBG (("I get=%d\n", size / sizeof (ITBL_OPCODES[0])));
 
-  new_size = sizeof (struct ITBL_OPCODE_STRUCT) * new_num_opcodes;
-  ASSERT (new_size > size);
-
-  /* FIXME since ITBL_OPCODES culd be a static table,
-               we can't realloc or delete the old memory. */
-  new_opcodes = (struct ITBL_OPCODE_STRUCT *) malloc (new_size);
+  /* FIXME since ITBL_OPCODES could be a static table,
+               we can't realloc or delete the old memory.  */
+  new_opcodes = XNEWVEC (struct ITBL_OPCODE_STRUCT, new_num_opcodes);
   if (!new_opcodes)
     {
-      printf ("Unable to allocate memory for new instructions\n");
+      printf (_("Unable to allocate memory for new instructions\n"));
       return;
     }
-  if (size)                    /* copy prexisting opcodes table */
+  if (size)                    /* copy preexisting opcodes table */
     memcpy (new_opcodes, ITBL_OPCODES, size);
 
   /* FIXME! some NUMOPCODES are calculated expressions.
-               These need to be changed before itbls can be supported. */
+               These need to be changed before itbls can be supported.  */
 
+#ifdef USE_MACROS
   id = ITBL_NUM_MACROS;                /* begin the next macro id after the last */
+#endif
   o = &new_opcodes[ITBL_NUM_OPCODES];  /* append macro to opcodes list */
   for (n = e_p0; n < e_nprocs; n++)
     {
@@ -374,13 +351,13 @@ append_insns_as_macros (void)
          o->name = e->name;
          o->args = strdup (form_args (e));
          o->mask = apply_range (e->value, e->range);
-         /* FIXME how to catch durring assembly? */
+         /* FIXME how to catch during assembly? */
          /* mask to identify this insn */
          o->match = apply_range (e->value, e->range);
          o->pinfo = 0;
 
 #ifdef USE_MACROS
-         o->mask = id++;       /* FIXME how to catch durring assembly? */
+         o->mask = id++;       /* FIXME how to catch during assembly? */
          o->match = 0;         /* for macros, the insn_isa number */
          o->pinfo = INSN_MACRO;
 #endif
@@ -401,7 +378,7 @@ append_insns_as_macros (void)
                Don't free name though, since name is being used by the new
                opcodes table.
 
-               Eventually, we should also free the new opcodes table itself 
+               Eventually, we should also free the new opcodes table itself
                on exit.
        */
 }
@@ -448,21 +425,22 @@ form_args (struct itbl_entry *e)
 }
 #endif /* !STAND_ALONE */
 
-
 /* Get processor's register name from val */
 
-unsigned long 
-itbl_get_reg_val (char *name)
+int
+itbl_get_reg_val (char *name, unsigned long *pval)
 {
   e_type t;
   e_processor p;
-  int r = 0;
+
   for (p = e_p0; p < e_nprocs; p++)
-    for (t = e_regtype0; t < e_nregtypes; t++)
-      {
-       if (r = itbl_get_val (p, t, name), r)
-         return r;
-      }
+    {
+      for (t = e_regtype0; t < e_nregtypes; t++)
+       {
+         if (itbl_get_val (p, t, name, pval))
+           return 1;
+       }
+    }
   return 0;
 }
 
@@ -480,35 +458,35 @@ itbl_get_name (e_processor processor, e_type type, unsigned long val)
 
 /* Get processor's register value from name */
 
-unsigned long 
-itbl_get_val (e_processor processor, e_type type, char *name)
+int
+itbl_get_val (e_processor processor, e_type type, char *name,
+             unsigned long *pval)
 {
   struct itbl_entry *r;
   /* type depends on instruction passed */
   r = find_entry_byname (processor, type, name);
-  if (r)
-    return r->value;
-  else
-    return 0;                  /* error; invalid operand */
+  if (r == NULL)
+    return 0;
+  *pval = r->value;
+  return 1;
 }
 
-
 /* Assemble instruction "name" with operands "s".
  * name - name of instruction
  * s - operands
  * returns - long word for assembled instruction */
 
-unsigned long 
+unsigned long
 itbl_assemble (char *name, char *s)
 {
   unsigned long opcode;
-  struct itbl_entry *e;
+  struct itbl_entry *e = NULL;
   struct itbl_field *f;
   char *n;
   int processor;
 
   if (!name || !*name)
-    return 0;                  /* error!  must have a opcode name/expr */
+    return 0;                  /* error!  must have an opcode name/expr */
 
   /* find entry in list of instructions for all processors */
   for (processor = 0; processor < e_nprocs; processor++)
@@ -518,11 +496,11 @@ itbl_assemble (char *name, char *s)
        break;
     }
   if (!e)
-    return 0;                  /* opcode not in table; invalid instrustion */
+    return 0;                  /* opcode not in table; invalid instruction */
   opcode = build_opcode (e);
 
   /* parse opcode's args (if any) */
-  for (f = e->fields; f; f = f->next)  /* for each arg, ... */
+  for (f = e->fields; f; f = f->next)  /* for each arg, ...  */
     {
       struct itbl_entry *r;
       unsigned long value;
@@ -562,9 +540,9 @@ itbl_assemble (char *name, char *s)
                                return 0;       /-* error; invalid operand *-/
                                break;
                        */
-         /* If not a symbol, fall thru to IMMED */
+         /* If not a symbol, fallthru to IMMED */
        case e_immed:
-         if (*n == '0' && *(n + 1) == 'x')     /* hex begins 0x... */
+         if (*n == '0' && *(n + 1) == 'x')     /* hex begins 0x...  */
            {
              n += 2;
              value = strtol (n, 0, 16);
@@ -594,7 +572,7 @@ itbl_assemble (char *name, char *s)
  * returns - 1 if succeeded; 0 if failed
  */
 
-int 
+int
 itbl_disassemble (char *s, unsigned long insn)
 {
   e_processor processor;
@@ -602,24 +580,25 @@ itbl_disassemble (char *s, unsigned long insn)
   struct itbl_field *f;
 
   if (!ITBL_IS_INSN (insn))
-    return 0;                  /* error*/
+    return 0;                  /* error */
   processor = get_processor (ITBL_DECODE_PNUM (insn));
 
   /* find entry in list */
   e = find_entry_byval (processor, e_insn, insn, 0);
   if (!e)
-    return 0;                  /* opcode not in table; invalid instrustion */
+    return 0;                  /* opcode not in table; invalid instruction */
   strcpy (s, e->name);
 
-  /* parse insn's args (if any) */
-  for (f = e->fields; f; f = f->next)  /* for each arg, ... */
+  /* Parse insn's args (if any).  */
+  for (f = e->fields; f; f = f->next)  /* for each arg, ...  */
     {
       struct itbl_entry *r;
       unsigned long value;
+      char s_value[20];
 
-      if (f == e->fields)      /* first operand is preceeded by tab */
+      if (f == e->fields)      /* First operand is preceded by tab.  */
        strcat (s, "\t");
-      else                     /* ','s separate following operands */
+      else                     /* ','s separate following operands */
        strcat (s, ",");
       value = extract_range (insn, f->range);
       /* n should be in form $n or 0xhhh (are symbol names valid?? */
@@ -629,27 +608,29 @@ itbl_disassemble (char *s, unsigned long insn)
        case e_creg:
        case e_greg:
          /* Accept either a string name
-                        * or '$' followed by the register number */
+            or '$' followed by the register number.  */
          r = find_entry_byval (e->processor, f->type, value, &f->range);
          if (r)
            strcat (s, r->name);
          else
-           sprintf (s, "%s$%d", s, value);
+           {
+             sprintf (s_value, "$%lu", value);
+             strcat (s, s_value);
+           }
          break;
        case e_addr:
-         /* use assembler's symbol table to find symbol */
-         /* FIXME!! Do we need this?
-                        *   if so, what about relocs??
-                       */
-         /* If not a symbol, fall thru to IMMED */
+         /* Use assembler's symbol table to find symbol.  */
+         /* FIXME!! Do we need this?  If so, what about relocs??  */
+         /* If not a symbol, fall through to IMMED.  */
        case e_immed:
-         sprintf (s, "%s0x%x", s, value);
+         sprintf (s_value, "0x%lx", value);
+         strcat (s, s_value);
          break;
        default:
          return 0;             /* error; invalid field spec */
        }
     }
-  return 1;                    /* done! */
+  return 1;                    /* Done!  */
 }
 
 /*======================================================================*/
@@ -661,7 +642,7 @@ itbl_disassemble (char *s, unsigned long insn)
 
 /* Calculate instruction's opcode and function values from entry */
 
-static unsigned long 
+static unsigned long
 build_opcode (struct itbl_entry *e)
 {
   unsigned long opcode;
@@ -682,7 +663,7 @@ build_opcode (struct itbl_entry *e)
  * mask: 0x01f00000.
  */
 
-static unsigned long 
+static unsigned long
 apply_range (unsigned long rval, struct itbl_range r)
 {
   unsigned long mask;
@@ -706,7 +687,7 @@ apply_range (unsigned long rval, struct itbl_range r)
 /* Calculate relative value given the absolute value and bit position range
  * within the instruction.  */
 
-static unsigned long 
+static unsigned long
 extract_range (unsigned long aval, struct itbl_range r)
 {
   unsigned long mask;
@@ -726,28 +707,20 @@ extract_range (unsigned long aval, struct itbl_range r)
 /* Extract processor's assembly instruction field name from s;
  * forms are "n args" "n,args" or "n" */
 /* Return next argument from string pointer "s" and advance s.
- * delimiters are " ,\0" */
+ * delimiters are " ,()" */
 
 char *
 itbl_get_field (char **S)
 {
   static char n[128];
-  char *p, *ps, *s;
+  char *s;
   int len;
 
   s = *S;
   if (!s || !*s)
     return 0;
-  p = s + strlen (s);
-  if (ps = strchr (s, ','), ps)
-    p = ps;
-  if (ps = strchr (s, ' '), ps)
-    p = min (p, ps);
-  if (ps = strchr (s, '\0'), ps)
-    p = min (p, ps);
-  if (p == 0)
-    return 0;                  /* error! */
-  len = p - s;
+  /* FIXME: This is a weird set of delimiters.  */
+  len = strcspn (s, " \t,()");
   ASSERT (128 > len + 1);
   strncpy (n, s, len);
   n[len] = 0;
@@ -771,7 +744,7 @@ find_entry_byname (e_processor processor,
   struct itbl_entry *e, **es;
 
   es = get_entries (processor, type);
-  for (e = *es; e; e = e->next)        /* for each entry, ... */
+  for (e = *es; e; e = e->next)        /* for each entry, ...  */
     {
       if (!strcmp (e->name, n))
        return e;
@@ -793,7 +766,7 @@ find_entry_byval (e_processor processor, e_type type,
   unsigned long eval;
 
   es = get_entries (processor, type);
-  for (e = *es; e; e = e->next)        /* for each entry, ... */
+  for (e = *es; e; e = e->next)        /* for each entry, ...  */
     {
       if (processor != e->processor)
        continue;
@@ -803,15 +776,15 @@ find_entry_byval (e_processor processor, e_type type,
         * This could cause ambiguities.
         * For operands, we get an extracted value and a range.
         */
-      /* if range is 0, mask val against the range of the compared entry. */
+      /* if range is 0, mask val against the range of the compared entry.  */
       if (r == 0)              /* if no range passed, must be whole 32-bits
                         * so create 32-bit value from entry's range */
        {
          eval = apply_range (e->value, e->range);
          val &= apply_range (0xffffffff, e->range);
        }
-      else if (r->sbit == e->range.sbit && r->ebit == e->range.ebit
-              || e->range.sbit == 0 && e->range.ebit == 0)
+      else if ((r->sbit == e->range.sbit && r->ebit == e->range.ebit)
+              || (e->range.sbit == 0 && e->range.ebit == 0))
        {
          eval = apply_range (e->value, *r);
          val = apply_range (val, *r);
@@ -824,7 +797,7 @@ find_entry_byval (e_processor processor, e_type type,
   return 0;
 }
 
-/* Return a pointer to the list of entries for a given processor and type. */
+/* Return a pointer to the list of entries for a given processor and type.  */
 
 static struct itbl_entry **
 get_entries (e_processor processor, e_type type)
@@ -832,9 +805,9 @@ get_entries (e_processor processor, e_type type)
   return &entries[processor][type];
 }
 
-/* Return an integral value for the processor passed from yyparse. */
+/* Return an integral value for the processor passed from yyparse.  */
 
-static e_processor 
+static e_processor
 get_processor (int yyproc)
 {
   /* translate from yacc's processor to enum */
@@ -843,9 +816,9 @@ get_processor (int yyproc)
   return e_invproc;            /* error; invalid processor */
 }
 
-/* Return an integral value for the entry type passed from yyparse. */
+/* Return an integral value for the entry type passed from yyparse.  */
 
-static e_type 
+static e_type
 get_type (int yytype)
 {
   switch (yytype)
@@ -868,7 +841,6 @@ get_type (int yytype)
     }
 }
 
-
 /* Allocate and initialize an entry */
 
 static struct itbl_entry *
@@ -878,13 +850,11 @@ alloc_entry (e_processor processor, e_type type,
   struct itbl_entry *e, **es;
   if (!name)
     return 0;
-  e = (struct itbl_entry *) malloc (sizeof (struct itbl_entry));
+  e = XNEW (struct itbl_entry);
   if (e)
     {
       memset (e, 0, sizeof (struct itbl_entry));
-      e->name = (char *) malloc (sizeof (strlen (name)) + 1);
-      if (e->name)
-       strcpy (e->name, name);
+      e->name = xstrdup (name);
       e->processor = processor;
       e->type = type;
       e->value = value;
@@ -902,7 +872,7 @@ alloc_field (e_type type, int sbit, int ebit,
             unsigned long flags)
 {
   struct itbl_field *f;
-  f = (struct itbl_field *) malloc (sizeof (struct itbl_field));
+  f = XNEW (struct itbl_field);
   if (f)
     {
       memset (f, 0, sizeof (struct itbl_field));