MIPS/GAS: Don't convert RELA JALR relocations on R6
[deliverable/binutils-gdb.git] / gas / config / xtensa-relax.c
index 4d2d01ac28f6e4bea9d55302bad7c2c8712c85c1..ffec5ed920b2264f20d5d30a4b5c5f16ed13de20 100644 (file)
@@ -1,11 +1,11 @@
 /* Table of relaxations for Xtensa assembly.
 /* Table of relaxations for Xtensa assembly.
-   Copyright 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003-2016 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
 
    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,
    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
 
    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.  */
+   the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 /* This file contains the code for generating runtime data structures
    for relaxation pattern matching from statically specified strings.
 
 /* This file contains the code for generating runtime data structures
    for relaxation pattern matching from statically specified strings.
@@ -25,7 +25,7 @@
    matches.  The preconditions can specify that two operands are the
    same or an operand is a specific constant or register.  The expansion
    uses the bound variables from the pattern to specify that specific
    matches.  The preconditions can specify that two operands are the
    same or an operand is a specific constant or register.  The expansion
    uses the bound variables from the pattern to specify that specific
-   operands from the pattern should be used in the result.  
+   operands from the pattern should be used in the result.
 
    The code determines whether the condition applies to a constant or
    a register depending on the type of the operand.  You may get
 
    The code determines whether the condition applies to a constant or
    a register depending on the type of the operand.  You may get
    OPTIONPRED   ::= OPTIONNAME ('+' OPTIONNAME)
    OPTIONNAME   ::= '"' id '"'
 
    OPTIONPRED   ::= OPTIONNAME ('+' OPTIONNAME)
    OPTIONNAME   ::= '"' id '"'
 
-   The replacement language 
+   The replacement language
    INSN_REPL      ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )*
    INSN_REPL      ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )*
-   INSN_LABEL_LIT ::= INSN_TEMPL 
-                      | 'LABEL' num 
-                      | 'LITERAL' num ' ' VARIABLE
+   INSN_LABEL_LIT ::= INSN_TEMPL
+                      | 'LABEL'
+                      | 'LITERAL' VARIABLE
 
    The operands in a PRECOND must be constants or variables bound by
    the INSN_PATTERN.
 
    The operands in a PRECOND must be constants or variables bound by
    the INSN_PATTERN.
    movi.n instruction to the wide movi instruction.
 
    A more complex example of a branch around:
    movi.n instruction to the wide movi instruction.
 
    A more complex example of a branch around:
-   {"beqz %as,%label", "bnez %as,%LABEL0;j %label;LABEL0"}
+   {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"}
    would convert a branch to a negated branch to the following instruction
    with a jump to the original label.
    would convert a branch to a negated branch to the following instruction
    with a jump to the original label.
-   
+
    An Xtensa-specific example that generates a literal:
    An Xtensa-specific example that generates a literal:
-   {"movi %at,%imm", "LITERAL0 %imm; l32r %at,%LITERAL0"}
+   {"movi %at,%imm", "LITERAL %imm; l32r %at,%LITERAL"}
    will convert a movi instruction to an l32r of a literal
    literal defined in the literal pool.
 
    will convert a movi instruction to an l32r of a literal
    literal defined in the literal pool.
 
@@ -87,7 +87,7 @@
    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",
-   "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l32i %at,%at,0"}
+   "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
 
    There is special case for loop instructions here, but because we do
    not currently have the ability to represent the difference of two
 #include <stddef.h>
 #include "xtensa-config.h"
 
 #include <stddef.h>
 #include "xtensa-config.h"
 
+#ifndef XCHAL_HAVE_WIDE_BRANCHES
+#define XCHAL_HAVE_WIDE_BRANCHES 0
+#endif
+
 /* Imported from bfd.  */
 extern xtensa_isa xtensa_default_isa;
 
 /* Imported from bfd.  */
 extern xtensa_isa xtensa_default_isa;
 
@@ -243,7 +247,10 @@ struct string_pattern_pair_struct
      addi.n a4, 0x1010
      => addi a4, 0x1010
      => addmi a4, 0x1010
      addi.n a4, 0x1010
      => addi a4, 0x1010
      => addmi a4, 0x1010
