Rework the R_NEG support on both gas and ld for the PowerPC AIX targets, in order...
[binutils-gdb.git] / gas / config / xtensa-relax.c
index 3adbf2aa60a68fc308ade94f2836f0b7416b8c01..267d436461a260d11ec2d90f1032b633f747e80f 100644 (file)
@@ -1,5 +1,5 @@
 /* Table of relaxations for Xtensa assembly.
 /* Table of relaxations for Xtensa assembly.
-   Copyright (C) 2003-2016 Free Software Foundation, Inc.
+   Copyright (C) 2003-2021 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 
    This file is part of GAS, the GNU Assembler.
 
    when the first and second operands are not the same as specified
    by the "| %at!=%as" precondition clause.
    {"l32i %at,%as,%imm | %at!=%as",
    when the first and second operands are not the same as specified
    by the "| %at!=%as" precondition clause.
    {"l32i %at,%as,%imm | %at!=%as",
-   "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"}
-
-   There is special case for loop instructions here, but because we do
-   not currently have the ability to represent the difference of two
-   symbols, the conversion requires special code in the assembler to
-   write the operands of the addi/addmi pair representing the
-   difference of the old and new loop end label.  */
+   "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"}  */
 
 #include "as.h"
 #include "xtensa-isa.h"
 
 #include "as.h"
 #include "xtensa-isa.h"
@@ -306,44 +300,83 @@ static string_pattern_pair widen_spec_list[] =
   {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
 
   {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
 
-  /* This is only PART of the loop instruction.  In addition,
-     hardcoded into its use is a modification of the final operand in
-     the instruction in bytes 9 and 12.  */
-  {"loop %as,%label | %as!=1 ? IsaUseLoops",
+  /* Widening loops with literals.  */
+  {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
    "loop %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "loop %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
-   "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
-   "addmi   %as, %as, 0;"      /* mid8(%label-%LABEL1) */
+   "LITERAL     %label;"
+   "l32r        %as, %LITERAL;"
+   "nop;"
    "wsr.lend    %as;"
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "wsr.lend    %as;"
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
-   "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
+   "addi    %as, %as, 1;"
    "LABEL"},
    "LABEL"},
-  {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
+  {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
    "beqz    %as,%label;"
    "bltz    %as,%label;"
    "loopgtz %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "beqz    %as,%label;"
    "bltz    %as,%label;"
    "loopgtz %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
-   "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
-   "addmi   %as, %as, 0;"      /* mid8(%label-%LABEL1) */
+   "LITERAL     %label;"
+   "l32r        %as, %LITERAL;"
+   "nop;"
    "wsr.lend    %as;"
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "wsr.lend    %as;"
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
-   "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
+   "addi    %as, %as, 1;"
    "LABEL"},
    "LABEL"},
-  {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
+  {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
    "beqz     %as,%label;"
    "loopnez %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "beqz     %as,%label;"
    "loopnez %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
-   "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
-   "addmi   %as, %as, 0;"      /* mid8(%label-%LABEL1) */
+   "LITERAL     %label;"
+   "l32r        %as, %LITERAL;"
+   "nop;"
    "wsr.lend    %as;"
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "wsr.lend    %as;"
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
-   "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
+   "addi    %as, %as, 1;"
+   "LABEL"},
+
+  /* Widening loops with const16.  */
+  {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
+   "loop %as,%LABEL;"
+   "rsr.lend    %as;"          /* LEND */
+   "wsr.lbeg    %as;"          /* LBEG */
+   "const16     %as,HI16U(%label);"
+   "const16     %as,LOW16U(%label);"
+   "wsr.lend    %as;"
+   "isync;"
+   "rsr.lcount    %as;"                /* LCOUNT */
+   "addi    %as, %as, 1;"
+   "LABEL"},
+  {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
+   "beqz    %as,%label;"
+   "bltz    %as,%label;"
+   "loopgtz %as,%LABEL;"
+   "rsr.lend    %as;"          /* LEND */
+   "wsr.lbeg    %as;"          /* LBEG */
+   "const16     %as,HI16U(%label);"
+   "const16     %as,LOW16U(%label);"
+   "wsr.lend    %as;"
+   "isync;"
+   "rsr.lcount    %as;"                /* LCOUNT */
+   "addi    %as, %as, 1;"
+   "LABEL"},
+  {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
+   "beqz     %as,%label;"
+   "loopnez %as,%LABEL;"
+   "rsr.lend    %as;"          /* LEND */
+   "wsr.lbeg    %as;"          /* LBEG */
+   "const16     %as,HI16U(%label);"
+   "const16     %as,LOW16U(%label);"
+   "wsr.lend    %as;"
+   "isync;"
+   "rsr.lcount    %as;"                /* LCOUNT */
+   "addi    %as, %as, 1;"
    "LABEL"},
 
   /* Relaxing to wide branches.  Order is important here.  With wide
    "LABEL"},
 
   /* Relaxing to wide branches.  Order is important here.  With wide
@@ -512,7 +545,7 @@ string_pattern_pair simplify_spec_list[] =
 \f
 /* Externally visible functions.  */
 
 \f
 /* Externally visible functions.  */
 
-extern bfd_boolean xg_has_userdef_op_fn (OpType);
+extern bool xg_has_userdef_op_fn (OpType);
 extern long xg_apply_userdef_op_fn (OpType, long);
 
 
 extern long xg_apply_userdef_op_fn (OpType, long);
 
 
@@ -522,7 +555,7 @@ append_transition (TransitionTable *tt,
                   TransitionRule *t,
                   transition_cmp_fn cmp)
 {
                   TransitionRule *t,
                   transition_cmp_fn cmp)
 {
-  TransitionList *tl = (TransitionList *) xmalloc (sizeof (TransitionList));
+  TransitionList *tl = XNEW (TransitionList);
   TransitionList *prev;
   TransitionList **t_p;
   gas_assert (tt != NULL);
   TransitionList *prev;
   TransitionList **t_p;
   gas_assert (tt != NULL);
@@ -554,8 +587,7 @@ append_transition (TransitionTable *tt,
 static void
 append_condition (TransitionRule *tr, Precondition *cond)
 {
 static void
 append_condition (TransitionRule *tr, Precondition *cond)
 {
-  PreconditionList *pl =
-    (PreconditionList *) xmalloc (sizeof (PreconditionList));
+  PreconditionList *pl = XNEW (PreconditionList);
   PreconditionList *prev = tr->conditions;
   PreconditionList *nxt;
 
   PreconditionList *prev = tr->conditions;
   PreconditionList *nxt;
 
@@ -582,7 +614,7 @@ append_value_condition (TransitionRule *tr,
                        unsigned op1,
                        unsigned op2)
 {
                        unsigned op1,
                        unsigned op2)
 {
-  Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
+  Precondition *cond = XNEW (Precondition);
 
   cond->cmp = cmp;
   cond->op_num = op1;
 
   cond->cmp = cmp;
   cond->op_num = op1;
@@ -598,7 +630,7 @@ append_constant_value_condition (TransitionRule *tr,
                                 unsigned op1,
                                 unsigned cnst)
 {
                                 unsigned op1,
                                 unsigned cnst)
 {
-  Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
+  Precondition *cond = XNEW (Precondition);
 
   cond->cmp = cmp;
   cond->op_num = op1;
 
   cond->cmp = cmp;
   cond->op_num = op1;
@@ -654,7 +686,7 @@ append_op (BuildInstr *bi, BuildOp *b_op)
 static void
 append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op)
 {
 static void
 append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op)
 {
-  BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
+  BuildOp *b_op = XNEW (BuildOp);
 
   b_op->op_num = op1;
   b_op->typ = OP_LITERAL;
 
   b_op->op_num = op1;
   b_op->typ = OP_LITERAL;
@@ -667,7 +699,7 @@ append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op)
 static void
 append_label_op (BuildInstr *bi, unsigned op1)
 {
 static void
 append_label_op (BuildInstr *bi, unsigned op1)
 {
-  BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
+  BuildOp *b_op = XNEW (BuildOp);
 
   b_op->op_num = op1;
   b_op->typ = OP_LABEL;
 
   b_op->op_num = op1;
   b_op->typ = OP_LABEL;
@@ -680,7 +712,7 @@ append_label_op (BuildInstr *bi, unsigned op1)
 static void
 append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst)
 {
 static void
 append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst)
 {
-  BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
+  BuildOp *b_op = XNEW (BuildOp);
 
   b_op->op_num = op1;
   b_op->typ = OP_CONSTANT;
 
   b_op->op_num = op1;
   b_op->typ = OP_CONSTANT;
@@ -693,7 +725,7 @@ append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst)
 static void
 append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op)
 {
 static void
 append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op)
 {
-  BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
+  BuildOp *b_op = XNEW (BuildOp);
 
   b_op->op_num = op1;
   b_op->typ = OP_OPERAND;
 
   b_op->op_num = op1;
   b_op->typ = OP_OPERAND;
@@ -711,7 +743,7 @@ append_user_fn_field_op (BuildInstr *bi,
                         OpType typ,
                         unsigned src_op)
 {
                         OpType typ,
                         unsigned src_op)
 {
-  BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
+  BuildOp *b_op = XNEW (BuildOp);
 
   b_op->op_num = op1;
   b_op->typ = typ;
 
   b_op->op_num = op1;
   b_op->typ = typ;
@@ -766,7 +798,7 @@ operand_function_HI16U (long a)
 }
 
 
 }
 
 
-bfd_boolean
+bool
 xg_has_userdef_op_fn (OpType op)
 {
   switch (op)
 xg_has_userdef_op_fn (OpType op)
 {
   switch (op)
@@ -776,11 +808,11 @@ xg_has_userdef_op_fn (OpType op)
     case OP_OPERAND_HI24S:
     case OP_OPERAND_LOW16U:
     case OP_OPERAND_HI16U:
     case OP_OPERAND_HI24S:
     case OP_OPERAND_LOW16U:
     case OP_OPERAND_HI16U:
-      return TRUE;
+      return true;
     default:
       break;
     }
     default:
       break;
     }
-  return FALSE;
+  return false;
 }
 
 
 }
 
 
@@ -802,7 +834,7 @@ xg_apply_userdef_op_fn (OpType op, long a)
     default:
       break;
     }
     default:
       break;
     }
-  return FALSE;
+  return false;
 }
 
 
 }
 
 
@@ -819,10 +851,8 @@ enter_opname_n (const char *name, int len)
          && strncmp (op->opname, name, len) == 0)
        return op->opname;
     }
          && strncmp (op->opname, name, len) == 0)
        return op->opname;
     }