-     => addmi a4, 0x1000, addi a4, 0x10.  */
+     => addmi a4, 0x1000, addi a4, 0x10.
+
+   See the comments in xg_assembly_relax for some important details
+   regarding how these chains must be built.  */
 
 static string_pattern_pair widen_spec_list[] =
 {
 
 static string_pattern_pair widen_spec_list[] =
 {
@@ -263,9 +270,9 @@ static string_pattern_pair widen_spec_list[] =
   {"slli %ar,%as,0", "or %ar,%as,%as"},
 
   /* Widening with literals or const16.  */
   {"slli %ar,%as,0", "or %ar,%as,%as"},
 
   /* Widening with literals or const16.  */
-  {"movi %at,%imm ? IsaUseL32R ", 
-   "LITERAL0 %imm; l32r %at,%LITERAL0"},
-  {"movi %at,%imm ? IsaUseConst16", 
+  {"movi %at,%imm ? IsaUseL32R ",
+   "LITERAL %imm; l32r %at,%LITERAL"},
+  {"movi %at,%imm ? IsaUseConst16",
    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
 
   {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
 
   {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
@@ -275,19 +282,19 @@ static string_pattern_pair widen_spec_list[] =
 
   /* In the end convert to either an l32r or const16.  */
   {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
 
   /* In the end convert to either an l32r or const16.  */
   {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
-   "LITERAL0 %imm; l32r %ar,%LITERAL0; add %ar,%as,%ar"},
+   "LITERAL %imm; l32r %ar,%LITERAL; add %ar,%as,%ar"},
   {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
    "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
 
   /* Widening the load instructions with too-large immediates */
   {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
   {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
    "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
 
   /* Widening the load instructions with too-large immediates */
   {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
-   "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l8ui %at,%at,0"},
+   "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l8ui %at,%at,0"},
   {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
   {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
-   "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l16si %at,%at,0"},
+   "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16si %at,%at,0"},
   {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
   {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
-   "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l16ui %at,%at,0"},
+   "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16ui %at,%at,0"},
   {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
   {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
-   "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l32i %at,%at,0"},
+   "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"},
 
   /* Widening load instructions with const16s.  */
   {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
 
   /* Widening load instructions with const16s.  */
   {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
@@ -299,20 +306,11 @@ 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"},
 
-#if 0 /* Xtensa Synchronization Option not yet available */
-  {"l32ai %at,%as,%imm ? IsaUseL32R",
-   "LITERAL0 %imm; l32r %at,%LITERAL0; add.n %at,%at,%as; l32ai %at,%at,0"},
-#endif
-#if 0 /* Xtensa Speculation Option not yet available */
-  {"l32is %at,%as,%imm ? IsaUseL32R",
-   "LITERAL0 %imm; l32r %at,%LITERAL0; add.n %at,%at,%as; l32is %at,%at,0"},
-#endif
-
   /* 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",
   /* 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",
-   "loop %as,%LABEL0;"
+   "loop %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
@@ -321,11 +319,11 @@ static string_pattern_pair widen_spec_list[] =
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
-   "LABEL0"},
+   "LABEL"},
   {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
    "beqz    %as,%label;"
    "bltz    %as,%label;"
   {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
    "beqz    %as,%label;"
    "bltz    %as,%label;"
-   "loopgtz %as,%LABEL0;"
+   "loopgtz %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
@@ -334,10 +332,10 @@ static string_pattern_pair widen_spec_list[] =
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
-   "LABEL0"},
+   "LABEL"},
   {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
    "beqz     %as,%label;"
   {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
    "beqz     %as,%label;"
-   "loopnez %as,%LABEL0;"
+   "loopnez %as,%LABEL;"
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
    "rsr.lend    %as;"          /* LEND */
    "wsr.lbeg    %as;"          /* LBEG */
    "addi    %as, %as, 0;"      /* lo8(%label-%LABEL1) */
@@ -346,53 +344,116 @@ static string_pattern_pair widen_spec_list[] =
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
    "isync;"
    "rsr.lcount    %as;"                /* LCOUNT */
    "addi    %as, %as, 1;"      /* density -> addi.n %as, %as, 1 */
-   "LABEL0"},
-
-  {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL0;j %label;LABEL0"},
-  {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL0;j %label;LABEL0"},
-  {"beqz %as,%label", "bnez %as,%LABEL0;j %label;LABEL0"},
-  {"bnez %as,%label", "beqz %as,%LABEL0;j %label;LABEL0"},
-  {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL0;j %label;LABEL0"},
-  {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL0;j %label;LABEL0"},
-
-  {"bgez %as,%label", "bltz %as,%LABEL0;j %label;LABEL0"},
-  {"bltz %as,%label", "bgez %as,%LABEL0;j %label;LABEL0"},
-  {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL0;j %label;LABEL0"},
-  {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL0;j %label;LABEL0"},
-  {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL0;j %label;LABEL0"},
-  {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL0;j %label;LABEL0"},
-  {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL0;j %label;LABEL0"},
-  {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL0;j %label;LABEL0"},
-  {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL0;j %label;LABEL0"},
-  {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL0;j %label;LABEL0"},
-  {"beq %as,%at,%label", "bne %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bne %as,%at,%label", "beq %as,%at,%LABEL0;j %label;LABEL0"},
-  {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bge %as,%at,%label", "blt %as,%at,%LABEL0;j %label;LABEL0"},
-  {"blt %as,%at,%label", "bge %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bany %as,%at,%label", "bnone %as,%at,%LABEL0;j %label;LABEL0"},
-
-  {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL0;j %label;LABEL0"},
-  {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL0;j %label;LABEL0"},
-
-  {"bnone %as,%at,%label", "bany %as,%at,%LABEL0;j %label;LABEL0"},
-  {"ball %as,%at,%label", "bnall %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bnall %as,%at,%label", "ball %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bbc %as,%at,%label", "bbs %as,%at,%LABEL0;j %label;LABEL0"},
-  {"bbs %as,%at,%label", "bbc %as,%at,%LABEL0;j %label;LABEL0"},
+   "LABEL"},
+
+  /* Relaxing to wide branches.  Order is important here.  With wide
+     branches, there is more than one correct relaxation for an
+     out-of-range branch.  Put the wide branch relaxations first in the
+     table since they are more efficient than the branch-around
+     relaxations.  */
+
+  {"beqz %as,%label ? IsaUseWideBranches", "WIDE.beqz %as,%label"},
+  {"bnez %as,%label ? IsaUseWideBranches", "WIDE.bnez %as,%label"},
+  {"bgez %as,%label ? IsaUseWideBranches", "WIDE.bgez %as,%label"},
+  {"bltz %as,%label ? IsaUseWideBranches", "WIDE.bltz %as,%label"},
+  {"beqi %as,%imm,%label ? IsaUseWideBranches", "WIDE.beqi %as,%imm,%label"},
+  {"bnei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bnei %as,%imm,%label"},
+  {"bgei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgei %as,%imm,%label"},
+  {"blti %as,%imm,%label ? IsaUseWideBranches", "WIDE.blti %as,%imm,%label"},
+  {"bgeui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgeui %as,%imm,%label"},
+  {"bltui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bltui %as,%imm,%label"},
+  {"bbci %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbci %as,%imm,%label"},
+  {"bbsi %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbsi %as,%imm,%label"},
+  {"beq %as,%at,%label ? IsaUseWideBranches", "WIDE.beq %as,%at,%label"},
+  {"bne %as,%at,%label ? IsaUseWideBranches", "WIDE.bne %as,%at,%label"},
+  {"bge %as,%at,%label ? IsaUseWideBranches", "WIDE.bge %as,%at,%label"},
+  {"blt %as,%at,%label ? IsaUseWideBranches", "WIDE.blt %as,%at,%label"},
+  {"bgeu %as,%at,%label ? IsaUseWideBranches", "WIDE.bgeu %as,%at,%label"},
+  {"bltu %as,%at,%label ? IsaUseWideBranches", "WIDE.bltu %as,%at,%label"},
+  {"bany %as,%at,%label ? IsaUseWideBranches", "WIDE.bany %as,%at,%label"},
+  {"bnone %as,%at,%label ? IsaUseWideBranches", "WIDE.bnone %as,%at,%label"},
+  {"ball %as,%at,%label ? IsaUseWideBranches", "WIDE.ball %as,%at,%label"},
+  {"bnall %as,%at,%label ? IsaUseWideBranches", "WIDE.bnall %as,%at,%label"},
+  {"bbc %as,%at,%label ? IsaUseWideBranches", "WIDE.bbc %as,%at,%label"},
+  {"bbs %as,%at,%label ? IsaUseWideBranches", "WIDE.bbs %as,%at,%label"},
+
+  /* Widening branch comparisons eq/ne to zero.  Prefer relaxing to narrow
+     branches if the density option is available.  */
+  {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
+  {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
+  {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
+  {"bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
+  {"WIDE.beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
+  {"WIDE.bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
+  {"WIDE.beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
+  {"WIDE.bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
+
+  /* Widening expect-taken branches.  */
+  {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL;j %label;LABEL"},
+  {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL;j %label;LABEL"},
+  {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL;j %label;LABEL"},
+  {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL;j %label;LABEL"},
+
+  /* Widening branches from the Xtensa boolean option.  */
+  {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL;j %label;LABEL"},
+  {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL;j %label;LABEL"},
+
+  /* Other branch-around-jump widenings.  */
+  {"bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
+  {"bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
+  {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
+  {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
+  {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
+  {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
+  {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
+  {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
+  {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
+  {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
+  {"beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
+  {"bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
+  {"bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
+  {"blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
+  {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
+  {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
+  {"bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
+  {"bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
+  {"ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
+  {"bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
+  {"bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
+  {"bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
+
+  {"WIDE.bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
+  {"WIDE.bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
+  {"WIDE.beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
+  {"WIDE.bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
+  {"WIDE.bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
+  {"WIDE.blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
+  {"WIDE.bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
+  {"WIDE.bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
+  {"WIDE.bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
+  {"WIDE.bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
+  {"WIDE.beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
+  {"WIDE.bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
 
   /* Expanding calls with literals.  */
   {"call0 %label,%ar0 ? IsaUseL32R",
 
   /* Expanding calls with literals.  */
   {"call0 %label,%ar0 ? IsaUseL32R",
-   "LITERAL0 %label; l32r a0,%LITERAL0; callx0 a0,%ar0"},
+   "LITERAL %label; l32r a0,%LITERAL; callx0 a0,%ar0"},
   {"call4 %label,%ar4 ? IsaUseL32R",
   {"call4 %label,%ar4 ? IsaUseL32R",
-   "LITERAL0 %label; l32r a4,%LITERAL0; callx4 a4,%ar4"},
+   "LITERAL %label; l32r a4,%LITERAL; callx4 a4,%ar4"},
   {"call8 %label,%ar8 ? IsaUseL32R",
   {"call8 %label,%ar8 ? IsaUseL32R",
-   "LITERAL0 %label; l32r a8,%LITERAL0; callx8 a8,%ar8"},
+   "LITERAL %label; l32r a8,%LITERAL; callx8 a8,%ar8"},
   {"call12 %label,%ar12 ? IsaUseL32R",
   {"call12 %label,%ar12 ? IsaUseL32R",
-   "LITERAL0 %label; l32r a12,%LITERAL0; callx12 a12,%ar12"},
+   "LITERAL %label; l32r a12,%LITERAL; callx12 a12,%ar12"},
 
   /* Expanding calls with const16.  */
   {"call0 %label,%ar0 ? IsaUseConst16",
 
   /* Expanding calls with const16.  */
   {"call0 %label,%ar0 ? IsaUseConst16",
@@ -402,7 +463,14 @@ static string_pattern_pair widen_spec_list[] =
   {"call8 %label,%ar8 ? IsaUseConst16",
    "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
   {"call12 %label,%ar12 ? IsaUseConst16",
   {"call8 %label,%ar8 ? IsaUseConst16",
    "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
   {"call12 %label,%ar12 ? IsaUseConst16",
-   "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"}
+   "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"},
+
+  /* Expanding j.l with literals.  */
+  {"j %label ? FREEREG ? IsaUseL32R",
+   "LITERAL %label; l32r FREEREG,%LITERAL; jx FREEREG"},
+  /* Expanding j.l with const16.  */
+  {"j %label ? FREEREG ? IsaUseConst16",
+   "const16 FREEREG,HI16U(%label); const16 FREEREG,LOW16U(%label); jx FREEREG"},
 };
 
 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
 };
 
 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
@@ -442,154 +510,23 @@ string_pattern_pair simplify_spec_list[] =
   (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
 
 \f
   (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
 
 \f
-/* Transition generation helpers.  */
-
-static void append_transition 
-  PARAMS ((TransitionTable *, xtensa_opcode, TransitionRule *,
-          transition_cmp_fn));
-static void append_condition 
-  PARAMS ((TransitionRule *, Precondition *));
-static void append_value_condition 
-  PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned));
-static void append_constant_value_condition 
-  PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned));
-static void append_build_insn
-  PARAMS ((TransitionRule *, BuildInstr *));
-static void append_op
-  PARAMS ((BuildInstr *, BuildOp *));
-static void append_literal_op 
-  PARAMS ((BuildInstr *, unsigned, unsigned));
-static void append_label_op 
-  PARAMS ((BuildInstr *, unsigned, unsigned));
-static void append_constant_op 
-  PARAMS ((BuildInstr *, unsigned, unsigned));
-static void append_field_op 
-  PARAMS ((BuildInstr *, unsigned, unsigned));
-static void append_user_fn_field_op 
-  PARAMS ((BuildInstr *, unsigned, OpType, unsigned));
-static long operand_function_HI24S
-  PARAMS ((long));
-static long operand_function_F32MINUS
-  PARAMS ((long));
-static long operand_function_LOW8
-  PARAMS ((long));
-static long operand_function_LOW16U
-  PARAMS ((long));
-static long operand_function_HI16U
-  PARAMS ((long));
-
 /* Externally visible functions.  */
 
 /* Externally visible functions.  */
 
-extern bfd_boolean xg_has_userdef_op_fn
-  PARAMS ((OpType));
-extern long xg_apply_userdef_op_fn
-  PARAMS ((OpType, long));
-
-/* Parsing helpers.  */
-
-static const char *enter_opname_n
-  PARAMS ((const char *, int));
-static const char *enter_opname
-  PARAMS ((const char *));
-
-/* Construction and destruction.  */
-
-static void init_opname_map
-  PARAMS ((opname_map *));
-static void clear_opname_map
-  PARAMS ((opname_map *));
-static void init_precond_list
-  PARAMS ((precond_list *));
-static void clear_precond_list
-  PARAMS ((precond_list *));
-static void init_insn_templ
-  PARAMS ((insn_templ *));
-static void clear_insn_templ
-  PARAMS ((insn_templ *));
-static void init_insn_pattern
-  PARAMS ((insn_pattern *));
-static void clear_insn_pattern
-  PARAMS ((insn_pattern *));
-static void init_insn_repl
-  PARAMS ((insn_repl *));
-static void clear_insn_repl
-  PARAMS ((insn_repl *));
-static void init_split_rec
-  PARAMS ((split_rec *));
-static void clear_split_rec
-  PARAMS ((split_rec *));
-static void clear_req_or_option_list
-  PARAMS ((ReqOrOption **));
-static void clear_req_option_list
-  PARAMS ((ReqOption **));
-static ReqOrOption *clone_req_or_option_list
-  PARAMS ((ReqOrOption *));
-static ReqOption *clone_req_option_list
-  PARAMS ((ReqOption *));
-
-/* Operand and insn_templ helpers.  */
-
-static bfd_boolean same_operand_name
-  PARAMS ((const opname_map_e *, const opname_map_e *));
-static opname_map_e *get_opmatch
-  PARAMS ((opname_map *, const char *));
-static bfd_boolean op_is_constant
-  PARAMS ((const opname_map_e *));
-static unsigned op_get_constant
-  PARAMS ((const opname_map_e *));
-static int insn_templ_operand_count
-  PARAMS ((const insn_templ *));
-
-/* Parsing helpers.  */
-
-static const char *skip_white
-  PARAMS ((const char *));
-static void trim_whitespace
-  PARAMS ((char *));
-static void split_string 
-  PARAMS ((split_rec *, const char *, char,  bfd_boolean));
-
-/* Language parsing.  */
-
-static bfd_boolean parse_insn_pattern 
-  PARAMS ((const char *, insn_pattern *));
-static bfd_boolean parse_insn_repl 
-  PARAMS ((const char *, insn_repl *));
-static bfd_boolean parse_insn_templ 
-  PARAMS ((const char *, insn_templ *));
-static bfd_boolean parse_special_fn 
-  PARAMS ((const char *, const char **, const char **));
-static bfd_boolean parse_precond
-  PARAMS ((const char *, precond_e *));
-static bfd_boolean parse_constant
-  PARAMS ((const char *, unsigned *));
-static bfd_boolean parse_id_constant 
-  PARAMS ((const char *, const char *, unsigned *));
-static bfd_boolean parse_option_cond
-  PARAMS ((const char *, ReqOption *));
-
-/* Transition table building code.  */
-
-static bfd_boolean transition_applies 
-  PARAMS ((insn_pattern *, const char *, const char *));
-static TransitionRule *build_transition 
-  PARAMS ((insn_pattern *, insn_repl *, const char *, const char *));
-static TransitionTable *build_transition_table 
-  PARAMS ((const string_pattern_pair *, int, transition_cmp_fn));
+extern bfd_boolean xg_has_userdef_op_fn (OpType);
+extern long xg_apply_userdef_op_fn (OpType, long);
 
 
-\f
-void
-append_transition (tt, opcode, t, cmp)
-     TransitionTable *tt;
-     xtensa_opcode opcode;
-     TransitionRule *t;
-     transition_cmp_fn cmp;
-{
-  TransitionList *tl = (TransitionList *) xmalloc (sizeof (TransitionList));
+
+static void
+append_transition (TransitionTable *tt,
+                  xtensa_opcode opcode,
+                  TransitionRule *t,
+                  transition_cmp_fn cmp)
+{
+  TransitionList *tl = XNEW (TransitionList);
   TransitionList *prev;
   TransitionList **t_p;
   TransitionList *prev;
   TransitionList **t_p;
-  assert (tt != NULL);
-  assert (opcode < tt->num_opcodes);
+  gas_assert (tt != NULL);
+  gas_assert (opcode < tt->num_opcodes);
 
   prev = tt->table[opcode];
   tl->rule = t;
 
   prev = tt->table[opcode];
   tl->rule = t;
@@ -614,13 +551,10 @@ append_transition (tt, opcode, t, cmp)
 }
 
 
 }
 
 
-void
-append_condition (tr, cond)
-     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;
 
@@ -641,14 +575,13 @@ append_condition (tr, cond)
 }
 
 
 }
 
 
-void
-append_value_condition (tr, cmp, op1, op2)
-     TransitionRule *tr;
-     CmpOp cmp;
-     unsigned op1;
-     unsigned op2;
+static void
+append_value_condition (TransitionRule *tr,
+                       CmpOp cmp,
+                       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;
@@ -658,14 +591,13 @@ append_value_condition (tr, cmp, op1, op2)
 }
 
 
 }
 
 
-void
-append_constant_value_condition (tr, cmp, op1, cnst)
-     TransitionRule *tr;
-     CmpOp cmp;
-     unsigned op1;
-     unsigned cnst;
+static void
+append_constant_value_condition (TransitionRule *tr,
+                                CmpOp cmp,
+                                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;
@@ -675,10 +607,8 @@ append_constant_value_condition (tr, cmp, op1, cnst)
 }
 
 
 }
 
 
-void
-append_build_insn (tr, bi)
-     TransitionRule *tr;
-     BuildInstr *bi;
+static void
+append_build_insn (TransitionRule *tr, BuildInstr *bi)
 {
   BuildInstr *prev = tr->to_instr;
   BuildInstr *nxt;
 {
   BuildInstr *prev = tr->to_instr;
   BuildInstr *nxt;
@@ -699,10 +629,8 @@ append_build_insn (tr, bi)
 }
 
 
 }
 
 
-void
-append_op (bi, b_op)
-     BuildInstr *bi;
-     BuildOp *b_op;
+static void
+append_op (BuildInstr *bi, BuildOp *b_op)
 {
   BuildOp *prev = bi->ops;
   BuildOp *nxt;
 {
   BuildOp *prev = bi->ops;
   BuildOp *nxt;
@@ -722,45 +650,36 @@ append_op (bi, b_op)
 }
 
 
 }
 
 
-void
-append_literal_op (bi, op1, litnum)
-     BuildInstr *bi;
-     unsigned op1;
-     unsigned litnum;
+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;
-  b_op->op_data = litnum;
+  b_op->op_data = src_op;
   b_op->next = NULL;
   append_op (bi, b_op);
 }
 
 
   b_op->next = NULL;
   append_op (bi, b_op);
 }
 
 
-void
-append_label_op (bi, op1, labnum)
-     BuildInstr *bi;
-     unsigned op1;
-     unsigned labnum;
+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;
-  b_op->op_data = labnum;
+  b_op->op_data = 0;
   b_op->next = NULL;
   append_op (bi, b_op);
 }
 
 
   b_op->next = NULL;
   append_op (bi, b_op);
 }
 
 
-void
-append_constant_op (bi, op1, cnst)
-     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;
@@ -770,13 +689,10 @@ append_constant_op (bi, op1, cnst)
 }
 
 
 }
 
 
-void
-append_field_op (bi, op1, src_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;
@@ -788,14 +704,13 @@ append_field_op (bi, op1, src_op)
 
 /* These could be generated but are not currently.  */
 
 
 /* These could be generated but are not currently.  */
 
-void
-append_user_fn_field_op (bi, op1, typ, src_op)
-     BuildInstr *bi;
-     unsigned op1;
-     OpType typ;
-     unsigned src_op;
+static void
+append_user_fn_field_op (BuildInstr *bi,
+                        unsigned op1,
+                        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;
@@ -808,9 +723,8 @@ append_user_fn_field_op (bi, op1, typ, src_op)
 /* These operand functions are the semantics of user-defined
    operand functions.  */
 
 /* These operand functions are the semantics of user-defined
    operand functions.  */
 
-long
-operand_function_HI24S (a)
-     long a;
+static long
+operand_function_HI24S (long a)
 {
   if (a & 0x80)
     return (a & (~0xff)) + 0x100;
 {
   if (a & 0x80)
     return (a & (~0xff)) + 0x100;
@@ -819,17 +733,15 @@ operand_function_HI24S (a)
 }
 
 
 }
 
 
-long
-operand_function_F32MINUS (a)
-     long a;
+static long
+operand_function_F32MINUS (long a)
 {
   return (32 - a);
 }
 
 
 {
   return (32 - a);
 }
 
 
-long
-operand_function_LOW8 (a)
-     long a;
+static long
+operand_function_LOW8 (long a)
 {
   if (a & 0x80)
     return (a & 0xff) | ~0xff;
 {
   if (a & 0x80)
     return (a & 0xff) | ~0xff;
@@ -838,17 +750,15 @@ operand_function_LOW8 (a)
 }
 
 
 }
 
 
-long
-operand_function_LOW16U (a)
-     long a;
+static long
+operand_function_LOW16U (long a)
 {
   return (a & 0xffff);
 }
 
 
 {
   return (a & 0xffff);
 }
 
 
-long
-operand_function_HI16U (a)
-     long a;
+static long
+operand_function_HI16U (long a)
 {
   unsigned long b = a & 0xffff0000;
   return (long) (b >> 16);
 {
   unsigned long b = a & 0xffff0000;
   return (long) (b >> 16);
@@ -856,8 +766,7 @@ operand_function_HI16U (a)
 
 
 bfd_boolean
 
 
 bfd_boolean
-xg_has_userdef_op_fn (op)
-     OpType op;
+xg_has_userdef_op_fn (OpType op)
 {
   switch (op)
     {
 {
   switch (op)
     {
@@ -875,9 +784,7 @@ xg_has_userdef_op_fn (op)
 
 
 long
 
 
 long
-xg_apply_userdef_op_fn (op, a)
-     OpType op;
-     long a;
+xg_apply_userdef_op_fn (OpType op, long a)
 {
   switch (op)
     {
 {
   switch (op)
     {
@@ -900,10 +807,8 @@ xg_apply_userdef_op_fn (op, a)
 
 /* Generate a transition table.  */
 
 
 /* Generate a transition table.  */
 
-const char *
-enter_opname_n (name, len)
-     const char *name;
-     int len;
+static const char *
+enter_opname_n (const char *name, int len)
 {
   opname_e *op;
 
 {
   opname_e *op;
 
@@ -913,17 +818,14 @@ enter_opname_n (name, 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;
 }
 
 
 static const char *
   return op->opname;
 }
 
 
 static const char *
-enter_opname (name)
-     const char *name;
+enter_opname (const char *name)
 {
   opname_e *op;
 
 {
   opname_e *op;
 
@@ -932,24 +834,22 @@ enter_opname (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;
 }
 
 
-void
-init_opname_map (m)
-     opname_map *m;
+static void
+init_opname_map (opname_map *m)
 {
   m->head = NULL;
   m->tail = &m->head;
 }
 
 
 {
   m->head = NULL;
   m->tail = &m->head;
 }
 
 
-void
-clear_opname_map (m)
-     opname_map *m;
+static void
+clear_opname_map (opname_map *m)
 {
   opname_map_e *e;
 
 {
   opname_map_e *e;
 
@@ -964,20 +864,16 @@ clear_opname_map (m)
 
 
 static bfd_boolean
 
 
 static bfd_boolean
-same_operand_name (m1, m2)
-     const opname_map_e *m1;
-     const opname_map_e *m2;
+same_operand_name (const opname_map_e *m1, const opname_map_e *m2)
 {
 {
-  if (m1->operand_name == NULL || m1->operand_name == NULL)
+  if (m1->operand_name == NULL || m2->operand_name == NULL)
     return FALSE;
   return (m1->operand_name == m2->operand_name);
 }
 
 
     return FALSE;
   return (m1->operand_name == m2->operand_name);
 }
 
 
-opname_map_e *
-get_opmatch (map, operand_name)
-     opname_map *map;
-     const char *operand_name;
+static opname_map_e *
+get_opmatch (opname_map *map, const char *operand_name)
 {
   opname_map_e *m;
 
 {
   opname_map_e *m;
 
@@ -990,35 +886,31 @@ get_opmatch (map, operand_name)
 }
 
 
 }
 
 
-bfd_boolean
-op_is_constant (m1)
-     const opname_map_e *m1;
+static bfd_boolean
+op_is_constant (const opname_map_e *m1)
 {
   return (m1->operand_name == NULL);
 }
 
 
 static unsigned
 {
   return (m1->operand_name == NULL);
 }
 
 
 static unsigned
-op_get_constant (m1)
-     const opname_map_e *m1;
+op_get_constant (const opname_map_e *m1)
 {
 {
-  assert (m1->operand_name == NULL);
+  gas_assert (m1->operand_name == NULL);
   return m1->constant_value;
 }
 
 
   return m1->constant_value;
 }
 
 
-void
-init_precond_list (l)
-     precond_list *l;
+static void
+init_precond_list (precond_list *l)
 {
   l->head = NULL;
   l->tail = &l->head;
 }
 
 
 {
   l->head = NULL;
   l->tail = &l->head;
 }
 
 
-void
-clear_precond_list (l)
-     precond_list *l;
+static void
+clear_precond_list (precond_list *l)
 {
   precond_e *e;
 
 {
   precond_e *e;
 
@@ -1032,26 +924,23 @@ clear_precond_list (l)
 }
 
 
 }
 
 
-void
-init_insn_templ (t)
-     insn_templ *t;
+static void
+init_insn_templ (insn_templ *t)
 {
   t->opcode_name = NULL;
   init_opname_map (&t->operand_map);
 }
 
 
 {
   t->opcode_name = NULL;
   init_opname_map (&t->operand_map);
 }
 
 
-void
-clear_insn_templ (t)
-     insn_templ *t;
+static void
+clear_insn_templ (insn_templ *t)
 {
   clear_opname_map (&t->operand_map);
 }
 
 
 {
   clear_opname_map (&t->operand_map);
 }
 
 
-void
-init_insn_pattern (p)
-     insn_pattern *p;
+static void
+init_insn_pattern (insn_pattern *p)
 {
   init_insn_templ (&p->t);
   init_precond_list (&p->preconds);
 {
   init_insn_templ (&p->t);
   init_precond_list (&p->preconds);
@@ -1059,27 +948,24 @@ init_insn_pattern (p)
 }
 
 
 }
 
 
-void
-clear_insn_pattern (p)
-     insn_pattern *p;
+static void
+clear_insn_pattern (insn_pattern *p)
 {
   clear_insn_templ (&p->t);
   clear_precond_list (&p->preconds);
 }
 
 
 {
   clear_insn_templ (&p->t);
   clear_precond_list (&p->preconds);
 }
 
 
-void
-init_insn_repl (r)
-     insn_repl *r;
+static void
+init_insn_repl (insn_repl *r)
 {
   r->head = NULL;
   r->tail = &r->head;
 }
 
 
 {
   r->head = NULL;
   r->tail = &r->head;
 }
 
 
-void
-clear_insn_repl (r)
-     insn_repl *r;
+static void
+clear_insn_repl (insn_repl *r)
 {
   insn_repl_e *e;
 
 {
   insn_repl_e *e;
 
@@ -1094,8 +980,7 @@ clear_insn_repl (r)
 
 
 static int
 
 
 static int
-insn_templ_operand_count (t)
-     const insn_templ *t;
+insn_templ_operand_count (const insn_templ *t)
 {
   int i = 0;
   const opname_map_e *op;
 {
   int i = 0;
   const opname_map_e *op;
@@ -1108,10 +993,8 @@ insn_templ_operand_count (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) */
 
-bfd_boolean
-parse_constant (in, val_p)
-     const char *in;
-     unsigned *val_p;
+static bfd_boolean
+parse_constant (const char *in, unsigned *val_p)
 {
   unsigned val = 0;
   const char *p;
 {
   unsigned val = 0;
   const char *p;
@@ -1133,40 +1016,12 @@ parse_constant (in, val_p)
 }
 
 
 }
 
 
-/* Match a pattern like "foo1" with
-   parse_id_constant("foo1", "foo", &num).
-   This may also be used to just match a number.  */
-
-bfd_boolean
-parse_id_constant (in, name, val_p)
-     const char *in;
-     const char *name;
-     unsigned *val_p;
-{
-  unsigned namelen = 0;
-  const char *p;
-
-  if (in == NULL)
-    return FALSE;
-
-  if (name != NULL)
-    namelen = strlen (name);
-
-  if (name != NULL && strncmp (in, name, namelen) != 0)
-    return FALSE;
-
-  p = &in[namelen];
-  return parse_constant (p, val_p);
-}
-
-
 static bfd_boolean
 static bfd_boolean
-parse_special_fn (name, fn_name_p, arg_name_p)
-     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)
 {
 {
-  char *p_start;
+  const char *p_start;
   const char *p_end;
 
   p_start = strchr (name, '(');
   const char *p_end;
 
   p_start = strchr (name, '(');
@@ -1187,9 +1042,8 @@ parse_special_fn (name, fn_name_p, arg_name_p)
 }
 
 
 }
 
 
-const char *
-skip_white (p)
-     const char *p;
+static const char *
+skip_white (const char *p)
 {
   if (p == NULL)
     return p;
 {
   if (p == NULL)
     return p;
@@ -1199,9 +1053,8 @@ skip_white (p)
 }
 
 
 }
 
 
-void
-trim_whitespace (in)
-     char *in;
+static void
+trim_whitespace (char *in)
 {
   char *last_white = NULL;
   char *p = in;
 {
   char *last_white = NULL;
   char *p = in;
@@ -1228,12 +1081,11 @@ trim_whitespace (in)
 /* Split a string into component strings where "c" is the
    delimiter.  Place the result in the split_rec.  */
 
 /* Split a string into component strings where "c" is the
    delimiter.  Place the result in the split_rec.  */
 
-void
-split_string (rec, in, c, elide_whitespace)
-     split_rec *rec;
-     const char *in;
-     char c;
-     bfd_boolean elide_whitespace;
+static void
+split_string (split_rec *rec,
+             const char *in,
+             char c,
+             bfd_boolean elide_whitespace)
 {
   int cnt = 0;
   int i;
 {
   int cnt = 0;
   int i;
@@ -1252,7 +1104,7 @@ split_string (rec, in, c, elide_whitespace)
   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;
 
@@ -1272,9 +1124,7 @@ split_string (rec, in, c, elide_whitespace)
       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++;
        }
 
@@ -1284,9 +1134,8 @@ split_string (rec, in, c, elide_whitespace)
 }
 
 
 }
 
 
-void
-clear_split_rec (rec)
-     split_rec *rec;
+static void
+clear_split_rec (split_rec *rec)
 {
   int i;
 
 {
   int i;
 
@@ -1301,9 +1150,8 @@ clear_split_rec (rec)
 /* Initialize a split record.  The split record must be initialized
    before split_string is called.  */
 
 /* Initialize a split record.  The split record must be initialized
    before split_string is called.  */
 
-void
-init_split_rec (rec)
-     split_rec *rec;
+static void
+init_split_rec (split_rec *rec)
 {
   rec->vec = NULL;
   rec->count = 0;
 {
   rec->vec = NULL;
   rec->count = 0;
@@ -1312,10 +1160,8 @@ init_split_rec (rec)
 
 /* Parse an instruction template like "insn op1, op2, op3".  */
 
 
 /* Parse an instruction template like "insn op1, op2, op3".  */
 
-bfd_boolean
-parse_insn_templ (s, t)
-     const char *s;
-     insn_templ *t;
+static bfd_boolean
+parse_insn_templ (const char *s, insn_templ *t)
 {
   const char *p = s;
   int insn_name_len;
 {
   const char *p = s;
   int insn_name_len;
@@ -1342,7 +1188,7 @@ parse_insn_templ (s, t)
   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;
@@ -1374,10 +1220,8 @@ parse_insn_templ (s, t)
 }
 
 
 }
 
 
-bfd_boolean
-parse_precond (s, precond)
-     const char *s;
-     precond_e *precond;
+static bfd_boolean
+parse_precond (const char *s, precond_e *precond)
 {
   /* All preconditions are currently of the form:
      a == b or a != b or a == k (where k is a constant).
 {
   /* All preconditions are currently of the form:
      a == b or a != b or a == k (where k is a constant).
@@ -1430,9 +1274,8 @@ parse_precond (s, precond)
 }
 
 
 }
 
 
-void
-clear_req_or_option_list (r_p)
-     ReqOrOption **r_p;
+static void
+clear_req_or_option_list (ReqOrOption **r_p)
 {
   if (*r_p == NULL)
     return;
 {
   if (*r_p == NULL)
     return;
@@ -1443,9 +1286,8 @@ clear_req_or_option_list (r_p)
 }
 
 
 }
 
 
-void
-clear_req_option_list (r_p)
-     ReqOption **r_p;
+static void
+clear_req_option_list (ReqOption **r_p)
 {
   if (*r_p == NULL)
     return;
 {
   if (*r_p == NULL)
     return;
@@ -1456,16 +1298,15 @@ clear_req_option_list (r_p)
 }
 
 
 }
 
 
-ReqOrOption *
-clone_req_or_option_list (req_or_option)
-     ReqOrOption *req_or_option;
+static ReqOrOption *
+clone_req_or_option_list (ReqOrOption *req_or_option)
 {
   ReqOrOption *new_req_or_option;
 
   if (req_or_option == NULL)
     return NULL;
 
 {
   ReqOrOption *new_req_or_option;
 
   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;
@@ -1474,29 +1315,26 @@ clone_req_or_option_list (req_or_option)
 }
 
 
 }
 
 
-ReqOption *
-clone_req_option_list (req_option)
-     ReqOption *req_option;
+static ReqOption *
+clone_req_option_list (ReqOption *req_option)
 {
   ReqOption *new_req_option;
 
   if (req_option == NULL)
     return NULL;
 
 {
   ReqOption *new_req_option;
 
   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 = NULL;
   new_req_option->next = NULL;
-  new_req_option->or_option_terms = 
+  new_req_option->or_option_terms =
     clone_req_or_option_list (req_option->or_option_terms);
   new_req_option->next = clone_req_option_list (req_option->next);
   return new_req_option;
 }
 
 
     clone_req_or_option_list (req_option->or_option_terms);
   new_req_option->next = clone_req_option_list (req_option->next);
   return new_req_option;
 }
 
 
-bfd_boolean
-parse_option_cond (s, option)
-     const char *s;
-     ReqOption *option;
+static bfd_boolean
+parse_option_cond (const char *s, ReqOption *option)
 {
   int i;
   split_rec option_term_rec;
 {
   int i;
   split_rec option_term_rec;
@@ -1529,13 +1367,13 @@ parse_option_cond (s, option)
       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;
 
       /* Append to list.  */
       req->option_name = option_name;
       req->is_true = is_true;
       req->next = NULL;
 
       /* Append to list.  */
-      for (r_p = &option->or_option_terms; (*r_p) != NULL; 
+      for (r_p = &option->or_option_terms; (*r_p) != NULL;
           r_p = &(*r_p)->next)
        ;
       (*r_p) = req;
           r_p = &(*r_p)->next)
        ;
       (*r_p) = req;
@@ -1560,10 +1398,8 @@ parse_option_cond (s, 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.  */
 
-bfd_boolean
-parse_insn_pattern (in, insn)
-     const char *in;
-     insn_pattern *insn;
+static bfd_boolean
+parse_insn_pattern (const char *in, insn_pattern *insn)
 {
   split_rec rec;
   split_rec optionrec;
 {
   split_rec rec;
   split_rec optionrec;
@@ -1578,7 +1414,7 @@ parse_insn_pattern (in, insn)
       clear_split_rec (&optionrec);
       return FALSE;
     }
       clear_split_rec (&optionrec);
       return FALSE;
     }
-  
+
   init_split_rec (&rec);
 
   split_string (&rec, optionrec.vec[0], '|', TRUE);
   init_split_rec (&rec);
 
   split_string (&rec, optionrec.vec[0], '|', TRUE);
@@ -1599,7 +1435,7 @@ parse_insn_pattern (in, insn)
 
   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))
        {
 
       if (!parse_precond (rec.vec[i], cond))
        {
@@ -1618,10 +1454,10 @@ parse_insn_pattern (in, 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;
-      
+
       if (!parse_option_cond (optionrec.vec[i], req_option))
        {
          clear_split_rec (&rec);
       if (!parse_option_cond (optionrec.vec[i], req_option))
        {
          clear_split_rec (&rec);
@@ -1644,10 +1480,8 @@ parse_insn_pattern (in, insn)
 }
 
 
 }
 
 
-bfd_boolean
-parse_insn_repl (in, r_p)
-     const char *in;
-     insn_repl *r_p;
+static bfd_boolean
+parse_insn_repl (const char *in, insn_repl *r_p)
 {
   /* This is a list of instruction templates separated by ';'.  */
   split_rec rec;
 {
   /* This is a list of instruction templates separated by ';'.  */
   split_rec rec;
@@ -1657,7 +1491,7 @@ parse_insn_repl (in, r_p)
 
   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;
 
@@ -1674,11 +1508,10 @@ parse_insn_repl (in, r_p)
 }
 
 
 }
 
 
-bfd_boolean
-transition_applies (initial_insn, from_string, to_string)
-     insn_pattern *initial_insn;
-     const char *from_string ATTRIBUTE_UNUSED; 
-     const char *to_string ATTRIBUTE_UNUSED; 
+static bfd_boolean
+transition_applies (insn_pattern *initial_insn,
+                   const char *from_string ATTRIBUTE_UNUSED,
+                   const char *to_string ATTRIBUTE_UNUSED)
 {
   ReqOption *req_option;
 
 {
   ReqOption *req_option;
 
@@ -1692,7 +1525,7 @@ transition_applies (initial_insn, from_string, to_string)
          || req_or_option->next != NULL)
        continue;
 
          || req_or_option->next != NULL)
        continue;
 
-      if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0) 
+      if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0)
        {
          bfd_boolean option_available = FALSE;
          char *option_name = req_or_option->option_name + 6;
        {
          bfd_boolean option_available = FALSE;
          char *option_name = req_or_option->option_name + 6;
@@ -1704,8 +1537,13 @@ transition_applies (initial_insn, from_string, to_string)
            option_available = (XCHAL_HAVE_CONST16 == 1);
          else if (!strcmp (option_name, "Loops"))
            option_available = (XCHAL_HAVE_LOOPS == 1);
            option_available = (XCHAL_HAVE_CONST16 == 1);
          else if (!strcmp (option_name, "Loops"))
            option_available = (XCHAL_HAVE_LOOPS == 1);
+         else if (!strcmp (option_name, "WideBranches"))
+           option_available
+             = (XCHAL_HAVE_WIDE_BRANCHES == 1 && produce_flix == FLIX_ALL);
          else if (!strcmp (option_name, "PredictedBranches"))
          else if (!strcmp (option_name, "PredictedBranches"))
-           option_available = (XCHAL_HAVE_PREDICTED_BRANCHES == 1);
+           option_available
+             = (XCHAL_HAVE_PREDICTED_BRANCHES == 1
+                && produce_flix == FLIX_ALL);
          else if (!strcmp (option_name, "Booleans"))
            option_available = (XCHAL_HAVE_BOOLEANS == 1);
          else
          else if (!strcmp (option_name, "Booleans"))
            option_available = (XCHAL_HAVE_BOOLEANS == 1);
          else
@@ -1716,7 +1554,7 @@ transition_applies (initial_insn, from_string, to_string)
        }
       else if (strcmp (req_or_option->option_name, "realnop") == 0)
        {
        }
       else if (strcmp (req_or_option->option_name, "realnop") == 0)
        {
-         bfd_boolean nop_available = 
+         bfd_boolean 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)
@@ -1727,35 +1565,55 @@ transition_applies (initial_insn, from_string, to_string)
 }
 
 
 }
 
 
-TransitionRule *
-build_transition (initial_insn, replace_insns, from_string, to_string)
-     insn_pattern *initial_insn;
-     insn_repl *replace_insns;
-     const char *from_string;
-     const char *to_string;
+static bfd_boolean
+wide_branch_opcode (const char *opcode_name,
+                   const char *suffix,
+                   xtensa_opcode *popcode)
+{
+  xtensa_isa isa = xtensa_default_isa;
+  xtensa_opcode opcode;
+  static char wbr_name_buf[20];
+
+  if (strncmp (opcode_name, "WIDE.", 5) != 0)
+    return FALSE;
+
+  strcpy (wbr_name_buf, opcode_name + 5);
+  strcat (wbr_name_buf, suffix);
+  opcode = xtensa_opcode_lookup (isa, wbr_name_buf);
+  if (opcode != XTENSA_UNDEFINED)
+    {
+      *popcode = opcode;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+static TransitionRule *
+build_transition (insn_pattern *initial_insn,
+                 insn_repl *replace_insns,
+                 const char *from_string,
+                 const char *to_string)
 {
   TransitionRule *tr = NULL;
   xtensa_opcode opcode;
   xtensa_isa isa = xtensa_default_isa;
 {
   TransitionRule *tr = NULL;
   xtensa_opcode opcode;
   xtensa_isa isa = xtensa_default_isa;
+  BuildInstr *literal_bi;
 
   opname_map_e *op1;
   opname_map_e *op2;
 
   precond_e *precond;
   insn_repl_e *r;
 
   opname_map_e *op1;
   opname_map_e *op2;
 
   precond_e *precond;
   insn_repl_e *r;
-  unsigned label_count = 0;
-  unsigned max_label_count = 0;
-  bfd_boolean has_label = FALSE;
-  unsigned literal_count = 0;
 
 
-  opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
+  if (!wide_branch_opcode (initial_insn->t.opcode_name, ".w18", &opcode)
+      && !wide_branch_opcode (initial_insn->t.opcode_name, ".w15", &opcode))
+    opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
+
   if (opcode == XTENSA_UNDEFINED)
     {
       /* It is OK to not be able to translate some of these opcodes.  */
   if (opcode == XTENSA_UNDEFINED)
     {
       /* It is OK to not be able to translate some of these opcodes.  */
-#if 0
-      as_warn (_("invalid opcode '%s' in transition rule '%s'"),
-              initial_insn->t.opcode_name, from_string);
-#endif
       return NULL;
     }
 
       return NULL;
     }
 
@@ -1766,16 +1624,10 @@ build_transition (initial_insn, replace_insns, from_string, to_string)
       /* This is also OK because there are opcodes that
         have different numbers of operands on different
         architecture variations.  */
       /* This is also OK because there are opcodes that
         have different numbers of operands on different
         architecture variations.  */
-#if 0
-      as_fatal (_("opcode %s mismatched operand count %d != expected %d"),
-               xtensa_opcode_name (isa, opcode),
-               xtensa_num_operands (isa, opcode),
-               insn_templ_operand_count (&initial_insn->t));
-#endif
       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;
@@ -1820,35 +1672,26 @@ build_transition (initial_insn, replace_insns, from_string, to_string)
        {
          op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
          if (op1 == NULL)
        {
          op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
          if (op1 == NULL)
-           {
-             as_fatal (_("opcode '%s': no bound opname '%s' "
-                         "for precondition in '%s'"),
-                       xtensa_opcode_name (isa, opcode),
-                       precond->opname1, from_string);
-             return NULL;
-           }
+           as_fatal (_("opcode '%s': no bound opname '%s' "
+                       "for precondition in '%s'"),
+                     xtensa_opcode_name (isa, opcode),
+                     precond->opname1, from_string);
        }
 
       if (precond->opname2)
        {
          op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
          if (op2 == NULL)
        }
 
       if (precond->opname2)
        {
          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"),
-                      xtensa_opcode_name (isa, opcode),
-                      precond->opname2, from_string);
-             return NULL;
-           }
+           as_fatal (_("opcode '%s': no bound opname '%s' "
+                       "for precondition in %s"),
+                     xtensa_opcode_name (isa, opcode),
+                     precond->opname2, from_string);
        }
 
       if (op1 == NULL && op2 == NULL)
        }
 
       if (op1 == NULL && op2 == NULL)
-       {
-         as_fatal (_("opcode '%s': precondition only contains "
-                     "constants in '%s'"),
-                   xtensa_opcode_name (isa, opcode), from_string);
-         return NULL;
-       }
+       as_fatal (_("opcode '%s': precondition only contains "
+                   "constants in '%s'"),
+                 xtensa_opcode_name (isa, opcode), from_string);
       else if (op1 != NULL && op2 != NULL)
        append_value_condition (tr, precond->cmpop,
                                op1->operand_num, op2->operand_num);
       else if (op1 != NULL && op2 != NULL)
        append_value_condition (tr, precond->cmpop,
                                op1->operand_num, op2->operand_num);
@@ -1863,27 +1706,25 @@ build_transition (initial_insn, replace_insns, from_string, to_string)
   tr->options = clone_req_option_list (initial_insn->options);
 
   /* Generate the replacement instructions.  Some of these
   tr->options = clone_req_option_list (initial_insn->options);
 
   /* Generate the replacement instructions.  Some of these
-     "instructions" are actually labels and literals.  The literals
-     must be defined in order 0..n and a literal must be defined
-     (e.g., "LITERAL0 %imm") before use (e.g., "%LITERAL0").  The
-     labels must be defined in order, but they can be used before they
-     are defined.  Also there are a number of special operands (e.g.,
-     HI24S).  */
+     "instructions" are actually labels and literals.  There can be at
+     most one literal and at most one label.  A literal must be defined
+     (e.g., "LITERAL %imm") before use (e.g., "%LITERAL").  The labels
+     can be used before they are defined.  Also there are a number of
+     special operands (e.g., HI24S).  */
 
 
+  literal_bi = NULL;
   for (r = replace_insns->head; r != NULL; r = r->next)
     {
       BuildInstr *bi;
       const char *opcode_name;
       int operand_count;
       opname_map_e *op;
   for (r = replace_insns->head; r != NULL; r = r->next)
     {
       BuildInstr *bi;
       const char *opcode_name;
       int operand_count;
       opname_map_e *op;
-      unsigned idnum = 0;
       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);
 
       append_build_insn (tr, bi);
 
-      bi->id = 0;
       bi->opcode = XTENSA_UNDEFINED;
       bi->ops = NULL;
       bi->next = NULL;
       bi->opcode = XTENSA_UNDEFINED;
       bi->ops = NULL;
       bi->next = NULL;
@@ -1891,39 +1732,37 @@ build_transition (initial_insn, replace_insns, from_string, to_string)
       opcode_name = r->t.opcode_name;
       operand_count = insn_templ_operand_count (&r->t);
 
       opcode_name = r->t.opcode_name;
       operand_count = insn_templ_operand_count (&r->t);
 
-      if (parse_id_constant (opcode_name, "LITERAL", &idnum))
+      if (strcmp (opcode_name, "LITERAL") == 0)
        {
          bi->typ = INSTR_LITERAL_DEF;
        {
          bi->typ = INSTR_LITERAL_DEF;
-         bi->id = idnum;
-         if (idnum != literal_count)
-           as_fatal (_("generated literals must be numbered consecutively"));
-         ++literal_count;
          if (operand_count != 1)
            as_fatal (_("expected one operand for generated literal"));
          if (operand_count != 1)
            as_fatal (_("expected one operand for generated literal"));
-
+         literal_bi = bi;
        }
        }
-      else if (parse_id_constant (opcode_name, "LABEL", &idnum))
+      else if (strcmp (opcode_name, "LABEL") == 0)
        {
          bi->typ = INSTR_LABEL_DEF;
        {
          bi->typ = INSTR_LABEL_DEF;
-         bi->id = idnum;
-         if (idnum != label_count)
-           as_fatal (_("generated labels must be numbered consecutively"));
-         ++label_count;
          if (operand_count != 0)
            as_fatal (_("expected 0 operands for generated label"));
        }
       else
        {
          bi->typ = INSTR_INSTR;
          if (operand_count != 0)
            as_fatal (_("expected 0 operands for generated label"));
        }
       else
        {
          bi->typ = INSTR_INSTR;
-         bi->opcode = xtensa_opcode_lookup (isa, r->t.opcode_name);
+         if (wide_branch_opcode (opcode_name, ".w18", &bi->opcode)
+             || wide_branch_opcode (opcode_name, ".w15", &bi->opcode))
+           opcode_name = xtensa_opcode_name (isa, bi->opcode);
+         else
+           bi->opcode = xtensa_opcode_lookup (isa, opcode_name);
+
          if (bi->opcode == XTENSA_UNDEFINED)
            {
              as_warn (_("invalid opcode '%s' in transition rule '%s'"),
          if (bi->opcode == XTENSA_UNDEFINED)
            {
              as_warn (_("invalid opcode '%s' in transition rule '%s'"),
-                      r->t.opcode_name, to_string);
+                      opcode_name, to_string);
              return NULL;
            }
              return NULL;
            }
+
          /* Check for the right number of ops.  */
          /* Check for the right number of ops.  */
-         if (xtensa_opcode_num_operands (isa, bi->opcode) 
+         if (xtensa_opcode_num_operands (isa, bi->opcode)
              != (int) operand_count)
            as_fatal (_("opcode '%s': replacement does not have %d ops"),
                      opcode_name,
              != (int) operand_count)
            as_fatal (_("opcode '%s': replacement does not have %d ops"),
                      opcode_name,
@@ -1936,22 +1775,18 @@ build_transition (initial_insn, replace_insns, from_string, to_string)
 
          if (op_is_constant (op))
            append_constant_op (bi, op->operand_num, op_get_constant (op));
 
          if (op_is_constant (op))
            append_constant_op (bi, op->operand_num, op_get_constant (op));
-         else if (parse_id_constant (op->operand_name, "%LITERAL", &idnum))
-           {
-             if (idnum >= literal_count)
-               as_fatal (_("opcode %s: replacement "
-                           "literal %d >= literal_count(%d)"),
-                         opcode_name, idnum, literal_count);
-             append_literal_op (bi, op->operand_num, idnum);
-           }
-         else if (parse_id_constant (op->operand_name, "%LABEL", &idnum))
+         else if (strcmp (op->operand_name, "%LITERAL") == 0)
            {
            {
-             has_label = TRUE;
-             if (idnum > max_label_count)
-               max_label_count = idnum;
-             append_label_op (bi, op->operand_num, idnum);
+             if (! literal_bi || ! literal_bi->ops || literal_bi->ops->next)
+               as_fatal (_("opcode '%s': cannot find literal definition"),
+                         opcode_name);
+             append_literal_op (bi, op->operand_num,
+                                literal_bi->ops->op_data);
            }
            }
-         else if (parse_id_constant (op->operand_name, "a", &idnum))
+         else if (strcmp (op->operand_name, "%LABEL") == 0)
+           append_label_op (bi, op->operand_num);
+         else if (op->operand_name[0] == 'a'
+                  && parse_constant (op->operand_name + 1, &idnum))
            append_constant_op (bi, op->operand_num, idnum);
          else if (op->operand_name[0] == '%')
            {
            append_constant_op (bi, op->operand_num, idnum);
          else if (op->operand_name[0] == '%')
            {
@@ -1959,14 +1794,13 @@ build_transition (initial_insn, replace_insns, from_string, to_string)
              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'"),
-                           opcode_name, op->operand_name, to_string);
-
-                 append_constant_op (bi, op->operand_num, 0);
-               }
-             else
-               append_field_op (bi, op->operand_num, orig_op->operand_num);
+               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);
+           }
+         else if (strcmp (op->operand_name, "FREEREG") == 0)
+           {
+             append_user_fn_field_op (bi, op->operand_num, OP_FREEREG, 0);
            }
          else if (parse_special_fn (op->operand_name,
                                     &fn_name, &operand_arg_name))
            }
          else if (parse_special_fn (op->operand_name,
                                     &fn_name, &operand_arg_name))
@@ -1990,40 +1824,25 @@ build_transition (initial_insn, replace_insns, from_string, to_string)
              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'"),
-                           opcode_name, op->operand_name, to_string);
-                 append_constant_op (bi, op->operand_num, 0);
-               }
-             else
-               append_user_fn_field_op (bi, op->operand_num,
-                                        typ, orig_op->operand_num);
+               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
            }
          else
-           {
-             as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
-                       opcode_name, op->operand_name, to_string);
-             append_constant_op (bi, op->operand_num, 0);
-           }
+           as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
+                     opcode_name, op->operand_name, to_string);
        }
     }
        }
     }
-  if (has_label && max_label_count >= label_count)
-    {
-      as_fatal (_("opcode %s: replacement label %d >= label_count(%d)"),
-               xtensa_opcode_name (isa, opcode),
-               max_label_count, label_count);
-      return NULL;
-    }
 
   return tr;
 }
 
 
 
   return tr;
 }
 
 
-TransitionTable *
-build_transition_table (transitions, transition_count, cmp)
-     const string_pattern_pair *transitions;
-     int transition_count;
-     transition_cmp_fn cmp;
+static TransitionTable *
+build_transition_table (const string_pattern_pair *transitions,
+                       int transition_count,
+                       transition_cmp_fn cmp)
 {
   TransitionTable *table = NULL;
   int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
 {
   TransitionTable *table = NULL;
   int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
@@ -2033,10 +1852,9 @@ build_transition_table (transitions, transition_count, cmp)
     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;
@@ -2052,20 +1870,11 @@ build_transition_table (transitions, transition_count, cmp)
 
       init_insn_pattern (&initial_insn);
       if (!parse_insn_pattern (from_string, &initial_insn))
 
       init_insn_pattern (&initial_insn);
       if (!parse_insn_pattern (from_string, &initial_insn))
-       {
-         as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
-         clear_insn_pattern (&initial_insn);
-         continue;
-       }
+       as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
 
       init_insn_repl (&replace_insns);
       if (!parse_insn_repl (to_string, &replace_insns))
 
       init_insn_repl (&replace_insns);
       if (!parse_insn_repl (to_string, &replace_insns))
-       {
-         as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
-         clear_insn_pattern (&initial_insn);
-         clear_insn_repl (&replace_insns);
-         continue;
-       }
+       as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
 
       if (transition_applies (&initial_insn, from_string, to_string))
        {
 
       if (transition_applies (&initial_insn, from_string, to_string))
        {
@@ -2090,8 +1899,7 @@ build_transition_table (transitions, transition_count, cmp)
 
 \f
 extern TransitionTable *
 
 \f
 extern TransitionTable *
-xg_build_widen_table (cmp)
-     transition_cmp_fn cmp;
+xg_build_widen_table (transition_cmp_fn cmp)
 {
   static TransitionTable *table = NULL;
   if (table == NULL)
 {
   static TransitionTable *table = NULL;
   if (table == NULL)
@@ -2101,8 +1909,7 @@ xg_build_widen_table (cmp)
 
 
 extern TransitionTable *
 
 
 extern TransitionTable *
-xg_build_simplify_table (cmp)
-     transition_cmp_fn cmp;
+xg_build_simplify_table (transition_cmp_fn cmp)
 {
   static TransitionTable *table = NULL;
   if (table == NULL)
 {
   static TransitionTable *table = NULL;
   if (table == NULL)
This page took 0.05098 seconds and 4 git commands to generate.