-  op = (opname_e *) xmalloc (sizeof (opname_e));
-  op->opname = (char *) xmalloc (len + 1);
-  strncpy (op->opname, name, len);
-  op->opname[len] = '\0';
+  op = XNEW (opname_e);
+  op->opname = xmemdup0 (name, len);
   return op->opname;
 }
 
   return op->opname;
 }
 
@@ -837,7 +867,7 @@ enter_opname (const char *name)
       if (strcmp (op->opname, name) == 0)
        return op->opname;
     }
       if (strcmp (op->opname, name) == 0)
        return op->opname;
     }
-  op = (opname_e *) xmalloc (sizeof (opname_e));
+  op = XNEW (opname_e);
   op->opname = xstrdup (name);
   return op->opname;
 }
   op->opname = xstrdup (name);
   return op->opname;
 }
@@ -866,11 +896,11 @@ clear_opname_map (opname_map *m)
 }
 
 
 }
 
 
-static bfd_boolean
+static bool
 same_operand_name (const opname_map_e *m1, const opname_map_e *m2)
 {
   if (m1->operand_name == NULL || m2->operand_name == NULL)
 same_operand_name (const opname_map_e *m1, const opname_map_e *m2)
 {
   if (m1->operand_name == NULL || m2->operand_name == NULL)
-    return FALSE;
+    return false;
   return (m1->operand_name == m2->operand_name);
 }
 
   return (m1->operand_name == m2->operand_name);
 }
 
@@ -889,7 +919,7 @@ get_opmatch (opname_map *map, const char *operand_name)
 }
 
 
 }
 
 
-static bfd_boolean
+static bool
 op_is_constant (const opname_map_e *m1)
 {
   return (m1->operand_name == NULL);
 op_is_constant (const opname_map_e *m1)
 {
   return (m1->operand_name == NULL);
@@ -996,14 +1026,14 @@ insn_templ_operand_count (const insn_templ *t)
 
 /* Convert a string to a number.  E.G.: parse_constant("10", &num) */
 
 
 /* Convert a string to a number.  E.G.: parse_constant("10", &num) */
 
-static bfd_boolean
+static bool
 parse_constant (const char *in, unsigned *val_p)
 {
   unsigned val = 0;
   const char *p;
 
   if (in == NULL)
 parse_constant (const char *in, unsigned *val_p)
 {
   unsigned val = 0;
   const char *p;
 
   if (in == NULL)
-    return FALSE;
+    return false;
   p = in;
 
   while (*p != '\0')
   p = in;
 
   while (*p != '\0')
@@ -1011,15 +1041,15 @@ parse_constant (const char *in, unsigned *val_p)
       if (*p >= '0' && *p <= '9')
        val = val * 10 + (*p - '0');
       else
       if (*p >= '0' && *p <= '9')
        val = val * 10 + (*p - '0');
       else
-       return FALSE;
+       return false;
       ++p;
     }
   *val_p = val;
       ++p;
     }
   *val_p = val;
-  return TRUE;
+  return true;
 }
 
 
 }
 
 
-static bfd_boolean
+static bool
 parse_special_fn (const char *name,
                  const char **fn_name_p,
                  const char **arg_name_p)
 parse_special_fn (const char *name,
                  const char **fn_name_p,
                  const char **arg_name_p)
@@ -1029,19 +1059,19 @@ parse_special_fn (const char *name,
 
   p_start = strchr (name, '(');
   if (p_start == NULL)
 
   p_start = strchr (name, '(');
   if (p_start == NULL)
-    return FALSE;
+    return false;
 
   p_end = strchr (p_start, ')');
 
   if (p_end == NULL)
 
   p_end = strchr (p_start, ')');
 
   if (p_end == NULL)
-    return FALSE;
+    return false;
 
   if (p_end[1] != '\0')
 
   if (p_end[1] != '\0')
-    return FALSE;
+    return false;
 
   *fn_name_p = enter_opname_n (name, p_start - name);
   *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
 
   *fn_name_p = enter_opname_n (name, p_start - name);
   *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
-  return TRUE;
+  return true;
 }
 
 
 }
 
 
@@ -1088,7 +1118,7 @@ static void
 split_string (split_rec *rec,
              const char *in,
              char c,
 split_string (split_rec *rec,
              const char *in,
              char c,
-             bfd_boolean elide_whitespace)
+             bool elide_whitespace)
 {
   int cnt = 0;
   int i;
 {
   int cnt = 0;
   int i;
@@ -1107,7 +1137,7 @@ split_string (split_rec *rec,
   if (rec->count == 0)
     return;
 
   if (rec->count == 0)
     return;
 
-  rec->vec = (char **) xmalloc (sizeof (char *) * cnt);
+  rec->vec = XNEWVEC (char *, cnt);
   for (i = 0; i < cnt; i++)
     rec->vec[i] = 0;
 
   for (i = 0; i < cnt; i++)
     rec->vec[i] = 0;
 
@@ -1127,9 +1157,7 @@ split_string (split_rec *rec,
       else
        {
          len = p - q;
       else
        {
          len = p - q;
-         rec->vec[i] = (char *) xmalloc (sizeof (char) * (len + 1));
-         strncpy (rec->vec[i], q, len);
-         rec->vec[i][len] = '\0';
+         rec->vec[i] = xmemdup0 (q, len);
          p++;
        }
 
          p++;
        }
 
@@ -1165,7 +1193,7 @@ init_split_rec (split_rec *rec)
 
 /* Parse an instruction template like "insn op1, op2, op3".  */
 
 
 /* Parse an instruction template like "insn op1, op2, op3".  */
 
-static bfd_boolean
+static bool
 parse_insn_templ (const char *s, insn_templ *t)
 {
   const char *p = s;
 parse_insn_templ (const char *s, insn_templ *t)
 {
   const char *p = s;
@@ -1180,7 +1208,7 @@ parse_insn_templ (const char *s, insn_templ *t)
   p = skip_white (p);
   insn_name_len = strcspn (s, " ");
   if (insn_name_len == 0)
   p = skip_white (p);
   insn_name_len = strcspn (s, " ");
   if (insn_name_len == 0)
-    return FALSE;
+    return false;
 
   init_insn_templ (t);
   t->opcode_name = enter_opname_n (p, insn_name_len);
 
   init_insn_templ (t);
   t->opcode_name = enter_opname_n (p, insn_name_len);
@@ -1188,12 +1216,12 @@ parse_insn_templ (const char *s, insn_templ *t)
   p = p + insn_name_len;
 
   /* Split by ',' and skip beginning and trailing whitespace.  */
   p = p + insn_name_len;
 
   /* Split by ',' and skip beginning and trailing whitespace.  */
-  split_string (&oprec, p, ',', TRUE);
+  split_string (&oprec, p, ',', true);
 
   for (i = 0; i < oprec.count; i++)
     {
       const char *opname = oprec.vec[i];
 
   for (i = 0; i < oprec.count; i++)
     {
       const char *opname = oprec.vec[i];
-      opname_map_e *e = (opname_map_e *) xmalloc (sizeof (opname_map_e));
+      opname_map_e *e = XNEW (opname_map_e);
       e->next = NULL;
       e->operand_name = NULL;
       e->constant_value = 0;
       e->next = NULL;
       e->operand_name = NULL;
       e->constant_value = 0;
@@ -1211,7 +1239,7 @@ parse_insn_templ (const char *s, insn_templ *t)
              free (e);
              clear_split_rec (&oprec);
              clear_insn_templ (t);
              free (e);
              clear_split_rec (&oprec);
              clear_insn_templ (t);
-             return FALSE;
+             return false;
            }
        }
       else
            }
        }
       else
@@ -1221,11 +1249,11 @@ parse_insn_templ (const char *s, insn_templ *t)
       t->operand_map.tail = &e->next;
     }
   clear_split_rec (&oprec);
       t->operand_map.tail = &e->next;
     }
   clear_split_rec (&oprec);
-  return TRUE;
+  return true;
 }
 
 
 }
 
 
-static bfd_boolean
+static bool
 parse_precond (const char *s, precond_e *precond)
 {
   /* All preconditions are currently of the form:
 parse_precond (const char *s, precond_e *precond)
 {
   /* All preconditions are currently of the form:
@@ -1247,19 +1275,19 @@ parse_precond (const char *s, precond_e *precond)
   len = strcspn (p, " !=");
 
   if (len == 0)
   len = strcspn (p, " !=");
 
   if (len == 0)
-    return FALSE;
+    return false;
 
   precond->opname1 = enter_opname_n (p, len);
   p = p + len;
   p = skip_white (p);
 
   /* Check for "==" and "!=".  */
 
   precond->opname1 = enter_opname_n (p, len);
   p = p + len;
   p = skip_white (p);
 
   /* Check for "==" and "!=".  */
-  if (strncmp (p, "==", 2) == 0)
+  if (startswith (p, "=="))
     precond->cmpop = OP_EQUAL;
     precond->cmpop = OP_EQUAL;
-  else if (strncmp (p, "!=", 2) == 0)
+  else if (startswith (p, "!="))
     precond->cmpop = OP_NOTEQUAL;
   else
     precond->cmpop = OP_NOTEQUAL;
   else
-    return FALSE;
+    return false;
 
   p = p + 2;
   p = skip_white (p);
 
   p = p + 2;
   p = skip_white (p);
@@ -1271,11 +1299,11 @@ parse_precond (const char *s, precond_e *precond)
       if (parse_constant (p, &val))
        precond->opval2 = val;
       else
       if (parse_constant (p, &val))
        precond->opval2 = val;
       else
-       return FALSE;
+       return false;
     }
   else
     precond->opname2 = enter_opname (p);
     }
   else
     precond->opname2 = enter_opname (p);
-  return TRUE;
+  return true;
 }
 
 
 }
 
 
@@ -1311,7 +1339,7 @@ clone_req_or_option_list (ReqOrOption *req_or_option)
   if (req_or_option == NULL)
     return NULL;
 
   if (req_or_option == NULL)
     return NULL;
 
-  new_req_or_option = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
+  new_req_or_option = XNEW (ReqOrOption);
   new_req_or_option->option_name = xstrdup (req_or_option->option_name);
   new_req_or_option->is_true = req_or_option->is_true;
   new_req_or_option->next = NULL;
   new_req_or_option->option_name = xstrdup (req_or_option->option_name);
   new_req_or_option->is_true = req_or_option->is_true;
   new_req_or_option->next = NULL;
@@ -1328,7 +1356,7 @@ clone_req_option_list (ReqOption *req_option)
   if (req_option == NULL)
     return NULL;
 
   if (req_option == NULL)
     return NULL;
 
-  new_req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
+  new_req_option = XNEW (ReqOption);
   new_req_option->or_option_terms = NULL;
   new_req_option->next = NULL;
   new_req_option->or_option_terms =
   new_req_option->or_option_terms = NULL;
   new_req_option->next = NULL;
   new_req_option->or_option_terms =
@@ -1338,7 +1366,7 @@ clone_req_option_list (ReqOption *req_option)
 }
 
 
 }
 
 
-static bfd_boolean
+static bool
 parse_option_cond (const char *s, ReqOption *option)
 {
   int i;
 parse_option_cond (const char *s, ReqOption *option)
 {
   int i;
@@ -1349,30 +1377,30 @@ parse_option_cond (const char *s, ReqOption *option)
      "Ands" are divided by "?".  */
 
   init_split_rec (&option_term_rec);
      "Ands" are divided by "?".  */
 
   init_split_rec (&option_term_rec);
-  split_string (&option_term_rec, s, '+', TRUE);
+  split_string (&option_term_rec, s, '+', true);
 
   if (option_term_rec.count == 0)
     {
       clear_split_rec (&option_term_rec);
 
   if (option_term_rec.count == 0)
     {
       clear_split_rec (&option_term_rec);
-      return FALSE;
+      return false;
     }
 
   for (i = 0; i < option_term_rec.count; i++)
     {
       char *option_name = option_term_rec.vec[i];
     }
 
   for (i = 0; i < option_term_rec.count; i++)
     {
       char *option_name = option_term_rec.vec[i];
-      bfd_boolean is_true = TRUE;
+      bool is_true = true;
       ReqOrOption *req;
       ReqOrOption **r_p;
 
       ReqOrOption *req;
       ReqOrOption **r_p;
 
-      if (strncmp (option_name, "no-", 3) == 0)
+      if (startswith (option_name, "no-"))
        {
          option_name = xstrdup (&option_name[3]);
        {
          option_name = xstrdup (&option_name[3]);
-         is_true = FALSE;
+         is_true = false;
        }
       else
        option_name = xstrdup (option_name);
 
        }
       else
        option_name = xstrdup (option_name);
 
-      req = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
+      req = XNEW (ReqOrOption);
       req->option_name = option_name;
       req->is_true = is_true;
       req->next = NULL;
       req->option_name = option_name;
       req->is_true = is_true;
       req->next = NULL;
@@ -1383,7 +1411,7 @@ parse_option_cond (const char *s, ReqOption *option)
        ;
       (*r_p) = req;
     }
        ;
       (*r_p) = req;
     }
-  return TRUE;
+  return true;
 }
 
 
 }
 
 
@@ -1403,7 +1431,7 @@ parse_option_cond (const char *s, ReqOption *option)
    split_string, it requires that '|' and '?' are only used as
    delimiters for predicates and required options.  */
 
    split_string, it requires that '|' and '?' are only used as
    delimiters for predicates and required options.  */
 
-static bfd_boolean
+static bool
 parse_insn_pattern (const char *in, insn_pattern *insn)
 {
   split_rec rec;
 parse_insn_pattern (const char *in, insn_pattern *insn)
 {
   split_rec rec;
@@ -1413,41 +1441,41 @@ parse_insn_pattern (const char *in, insn_pattern *insn)
   init_insn_pattern (insn);
 
   init_split_rec (&optionrec);
   init_insn_pattern (insn);
 
   init_split_rec (&optionrec);
-  split_string (&optionrec, in, '?', TRUE);
+  split_string (&optionrec, in, '?', true);
   if (optionrec.count == 0)
     {
       clear_split_rec (&optionrec);
   if (optionrec.count == 0)
     {
       clear_split_rec (&optionrec);
-      return FALSE;
+      return false;
     }
 
   init_split_rec (&rec);
 
     }
 
   init_split_rec (&rec);
 
-  split_string (&rec, optionrec.vec[0], '|', TRUE);
+  split_string (&rec, optionrec.vec[0], '|', true);
 
   if (rec.count == 0)
     {
       clear_split_rec (&rec);
       clear_split_rec (&optionrec);
 
   if (rec.count == 0)
     {
       clear_split_rec (&rec);
       clear_split_rec (&optionrec);
-      return FALSE;
+      return false;
     }
 
   if (!parse_insn_templ (rec.vec[0], &insn->t))
     {
       clear_split_rec (&rec);
       clear_split_rec (&optionrec);
     }
 
   if (!parse_insn_templ (rec.vec[0], &insn->t))
     {
       clear_split_rec (&rec);
       clear_split_rec (&optionrec);
-      return FALSE;
+      return false;
     }
 
   for (i = 1; i < rec.count; i++)
     {
     }
 
   for (i = 1; i < rec.count; i++)
     {
-      precond_e *cond = (precond_e *) xmalloc (sizeof (precond_e));
+      precond_e *cond = XNEW (precond_e);
 
       if (!parse_precond (rec.vec[i], cond))
        {
          clear_split_rec (&rec);
          clear_split_rec (&optionrec);
          clear_insn_pattern (insn);
 
       if (!parse_precond (rec.vec[i], cond))
        {
          clear_split_rec (&rec);
          clear_split_rec (&optionrec);
          clear_insn_pattern (insn);
-         return FALSE;
+         return false;
        }
 
       /* Append the condition.  */
        }
 
       /* Append the condition.  */
@@ -1459,7 +1487,7 @@ parse_insn_pattern (const char *in, insn_pattern *insn)
     {
       /* Handle the option conditions.  */
       ReqOption **r_p;
     {
       /* Handle the option conditions.  */
       ReqOption **r_p;
-      ReqOption *req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
+      ReqOption *req_option = XNEW (ReqOption);
       req_option->or_option_terms = NULL;
       req_option->next = NULL;
 
       req_option->or_option_terms = NULL;
       req_option->next = NULL;
 
@@ -1469,7 +1497,7 @@ parse_insn_pattern (const char *in, insn_pattern *insn)
          clear_split_rec (&optionrec);
          clear_insn_pattern (insn);
          clear_req_option_list (&req_option);
          clear_split_rec (&optionrec);
          clear_insn_pattern (insn);
          clear_req_option_list (&req_option);
-         return FALSE;
+         return false;
        }
 
       /* Append the condition.  */
        }
 
       /* Append the condition.  */
@@ -1481,22 +1509,22 @@ parse_insn_pattern (const char *in, insn_pattern *insn)
 
   clear_split_rec (&rec);
   clear_split_rec (&optionrec);
 
   clear_split_rec (&rec);
   clear_split_rec (&optionrec);
-  return TRUE;
+  return true;
 }
 
 
 }
 
 
-static bfd_boolean
+static bool
 parse_insn_repl (const char *in, insn_repl *r_p)
 {
   /* This is a list of instruction templates separated by ';'.  */
   split_rec rec;
   int i;
 
 parse_insn_repl (const char *in, insn_repl *r_p)
 {
   /* This is a list of instruction templates separated by ';'.  */
   split_rec rec;
   int i;
 
-  split_string (&rec, in, ';', TRUE);
+  split_string (&rec, in, ';', true);
 
   for (i = 0; i < rec.count; i++)
     {
 
   for (i = 0; i < rec.count; i++)
     {
-      insn_repl_e *e = (insn_repl_e *) xmalloc (sizeof (insn_repl_e));
+      insn_repl_e *e = XNEW (insn_repl_e);
 
       e->next = NULL;
 
 
       e->next = NULL;
 
@@ -1504,16 +1532,16 @@ parse_insn_repl (const char *in, insn_repl *r_p)
        {
          free (e);
          clear_insn_repl (r_p);
        {
          free (e);
          clear_insn_repl (r_p);
-         return FALSE;
+         return false;
        }
       *r_p->tail = e;
       r_p->tail = &e->next;
     }
        }
       *r_p->tail = e;
       r_p->tail = &e->next;
     }
-  return TRUE;
+  return true;
 }
 
 
 }
 
 
-static bfd_boolean
+static bool
 transition_applies (insn_pattern *initial_insn,
                    const char *from_string ATTRIBUTE_UNUSED,
                    const char *to_string ATTRIBUTE_UNUSED)
 transition_applies (insn_pattern *initial_insn,
                    const char *from_string ATTRIBUTE_UNUSED,
                    const char *to_string ATTRIBUTE_UNUSED)
@@ -1530,9 +1558,9 @@ transition_applies (insn_pattern *initial_insn,
          || req_or_option->next != NULL)
        continue;
 
          || req_or_option->next != NULL)
        continue;
 
-      if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0)
+      if (startswith (req_or_option->option_name, "IsaUse"))
        {
        {
-         bfd_boolean option_available = FALSE;
+         bool option_available = false;
          char *option_name = req_or_option->option_name + 6;
          if (!strcmp (option_name, "DensityInstruction"))
            option_available = (XCHAL_HAVE_DENSITY == 1);
          char *option_name = req_or_option->option_name + 6;
          if (!strcmp (option_name, "DensityInstruction"))
            option_available = (XCHAL_HAVE_DENSITY == 1);
@@ -1555,22 +1583,22 @@ transition_applies (insn_pattern *initial_insn,
            as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
                     req_or_option->option_name, from_string);
          if ((option_available ^ req_or_option->is_true) != 0)
            as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
                     req_or_option->option_name, from_string);
          if ((option_available ^ req_or_option->is_true) != 0)
-           return FALSE;
+           return false;
        }
       else if (strcmp (req_or_option->option_name, "realnop") == 0)
        {
        }
       else if (strcmp (req_or_option->option_name, "realnop") == 0)
        {
-         bfd_boolean nop_available =
+         bool nop_available =
            (xtensa_opcode_lookup (xtensa_default_isa, "nop")
             != XTENSA_UNDEFINED);
          if ((nop_available ^ req_or_option->is_true) != 0)
            (xtensa_opcode_lookup (xtensa_default_isa, "nop")
             != XTENSA_UNDEFINED);
          if ((nop_available ^ req_or_option->is_true) != 0)
-           return FALSE;
+           return false;
        }
     }
        }
     }
-  return TRUE;
+  return true;
 }
 
 
 }
 
 
-static bfd_boolean
+static bool
 wide_branch_opcode (const char *opcode_name,
                    const char *suffix,
                    xtensa_opcode *popcode)
 wide_branch_opcode (const char *opcode_name,
                    const char *suffix,
                    xtensa_opcode *popcode)
@@ -1579,8 +1607,8 @@ wide_branch_opcode (const char *opcode_name,
   xtensa_opcode opcode;
   static char wbr_name_buf[20];
 
   xtensa_opcode opcode;
   static char wbr_name_buf[20];
 
-  if (strncmp (opcode_name, "WIDE.", 5) != 0)
-    return FALSE;
+  if (!startswith (opcode_name, "WIDE."))
+    return false;
 
   strcpy (wbr_name_buf, opcode_name + 5);
   strcat (wbr_name_buf, suffix);
 
   strcpy (wbr_name_buf, opcode_name + 5);
   strcat (wbr_name_buf, suffix);
@@ -1588,10 +1616,10 @@ wide_branch_opcode (const char *opcode_name,
   if (opcode != XTENSA_UNDEFINED)
     {
       *popcode = opcode;
   if (opcode != XTENSA_UNDEFINED)
     {
       *popcode = opcode;
-      return TRUE;
+      return true;
     }
 
     }
 
-  return FALSE;
+  return false;
 }
 
 
 }
 
 
@@ -1632,7 +1660,7 @@ build_transition (insn_pattern *initial_insn,
       return NULL;
     }
 
       return NULL;
     }
 
-  tr = (TransitionRule *) xmalloc (sizeof (TransitionRule));
+  tr = XNEW (TransitionRule);
   tr->opcode = opcode;
   tr->conditions = NULL;
   tr->to_instr = NULL;
   tr->opcode = opcode;
   tr->conditions = NULL;
   tr->to_instr = NULL;
@@ -1688,7 +1716,7 @@ build_transition (insn_pattern *initial_insn,
          op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
          if (op2 == NULL)
            as_fatal (_("opcode '%s': no bound opname '%s' "
          op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
          if (op2 == NULL)
            as_fatal (_("opcode '%s': no bound opname '%s' "
-                       "for precondition in %s"),
+                       "for precondition in '%s'"),
                      xtensa_opcode_name (isa, opcode),
                      precond->opname2, from_string);
        }
                      xtensa_opcode_name (isa, opcode),
                      precond->opname2, from_string);
        }
@@ -1727,7 +1755,7 @@ build_transition (insn_pattern *initial_insn,
       const char *fn_name;
       const char *operand_arg_name;
 
       const char *fn_name;
       const char *operand_arg_name;
 
-      bi = (BuildInstr *) xmalloc (sizeof (BuildInstr));
+      bi = XNEW (BuildInstr);
       append_build_insn (tr, bi);
 
       bi->opcode = XTENSA_UNDEFINED;
       append_build_insn (tr, bi);
 
       bi->opcode = XTENSA_UNDEFINED;
@@ -1769,7 +1797,9 @@ build_transition (insn_pattern *initial_insn,
          /* Check for the right number of ops.  */
          if (xtensa_opcode_num_operands (isa, bi->opcode)
              != (int) operand_count)
          /* Check for the right number of ops.  */
          if (xtensa_opcode_num_operands (isa, bi->opcode)
              != (int) operand_count)
-           as_fatal (_("opcode '%s': replacement does not have %d ops"),
+           as_fatal (ngettext ("opcode '%s': replacement does not have %d op",
+                               "opcode '%s': replacement does not have %d ops",
+                               xtensa_opcode_num_operands (isa, bi->opcode)),
                      opcode_name,
                      xtensa_opcode_num_operands (isa, bi->opcode));
        }
                      opcode_name,
                      xtensa_opcode_num_operands (isa, bi->opcode));
        }
@@ -1799,7 +1829,7 @@ build_transition (insn_pattern *initial_insn,
              orig_op = get_opmatch (&initial_insn->t.operand_map,
                                     op->operand_name);
              if (orig_op == NULL)
              orig_op = get_opmatch (&initial_insn->t.operand_map,
                                     op->operand_name);
              if (orig_op == NULL)
-               as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
+               as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"),
                          opcode_name, op->operand_name, to_string);
              append_field_op (bi, op->operand_num, orig_op->operand_num);
            }
                          opcode_name, op->operand_name, to_string);
              append_field_op (bi, op->operand_num, orig_op->operand_num);
            }
@@ -1829,13 +1859,13 @@ build_transition (insn_pattern *initial_insn,
              orig_op = get_opmatch (&initial_insn->t.operand_map,
                                     operand_arg_name);
              if (orig_op == NULL)
              orig_op = get_opmatch (&initial_insn->t.operand_map,
                                     operand_arg_name);
              if (orig_op == NULL)
-               as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
+               as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"),
                          opcode_name, op->operand_name, to_string);
              append_user_fn_field_op (bi, op->operand_num,
                                       typ, orig_op->operand_num);
            }
          else
                          opcode_name, op->operand_name, to_string);
              append_user_fn_field_op (bi, op->operand_num,
                                       typ, orig_op->operand_num);
            }
          else
-           as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
+           as_fatal (_("opcode '%s': could not parse operand '%s' in '%s'"),
                      opcode_name, op->operand_name, to_string);
        }
     }
                      opcode_name, op->operand_name, to_string);
        }
     }
@@ -1857,10 +1887,9 @@ build_transition_table (const string_pattern_pair *transitions,
     return table;
 
   /* Otherwise, build it now.  */
     return table;
 
   /* Otherwise, build it now.  */
-  table = (TransitionTable *) xmalloc (sizeof (TransitionTable));
+  table = XNEW (TransitionTable);
   table->num_opcodes = num_opcodes;
   table->num_opcodes = num_opcodes;
-  table->table =
-    (TransitionList **) xmalloc (sizeof (TransitionTable *) * num_opcodes);
+  table->table = XNEWVEC (TransitionList *, num_opcodes);
 
   for (i = 0; i < num_opcodes; i++)
     table->table[i] = NULL;
 
   for (i = 0; i < num_opcodes; i++)
     table->table[i] = NULL;