/* tc-xtensa.c -- Assemble Xtensa instructions.
   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
   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,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   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, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "as.h"
#include <limits.h>
#include "sb.h"
#include "safe-ctype.h"
#include "tc-xtensa.h"
#include "subsegs.h"
#include "xtensa-relax.h"
#include "dwarf2dbg.h"
#include "xtensa-istack.h"
#include "struc-symbol.h"
#include "xtensa-config.h"
#include "elf/xtensa.h"

/* Provide default values for new configuration settings.  */
#ifndef XSHAL_ABI
#define XSHAL_ABI 0
#endif

#ifndef uint32
#define uint32 unsigned int
#endif
#ifndef int32
#define int32 signed int
#endif

/* Notes:

   Naming conventions (used somewhat inconsistently):
      The xtensa_ functions are exported
      The xg_ functions are internal

   We also have a couple of different extensibility mechanisms.
   1) The idiom replacement:
      This is used when a line is first parsed to
      replace an instruction pattern with another instruction
      It is currently limited to replacements of instructions
      with constant operands.
   2) The xtensa-relax.c mechanism that has stronger instruction
      replacement patterns.  When an instruction's immediate field
      does not fit the next instruction sequence is attempted.
      In addition, "narrow" opcodes are supported this way.  */


/* Define characters with special meanings to GAS.  */
const char comment_chars[] = "#";
const char line_comment_chars[] = "#";
const char line_separator_chars[] = ";";
const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "rRsSfFdDxXpP";


/* Flags to indicate whether the hardware supports the density and
   absolute literals options.  */

bfd_boolean density_supported = XCHAL_HAVE_DENSITY;
bfd_boolean absolute_literals_supported = XSHAL_USE_ABSOLUTE_LITERALS;

static vliw_insn cur_vinsn;

unsigned xtensa_num_pipe_stages;
unsigned xtensa_fetch_width = XCHAL_INST_FETCH_WIDTH;

static enum debug_info_type xt_saved_debug_type = DEBUG_NONE;

/* Some functions are only valid in the front end.  This variable
   allows us to assert that we haven't crossed over into the
   back end.  */
static bfd_boolean past_xtensa_end = FALSE;

/* Flags for properties of the last instruction in a segment.  */
#define FLAG_IS_A0_WRITER	0x1
#define FLAG_IS_BAD_LOOPEND	0x2


/* We define a special segment names ".literal" to place literals
   into.  The .fini and .init sections are special because they
   contain code that is moved together by the linker.  We give them
   their own special .fini.literal and .init.literal sections.  */

#define LITERAL_SECTION_NAME		xtensa_section_rename (".literal")
#define LIT4_SECTION_NAME		xtensa_section_rename (".lit4")
#define INIT_SECTION_NAME		xtensa_section_rename (".init")
#define FINI_SECTION_NAME		xtensa_section_rename (".fini")


/* This type is used for the directive_stack to keep track of the
   state of the literal collection pools.  If lit_prefix is set, it is
   used to determine the literal section names; otherwise, the literal
   sections are determined based on the current text section.  The
   lit_seg and lit4_seg fields cache these literal sections, with the
   current_text_seg field used a tag to indicate whether the cached
   values are valid.  */

typedef struct lit_state_struct
{
  char *lit_prefix;
  segT current_text_seg;
  segT lit_seg;
  segT lit4_seg;
} lit_state;

static lit_state default_lit_sections;


/* We keep a list of literal segments.  The seg_list type is the node
   for this list.  The literal_head pointer is the head of the list,
   with the literal_head_h dummy node at the start.  */

typedef struct seg_list_struct
{
  struct seg_list_struct *next;
  segT seg;
} seg_list;

static seg_list literal_head_h;
static seg_list *literal_head = &literal_head_h;


/* Lists of symbols.  We keep a list of symbols that label the current
   instruction, so that we can adjust the symbols when inserting alignment
   for various instructions.  We also keep a list of all the symbols on
   literals, so that we can fix up those symbols when the literals are
   later moved into the text sections.  */

typedef struct sym_list_struct
{
  struct sym_list_struct *next;
  symbolS *sym;
} sym_list;

static sym_list *insn_labels = NULL;
static sym_list *free_insn_labels = NULL;
static sym_list *saved_insn_labels = NULL;

static sym_list *literal_syms;


/* Flags to determine whether to prefer const16 or l32r
   if both options are available.  */
int prefer_const16 = 0;
int prefer_l32r = 0;

/* Global flag to indicate when we are emitting literals.  */
int generating_literals = 0;

/* The following PROPERTY table definitions are copied from
   <elf/xtensa.h> and must be kept in sync with the code there.  */

/* Flags in the property tables to specify whether blocks of memory
   are literals, instructions, data, or unreachable.  For
   instructions, blocks that begin loop targets and branch targets are
   designated.  Blocks that do not allow density, instruction
   reordering or transformation are also specified.  Finally, for
   branch targets, branch target alignment priority is included.
   Alignment of the next block is specified in the current block
   and the size of the current block does not include any fill required
   to align to the next block.  */

#define XTENSA_PROP_LITERAL		0x00000001
#define XTENSA_PROP_INSN		0x00000002
#define XTENSA_PROP_DATA		0x00000004
#define XTENSA_PROP_UNREACHABLE		0x00000008
/* Instruction only properties at beginning of code.  */
#define XTENSA_PROP_INSN_LOOP_TARGET	0x00000010
#define XTENSA_PROP_INSN_BRANCH_TARGET	0x00000020
/* Instruction only properties about code.  */
#define XTENSA_PROP_INSN_NO_DENSITY	0x00000040
#define XTENSA_PROP_INSN_NO_REORDER	0x00000080
/* Historically, NO_TRANSFORM was a property of instructions,
   but it should apply to literals under certain circumstances.  */
#define XTENSA_PROP_NO_TRANSFORM	0x00000100

/*  Branch target alignment information.  This transmits information
    to the linker optimization about the priority of aligning a
    particular block for branch target alignment: None, low priority,
    high priority, or required.  These only need to be checked in
    instruction blocks marked as XTENSA_PROP_INSN_BRANCH_TARGET.
    Common usage is

    switch (GET_XTENSA_PROP_BT_ALIGN (flags))
    case XTENSA_PROP_BT_ALIGN_NONE:
    case XTENSA_PROP_BT_ALIGN_LOW:
    case XTENSA_PROP_BT_ALIGN_HIGH:
    case XTENSA_PROP_BT_ALIGN_REQUIRE:
*/
#define XTENSA_PROP_BT_ALIGN_MASK       0x00000600

/* No branch target alignment.  */
#define XTENSA_PROP_BT_ALIGN_NONE       0x0
/* Low priority branch target alignment.  */
#define XTENSA_PROP_BT_ALIGN_LOW        0x1
/* High priority branch target alignment.  */
#define XTENSA_PROP_BT_ALIGN_HIGH       0x2
/* Required branch target alignment.  */
#define XTENSA_PROP_BT_ALIGN_REQUIRE    0x3

#define SET_XTENSA_PROP_BT_ALIGN(flag, align) \
  (((flag) & (~XTENSA_PROP_BT_ALIGN_MASK)) | \
    (((align) << 9) & XTENSA_PROP_BT_ALIGN_MASK))


/* Alignment is specified in the block BEFORE the one that needs
   alignment.  Up to 5 bits.  Use GET_XTENSA_PROP_ALIGNMENT(flags) to
   get the required alignment specified as a power of 2.  Use
   SET_XTENSA_PROP_ALIGNMENT(flags, pow2) to set the required
   alignment.  Be careful of side effects since the SET will evaluate
   flags twice.  Also, note that the SIZE of a block in the property
   table does not include the alignment size, so the alignment fill
   must be calculated to determine if two blocks are contiguous.
   TEXT_ALIGN is not currently implemented but is a placeholder for a
   possible future implementation.  */

#define XTENSA_PROP_ALIGN		0x00000800

#define XTENSA_PROP_ALIGNMENT_MASK      0x0001f000

#define SET_XTENSA_PROP_ALIGNMENT(flag, align) \
  (((flag) & (~XTENSA_PROP_ALIGNMENT_MASK)) | \
    (((align) << 12) & XTENSA_PROP_ALIGNMENT_MASK))

#define XTENSA_PROP_INSN_ABSLIT 0x00020000


/* Structure for saving instruction and alignment per-fragment data
   that will be written to the object file.  This structure is
   equivalent to the actual data that will be written out to the file
   but is easier to use.   We provide a conversion to file flags
   in frag_flags_to_number.  */

typedef struct frag_flags_struct frag_flags;

struct frag_flags_struct
{
  /* is_literal should only be used after xtensa_move_literals.
     If you need to check if you are generating a literal fragment,
     then use the generating_literals global.  */

  unsigned is_literal : 1;
  unsigned is_insn : 1;
  unsigned is_data : 1;
  unsigned is_unreachable : 1;

  /* is_specific_opcode implies no_transform.  */
  unsigned is_no_transform : 1;

  struct
  {
    unsigned is_loop_target : 1;
    unsigned is_branch_target : 1; /* Branch targets have a priority.  */
    unsigned bt_align_priority : 2;

    unsigned is_no_density : 1;
    /* no_longcalls flag does not need to be placed in the object file.  */

    unsigned is_no_reorder : 1;

    /* Uses absolute literal addressing for l32r.  */
    unsigned is_abslit : 1;
  } insn;
  unsigned is_align : 1;
  unsigned alignment : 5;
};


/* Structure for saving information about a block of property data
   for frags that have the same flags.  */
struct xtensa_block_info_struct
{
  segT sec;
  bfd_vma offset;
  size_t size;
  frag_flags flags;
  struct xtensa_block_info_struct *next;
};


/* Structure for saving the current state before emitting literals.  */
typedef struct emit_state_struct
{
  const char *name;
  segT now_seg;
  subsegT now_subseg;
  int generating_literals;
} emit_state;


/* Opcode placement information */

typedef unsigned long long bitfield;
#define bit_is_set(bit, bf)	((bf) & (0x01ll << (bit)))
#define set_bit(bit, bf)	((bf) |= (0x01ll << (bit)))
#define clear_bit(bit, bf)	((bf) &= ~(0x01ll << (bit)))

#define MAX_FORMATS 32

typedef struct op_placement_info_struct
{
  int num_formats;
  /* A number describing how restrictive the issue is for this
     opcode.  For example, an opcode that fits lots of different
     formats has a high freedom, as does an opcode that fits
     only one format but many slots in that format.  The most
     restrictive is the opcode that fits only one slot in one
     format.  */
  int issuef;
  xtensa_format narrowest;
  char narrowest_size;
  char narrowest_slot;

  /* formats is a bitfield with the Nth bit set
     if the opcode fits in the Nth xtensa_format.  */
  bitfield formats;

  /* slots[N]'s Mth bit is set if the op fits in the
     Mth slot of the Nth xtensa_format.  */
  bitfield slots[MAX_FORMATS];

  /* A count of the number of slots in a given format
     an op can fit (i.e., the bitcount of the slot field above).  */
  char slots_in_format[MAX_FORMATS];

} op_placement_info, *op_placement_info_table;

op_placement_info_table op_placement_table;


/* Extra expression types.  */

#define O_pltrel	O_md1	/* like O_symbol but use a PLT reloc */
#define O_hi16		O_md2	/* use high 16 bits of symbolic value */
#define O_lo16		O_md3	/* use low 16 bits of symbolic value */
#define O_pcrel		O_md4	/* value is a PC-relative offset */
#define O_tlsfunc	O_md5	/* TLS_FUNC/TLSDESC_FN relocation */
#define O_tlsarg	O_md6	/* TLS_ARG/TLSDESC_ARG relocation */
#define O_tlscall	O_md7	/* TLS_CALL relocation */
#define O_tpoff		O_md8	/* TPOFF relocation */
#define O_dtpoff	O_md9	/* DTPOFF relocation */

struct suffix_reloc_map
{
  const char *suffix;
  int length;
  bfd_reloc_code_real_type reloc;
  operatorT operator;
};

#define SUFFIX_MAP(str, reloc, op) { str, sizeof (str) - 1, reloc, op }

static struct suffix_reloc_map suffix_relocs[] =
{
  SUFFIX_MAP ("l",	BFD_RELOC_LO16,			O_lo16),
  SUFFIX_MAP ("h",	BFD_RELOC_HI16,			O_hi16),
  SUFFIX_MAP ("plt",	BFD_RELOC_XTENSA_PLT,		O_pltrel),
  SUFFIX_MAP ("pcrel",	BFD_RELOC_32_PCREL,		O_pcrel),
  SUFFIX_MAP ("tlsfunc", BFD_RELOC_XTENSA_TLS_FUNC,	O_tlsfunc),
  SUFFIX_MAP ("tlsarg",	BFD_RELOC_XTENSA_TLS_ARG,	O_tlsarg),
  SUFFIX_MAP ("tlscall", BFD_RELOC_XTENSA_TLS_CALL,	O_tlscall),
  SUFFIX_MAP ("tpoff",	BFD_RELOC_XTENSA_TLS_TPOFF,	O_tpoff),
  SUFFIX_MAP ("dtpoff",	BFD_RELOC_XTENSA_TLS_DTPOFF,	O_dtpoff),
};


/* Directives.  */

typedef enum
{
  directive_none = 0,
  directive_literal,
  directive_density,
  directive_transform,
  directive_freeregs,
  directive_longcalls,
  directive_literal_prefix,
  directive_schedule,
  directive_absolute_literals,
  directive_last_directive
} directiveE;

typedef struct
{
  const char *name;
  bfd_boolean can_be_negated;
} directive_infoS;

const directive_infoS directive_info[] =
{
  { "none",		FALSE },
  { "literal",		FALSE },
  { "density",		TRUE },
  { "transform",	TRUE },
  { "freeregs",		FALSE },
  { "longcalls",	TRUE },
  { "literal_prefix",	FALSE },
  { "schedule",		TRUE },
  { "absolute-literals", TRUE }
};

bfd_boolean directive_state[] =
{
  FALSE,			/* none */
  FALSE,			/* literal */
#if !XCHAL_HAVE_DENSITY
  FALSE,			/* density */
#else
  TRUE,				/* density */
#endif
  TRUE,				/* transform */
  FALSE,			/* freeregs */
  FALSE,			/* longcalls */
  FALSE,			/* literal_prefix */
  FALSE,			/* schedule */
#if XSHAL_USE_ABSOLUTE_LITERALS
  TRUE				/* absolute_literals */
#else
  FALSE				/* absolute_literals */
#endif
};

/* A circular list of all potential and actual literal pool locations
   in a segment.  */
struct litpool_frag
{
  struct litpool_frag *next;
  struct litpool_frag *prev;
  fragS *fragP;
  addressT addr;
  short priority; /* 1, 2, or 3 -- 1 is highest  */
  short original_priority;
};

/* Map a segment to its litpool_frag list.  */
struct litpool_seg
{
  struct litpool_seg *next;
  asection *seg;
  struct litpool_frag frag_list;
  int frag_count; /* since last litpool location  */
};

static struct litpool_seg litpool_seg_list;


/* Directive functions.  */

static void xtensa_begin_directive (int);
static void xtensa_end_directive (int);
static void xtensa_literal_prefix (void);
static void xtensa_literal_position (int);
static void xtensa_literal_pseudo (int);
static void xtensa_frequency_pseudo (int);
static void xtensa_elf_cons (int);
static void xtensa_leb128 (int);

/* Parsing and Idiom Translation.  */

static bfd_reloc_code_real_type xtensa_elf_suffix (char **, expressionS *);

/* Various Other Internal Functions.  */

extern bfd_boolean xg_is_single_relaxable_insn (TInsn *, TInsn *, bfd_boolean);
static bfd_boolean xg_build_to_insn (TInsn *, TInsn *, BuildInstr *);
static void xtensa_mark_literal_pool_location (void);
static addressT get_expanded_loop_offset (xtensa_opcode);
static fragS *get_literal_pool_location (segT);
static void set_literal_pool_location (segT, fragS *);
static void xtensa_set_frag_assembly_state (fragS *);
static void finish_vinsn (vliw_insn *);
static bfd_boolean emit_single_op (TInsn *);
static int total_frag_text_expansion (fragS *);
static bfd_boolean use_trampolines = TRUE;
static void xtensa_check_frag_count (void);
static void xtensa_create_trampoline_frag (bfd_boolean);
static void xtensa_maybe_create_trampoline_frag (void);
struct trampoline_frag;
static int init_trampoline_frag (struct trampoline_frag *);
static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean);
static bfd_boolean auto_litpools = FALSE;
static int auto_litpool_limit = 10000;

/* Alignment Functions.  */

static int get_text_align_power (unsigned);
static int get_text_align_max_fill_size (int, bfd_boolean, bfd_boolean);
static int branch_align_power (segT);

/* Helpers for xtensa_relax_frag().  */

static long relax_frag_add_nop (fragS *);

/* Accessors for additional per-subsegment information.  */

static unsigned get_last_insn_flags (segT, subsegT);
static void set_last_insn_flags (segT, subsegT, unsigned, bfd_boolean);
static float get_subseg_total_freq (segT, subsegT);
static float get_subseg_target_freq (segT, subsegT);
static void set_subseg_freq (segT, subsegT, float, float);

/* Segment list functions.  */

static void xtensa_move_literals (void);
static void xtensa_reorder_segments (void);
static void xtensa_switch_to_literal_fragment (emit_state *);
static void xtensa_switch_to_non_abs_literal_fragment (emit_state *);
static void xtensa_switch_section_emit_state (emit_state *, segT, subsegT);
static void xtensa_restore_emit_state (emit_state *);
static segT cache_literal_section (bfd_boolean);

/* op_placement_info functions.  */

static void init_op_placement_info_table (void);
extern bfd_boolean opcode_fits_format_slot (xtensa_opcode, xtensa_format, int);
static int xg_get_single_size (xtensa_opcode);
static xtensa_format xg_get_single_format (xtensa_opcode);
static int xg_get_single_slot (xtensa_opcode);

/* TInsn and IStack functions.  */

static bfd_boolean tinsn_has_symbolic_operands (const TInsn *);
static bfd_boolean tinsn_has_invalid_symbolic_operands (const TInsn *);
static bfd_boolean tinsn_has_complex_operands (const TInsn *);
static bfd_boolean tinsn_to_insnbuf (TInsn *, xtensa_insnbuf);
static bfd_boolean tinsn_check_arguments (const TInsn *);
static void tinsn_from_chars (TInsn *, char *, int);
static void tinsn_immed_from_frag (TInsn *, fragS *, int);
static int get_num_stack_text_bytes (IStack *);
static int get_num_stack_literal_bytes (IStack *);
static bfd_boolean tinsn_to_slotbuf (xtensa_format, int, TInsn *, xtensa_insnbuf);

/* vliw_insn functions.  */

static void xg_init_vinsn (vliw_insn *);
static void xg_copy_vinsn (vliw_insn *, vliw_insn *);
static void xg_clear_vinsn (vliw_insn *);
static bfd_boolean vinsn_has_specific_opcodes (vliw_insn *);
static void xg_free_vinsn (vliw_insn *);
static bfd_boolean vinsn_to_insnbuf
  (vliw_insn *, char *, fragS *, bfd_boolean);
static void vinsn_from_chars (vliw_insn *, char *);

/* Expression Utilities.  */

bfd_boolean expr_is_const (const expressionS *);
offsetT get_expr_const (const expressionS *);
void set_expr_const (expressionS *, offsetT);
bfd_boolean expr_is_register (const expressionS *);
offsetT get_expr_register (const expressionS *);
void set_expr_symbol_offset (expressionS *, symbolS *, offsetT);
bfd_boolean expr_is_equal (expressionS *, expressionS *);
static void copy_expr (expressionS *, const expressionS *);

/* Section renaming.  */

static void build_section_rename (const char *);


/* ISA imported from bfd.  */
extern xtensa_isa xtensa_default_isa;

extern int target_big_endian;

static xtensa_opcode xtensa_addi_opcode;
static xtensa_opcode xtensa_addmi_opcode;
static xtensa_opcode xtensa_call0_opcode;
static xtensa_opcode xtensa_call4_opcode;
static xtensa_opcode xtensa_call8_opcode;
static xtensa_opcode xtensa_call12_opcode;
static xtensa_opcode xtensa_callx0_opcode;
static xtensa_opcode xtensa_callx4_opcode;
static xtensa_opcode xtensa_callx8_opcode;
static xtensa_opcode xtensa_callx12_opcode;
static xtensa_opcode xtensa_const16_opcode;
static xtensa_opcode xtensa_entry_opcode;
static xtensa_opcode xtensa_extui_opcode;
static xtensa_opcode xtensa_movi_opcode;
static xtensa_opcode xtensa_movi_n_opcode;
static xtensa_opcode xtensa_isync_opcode;
static xtensa_opcode xtensa_j_opcode;
static xtensa_opcode xtensa_jx_opcode;
static xtensa_opcode xtensa_l32r_opcode;
static xtensa_opcode xtensa_loop_opcode;
static xtensa_opcode xtensa_loopnez_opcode;
static xtensa_opcode xtensa_loopgtz_opcode;
static xtensa_opcode xtensa_nop_opcode;
static xtensa_opcode xtensa_nop_n_opcode;
static xtensa_opcode xtensa_or_opcode;
static xtensa_opcode xtensa_ret_opcode;
static xtensa_opcode xtensa_ret_n_opcode;
static xtensa_opcode xtensa_retw_opcode;
static xtensa_opcode xtensa_retw_n_opcode;
static xtensa_opcode xtensa_rsr_lcount_opcode;
static xtensa_opcode xtensa_waiti_opcode;
static int config_max_slots = 0;


/* Command-line Options.  */

bfd_boolean use_literal_section = TRUE;
enum flix_level produce_flix = FLIX_ALL;
static bfd_boolean align_targets = TRUE;
static bfd_boolean warn_unaligned_branch_targets = FALSE;
static bfd_boolean has_a0_b_retw = FALSE;
static bfd_boolean workaround_a0_b_retw = FALSE;
static bfd_boolean workaround_b_j_loop_end = FALSE;
static bfd_boolean workaround_short_loop = FALSE;
static bfd_boolean maybe_has_short_loop = FALSE;
static bfd_boolean workaround_close_loop_end = FALSE;
static bfd_boolean maybe_has_close_loop_end = FALSE;
static bfd_boolean enforce_three_byte_loop_align = FALSE;

/* When workaround_short_loops is TRUE, all loops with early exits must
   have at least 3 instructions.  workaround_all_short_loops is a modifier
   to the workaround_short_loop flag.  In addition to the
   workaround_short_loop actions, all straightline loopgtz and loopnez
   must have at least 3 instructions.  */

static bfd_boolean workaround_all_short_loops = FALSE;


static void
xtensa_setup_hw_workarounds (int earliest, int latest)
{
  if (earliest > latest)
    as_fatal (_("illegal range of target hardware versions"));

  /* Enable all workarounds for pre-T1050.0 hardware.  */
  if (earliest < 105000 || latest < 105000)
    {
      workaround_a0_b_retw |= TRUE;
      workaround_b_j_loop_end |= TRUE;
      workaround_short_loop |= TRUE;
      workaround_close_loop_end |= TRUE;
      workaround_all_short_loops |= TRUE;
      enforce_three_byte_loop_align = TRUE;
    }
}


enum
{
  option_density = OPTION_MD_BASE,
  option_no_density,

  option_flix,
  option_no_generate_flix,
  option_no_flix,

  option_relax,
  option_no_relax,

  option_link_relax,
  option_no_link_relax,

  option_generics,
  option_no_generics,

  option_transform,
  option_no_transform,

  option_text_section_literals,
  option_no_text_section_literals,

  option_absolute_literals,
  option_no_absolute_literals,

  option_align_targets,
  option_no_align_targets,

  option_warn_unaligned_targets,

  option_longcalls,
  option_no_longcalls,

  option_workaround_a0_b_retw,
  option_no_workaround_a0_b_retw,

  option_workaround_b_j_loop_end,
  option_no_workaround_b_j_loop_end,

  option_workaround_short_loop,
  option_no_workaround_short_loop,

  option_workaround_all_short_loops,
  option_no_workaround_all_short_loops,

  option_workaround_close_loop_end,
  option_no_workaround_close_loop_end,

  option_no_workarounds,

  option_rename_section_name,

  option_prefer_l32r,
  option_prefer_const16,

  option_target_hardware,

  option_trampolines,
  option_no_trampolines,

  option_auto_litpools,
  option_no_auto_litpools,
  option_auto_litpool_limit,
};

const char *md_shortopts = "";

struct option md_longopts[] =
{
  { "density", no_argument, NULL, option_density },
  { "no-density", no_argument, NULL, option_no_density },

  { "flix", no_argument, NULL, option_flix },
  { "no-generate-flix", no_argument, NULL, option_no_generate_flix },
  { "no-allow-flix", no_argument, NULL, option_no_flix },

  /* Both "relax" and "generics" are deprecated and treated as equivalent
     to the "transform" option.  */
  { "relax", no_argument, NULL, option_relax },
  { "no-relax", no_argument, NULL, option_no_relax },
  { "generics", no_argument, NULL, option_generics },
  { "no-generics", no_argument, NULL, option_no_generics },

  { "transform", no_argument, NULL, option_transform },
  { "no-transform", no_argument, NULL, option_no_transform },
  { "text-section-literals", no_argument, NULL, option_text_section_literals },
  { "no-text-section-literals", no_argument, NULL,
    option_no_text_section_literals },
  { "absolute-literals", no_argument, NULL, option_absolute_literals },
  { "no-absolute-literals", no_argument, NULL, option_no_absolute_literals },
  /* This option was changed from -align-target to -target-align
     because it conflicted with the "-al" option.  */
  { "target-align", no_argument, NULL, option_align_targets },
  { "no-target-align", no_argument, NULL, option_no_align_targets },
  { "warn-unaligned-targets", no_argument, NULL,
    option_warn_unaligned_targets },
  { "longcalls", no_argument, NULL, option_longcalls },
  { "no-longcalls", no_argument, NULL, option_no_longcalls },

  { "no-workaround-a0-b-retw", no_argument, NULL,
    option_no_workaround_a0_b_retw },
  { "workaround-a0-b-retw", no_argument, NULL, option_workaround_a0_b_retw },

  { "no-workaround-b-j-loop-end", no_argument, NULL,
    option_no_workaround_b_j_loop_end },
  { "workaround-b-j-loop-end", no_argument, NULL,
    option_workaround_b_j_loop_end },

  { "no-workaround-short-loops", no_argument, NULL,
    option_no_workaround_short_loop },
  { "workaround-short-loops", no_argument, NULL,
    option_workaround_short_loop },

  { "no-workaround-all-short-loops", no_argument, NULL,
    option_no_workaround_all_short_loops },
  { "workaround-all-short-loop", no_argument, NULL,
    option_workaround_all_short_loops },

  { "prefer-l32r", no_argument, NULL, option_prefer_l32r },
  { "prefer-const16", no_argument, NULL, option_prefer_const16 },

  { "no-workarounds", no_argument, NULL, option_no_workarounds },

  { "no-workaround-close-loop-end", no_argument, NULL,
    option_no_workaround_close_loop_end },
  { "workaround-close-loop-end", no_argument, NULL,
    option_workaround_close_loop_end },

  { "rename-section", required_argument, NULL, option_rename_section_name },

  { "link-relax", no_argument, NULL, option_link_relax },
  { "no-link-relax", no_argument, NULL, option_no_link_relax },

  { "target-hardware", required_argument, NULL, option_target_hardware },

  { "trampolines", no_argument, NULL, option_trampolines },
  { "no-trampolines", no_argument, NULL, option_no_trampolines },

  { "auto-litpools", no_argument, NULL, option_auto_litpools },
  { "no-auto-litpools", no_argument, NULL, option_no_auto_litpools },
  { "auto-litpool-limit", required_argument, NULL, option_auto_litpool_limit },

  { NULL, no_argument, NULL, 0 }
};

size_t md_longopts_size = sizeof md_longopts;


int
md_parse_option (int c, const char *arg)
{
  switch (c)
    {
    case option_density:
      as_warn (_("--density option is ignored"));
      return 1;
    case option_no_density:
      as_warn (_("--no-density option is ignored"));
      return 1;
    case option_link_relax:
      linkrelax = 1;
      return 1;
    case option_no_link_relax:
      linkrelax = 0;
      return 1;
    case option_flix:
      produce_flix = FLIX_ALL;
      return 1;
    case option_no_generate_flix:
      produce_flix = FLIX_NO_GENERATE;
      return 1;
    case option_no_flix:
      produce_flix = FLIX_NONE;
      return 1;
    case option_generics:
      as_warn (_("--generics is deprecated; use --transform instead"));
      return md_parse_option (option_transform, arg);
    case option_no_generics:
      as_warn (_("--no-generics is deprecated; use --no-transform instead"));
      return md_parse_option (option_no_transform, arg);
    case option_relax:
      as_warn (_("--relax is deprecated; use --transform instead"));
      return md_parse_option (option_transform, arg);
    case option_no_relax:
      as_warn (_("--no-relax is deprecated; use --no-transform instead"));
      return md_parse_option (option_no_transform, arg);
    case option_longcalls:
      directive_state[directive_longcalls] = TRUE;
      return 1;
    case option_no_longcalls:
      directive_state[directive_longcalls] = FALSE;
      return 1;
    case option_text_section_literals:
      use_literal_section = FALSE;
      return 1;
    case option_no_text_section_literals:
      use_literal_section = TRUE;
      return 1;
    case option_absolute_literals:
      if (!absolute_literals_supported)
	{
	  as_fatal (_("--absolute-literals option not supported in this Xtensa configuration"));
	  return 0;
	}
      directive_state[directive_absolute_literals] = TRUE;
      return 1;
    case option_no_absolute_literals:
      directive_state[directive_absolute_literals] = FALSE;
      return 1;

    case option_workaround_a0_b_retw:
      workaround_a0_b_retw = TRUE;
      return 1;
    case option_no_workaround_a0_b_retw:
      workaround_a0_b_retw = FALSE;
      return 1;
    case option_workaround_b_j_loop_end:
      workaround_b_j_loop_end = TRUE;
      return 1;
    case option_no_workaround_b_j_loop_end:
      workaround_b_j_loop_end = FALSE;
      return 1;

    case option_workaround_short_loop:
      workaround_short_loop = TRUE;
      return 1;
    case option_no_workaround_short_loop:
      workaround_short_loop = FALSE;
      return 1;

    case option_workaround_all_short_loops:
      workaround_all_short_loops = TRUE;
      return 1;
    case option_no_workaround_all_short_loops:
      workaround_all_short_loops = FALSE;
      return 1;

    case option_workaround_close_loop_end:
      workaround_close_loop_end = TRUE;
      return 1;
    case option_no_workaround_close_loop_end:
      workaround_close_loop_end = FALSE;
      return 1;

    case option_no_workarounds:
      workaround_a0_b_retw = FALSE;
      workaround_b_j_loop_end = FALSE;
      workaround_short_loop = FALSE;
      workaround_all_short_loops = FALSE;
      workaround_close_loop_end = FALSE;
      return 1;

    case option_align_targets:
      align_targets = TRUE;
      return 1;
    case option_no_align_targets:
      align_targets = FALSE;
      return 1;

    case option_warn_unaligned_targets:
      warn_unaligned_branch_targets = TRUE;
      return 1;

    case option_rename_section_name:
      build_section_rename (arg);
      return 1;

    case 'Q':
      /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
         should be emitted or not.  FIXME: Not implemented.  */
      return 1;

    case option_prefer_l32r:
      if (prefer_const16)
	as_fatal (_("prefer-l32r conflicts with prefer-const16"));
      prefer_l32r = 1;
      return 1;

    case option_prefer_const16:
      if (prefer_l32r)
	as_fatal (_("prefer-const16 conflicts with prefer-l32r"));
      prefer_const16 = 1;
      return 1;

    case option_target_hardware:
      {
	int earliest, latest = 0;
	char *end;
	if (*arg == 0 || *arg == '-')
	  as_fatal (_("invalid target hardware version"));

	earliest = strtol (arg, &end, 0);

	if (*end == 0)
	  latest = earliest;
	else if (*end == '-')
	  {
	    if (*++end == 0)
	      as_fatal (_("invalid target hardware version"));
	    latest = strtol (end, &end, 0);
	  }
	if (*end != 0)
	  as_fatal (_("invalid target hardware version"));

	xtensa_setup_hw_workarounds (earliest, latest);
	return 1;
      }

    case option_transform:
      /* This option has no affect other than to use the defaults,
	 which are already set.  */
      return 1;

    case option_no_transform:
      /* This option turns off all transformations of any kind.
	 However, because we want to preserve the state of other
	 directives, we only change its own field.  Thus, before
	 you perform any transformation, always check if transform
	 is available.  If you use the functions we provide for this
	 purpose, you will be ok.  */
      directive_state[directive_transform] = FALSE;
      return 1;

    case option_trampolines:
      use_trampolines = TRUE;
      return 1;

    case option_no_trampolines:
      use_trampolines = FALSE;
      return 1;

    case option_auto_litpools:
      auto_litpools = TRUE;
      use_literal_section = FALSE;
      return 1;

    case option_no_auto_litpools:
      auto_litpools = FALSE;
      auto_litpool_limit = -1;
      return 1;

    case option_auto_litpool_limit:
      {
	int value = 0;
	char *end;
	if (auto_litpool_limit < 0)
	  as_fatal (_("no-auto-litpools is incompatible with auto-litpool-limit"));
	if (*arg == 0 || *arg == '-')
	  as_fatal (_("invalid auto-litpool-limit argument"));
	value = strtol (arg, &end, 10);
	if (*end != 0)
	  as_fatal (_("invalid auto-litpool-limit argument"));
	if (value < 100 || value > 10000)
	  as_fatal (_("invalid auto-litpool-limit argument (range is 100-10000)"));
	auto_litpool_limit = value;
	auto_litpools = TRUE;
	use_literal_section = FALSE;
	return 1;
      }

    default:
      return 0;
    }
}


void
md_show_usage (FILE *stream)
{
  fputs ("\n\
Xtensa options:\n\
  --[no-]text-section-literals\n\
                          [Do not] put literals in the text section\n\
  --[no-]absolute-literals\n\
                          [Do not] default to use non-PC-relative literals\n\
  --[no-]target-align     [Do not] try to align branch targets\n\
  --[no-]longcalls        [Do not] emit 32-bit call sequences\n\
  --[no-]transform        [Do not] transform instructions\n\
  --flix                  both allow hand-written and generate flix bundles\n\
  --no-generate-flix      allow hand-written but do not generate\n\
                          flix bundles\n\
  --no-allow-flix         neither allow hand-written nor generate\n\
                          flix bundles\n\
  --rename-section old=new Rename section 'old' to 'new'\n\
  --[no-]trampolines      [Do not] generate trampolines (jumps to jumps)\n\
                          when jumps do not reach their targets\n\
  --[no-]auto-litpools    [Do not] automatically create literal pools\n\
  --auto-litpool-limit=<value>\n\
                          (range 100-10000) Maximum number of blocks of\n\
                          instructions to emit between literal pool\n\
                          locations; implies --auto-litpools flag\n", stream);
}


/* Functions related to the list of current label symbols.  */

static void
xtensa_add_insn_label (symbolS *sym)
{
  sym_list *l;

  if (!free_insn_labels)
    l = XNEW (sym_list);
  else
    {
      l = free_insn_labels;
      free_insn_labels = l->next;
    }

  l->sym = sym;
  l->next = insn_labels;
  insn_labels = l;
}


static void
xtensa_clear_insn_labels (void)
{
  sym_list **pl;

  for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)
    ;
  *pl = insn_labels;
  insn_labels = NULL;
}


static void
xtensa_move_labels (fragS *new_frag, valueT new_offset)
{
  sym_list *lit;

  for (lit = insn_labels; lit; lit = lit->next)
    {
      symbolS *lit_sym = lit->sym;
      S_SET_VALUE (lit_sym, new_offset);
      symbol_set_frag (lit_sym, new_frag);
    }
}


/* Directive data and functions.  */

typedef struct state_stackS_struct
{
  directiveE directive;
  bfd_boolean negated;
  bfd_boolean old_state;
  const char *file;
  unsigned int line;
  const void *datum;
  struct state_stackS_struct *prev;
} state_stackS;

state_stackS *directive_state_stack;

const pseudo_typeS md_pseudo_table[] =
{
  { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0).  */
  { "literal_position", xtensa_literal_position, 0 },
  { "frame", s_ignore, 0 },	/* Formerly used for STABS debugging.  */
  { "long", xtensa_elf_cons, 4 },
  { "word", xtensa_elf_cons, 4 },
  { "4byte", xtensa_elf_cons, 4 },
  { "short", xtensa_elf_cons, 2 },
  { "2byte", xtensa_elf_cons, 2 },
  { "sleb128", xtensa_leb128, 1},
  { "uleb128", xtensa_leb128, 0},
  { "begin", xtensa_begin_directive, 0 },
  { "end", xtensa_end_directive, 0 },
  { "literal", xtensa_literal_pseudo, 0 },
  { "frequency", xtensa_frequency_pseudo, 0 },
  { NULL, 0, 0 },
};


static bfd_boolean
use_transform (void)
{
  /* After md_end, you should be checking frag by frag, rather
     than state directives.  */
  gas_assert (!past_xtensa_end);
  return directive_state[directive_transform];
}


static bfd_boolean
do_align_targets (void)
{
  /* Do not use this function after md_end; just look at align_targets
     instead.  There is no target-align directive, so alignment is either
     enabled for all frags or not done at all.  */
  gas_assert (!past_xtensa_end);
  return align_targets && use_transform ();
}


static void
directive_push (directiveE directive, bfd_boolean negated, const void *datum)
{
  const char *file;
  unsigned int line;
  state_stackS *stack = XNEW (state_stackS);

  file = as_where (&line);

  stack->directive = directive;
  stack->negated = negated;
  stack->old_state = directive_state[directive];
  stack->file = file;
  stack->line = line;
  stack->datum = datum;
  stack->prev = directive_state_stack;
  directive_state_stack = stack;

  directive_state[directive] = !negated;
}


static void
directive_pop (directiveE *directive,
	       bfd_boolean *negated,
	       const char **file,
	       unsigned int *line,
	       const void **datum)
{
  state_stackS *top = directive_state_stack;

  if (!directive_state_stack)
    {
      as_bad (_("unmatched end directive"));
      *directive = directive_none;
      return;
    }

  directive_state[directive_state_stack->directive] = top->old_state;
  *directive = top->directive;
  *negated = top->negated;
  *file = top->file;
  *line = top->line;
  *datum = top->datum;
  directive_state_stack = top->prev;
  free (top);
}


static void
directive_balance (void)
{
  while (directive_state_stack)
    {
      directiveE directive;
      bfd_boolean negated;
      const char *file;
      unsigned int line;
      const void *datum;

      directive_pop (&directive, &negated, &file, &line, &datum);
      as_warn_where ((char *) file, line,
		     _(".begin directive with no matching .end directive"));
    }
}


static bfd_boolean
inside_directive (directiveE dir)
{
  state_stackS *top = directive_state_stack;

  while (top && top->directive != dir)
    top = top->prev;

  return (top != NULL);
}


static void
get_directive (directiveE *directive, bfd_boolean *negated)
{
  int len;
  unsigned i;
  const char *directive_string;

  if (strncmp (input_line_pointer, "no-", 3) != 0)
    *negated = FALSE;
  else
    {
      *negated = TRUE;
      input_line_pointer += 3;
    }

  len = strspn (input_line_pointer,
		"abcdefghijklmnopqrstuvwxyz_-/0123456789.");

  /* This code is a hack to make .begin [no-][generics|relax] exactly
     equivalent to .begin [no-]transform.  We should remove it when
     we stop accepting those options.  */

  if (strncmp (input_line_pointer, "generics", strlen ("generics")) == 0)
    {
      as_warn (_("[no-]generics is deprecated; use [no-]transform instead"));
      directive_string = "transform";
    }
  else if (strncmp (input_line_pointer, "relax", strlen ("relax")) == 0)
    {
      as_warn (_("[no-]relax is deprecated; use [no-]transform instead"));
      directive_string = "transform";
    }
  else
    directive_string = input_line_pointer;

  for (i = 0; i < sizeof (directive_info) / sizeof (*directive_info); ++i)
    {
      if (strncmp (directive_string, directive_info[i].name, len) == 0)
	{
	  input_line_pointer += len;
	  *directive = (directiveE) i;
	  if (*negated && !directive_info[i].can_be_negated)
	    as_bad (_("directive %s cannot be negated"),
		    directive_info[i].name);
	  return;
	}
    }

  as_bad (_("unknown directive"));
  *directive = (directiveE) XTENSA_UNDEFINED;
}


static void
xtensa_begin_directive (int ignore ATTRIBUTE_UNUSED)
{
  directiveE directive;
  bfd_boolean negated;
  emit_state *state;
  lit_state *ls;

  get_directive (&directive, &negated);
  if (directive == (directiveE) XTENSA_UNDEFINED)
    {
      discard_rest_of_line ();
      return;
    }

  if (cur_vinsn.inside_bundle)
    as_bad (_("directives are not valid inside bundles"));

  switch (directive)
    {
    case directive_literal:
      if (!inside_directive (directive_literal))
	{
	  /* Previous labels go with whatever follows this directive, not with
	     the literal, so save them now.  */
	  saved_insn_labels = insn_labels;
	  insn_labels = NULL;
	}
      as_warn (_(".begin literal is deprecated; use .literal instead"));
      state = XNEW (emit_state);
      xtensa_switch_to_literal_fragment (state);
      directive_push (directive_literal, negated, state);
      break;

    case directive_literal_prefix:
      /* Have to flush pending output because a movi relaxed to an l32r
	 might produce a literal.  */
      md_flush_pending_output ();
      /* Check to see if the current fragment is a literal
	 fragment.  If it is, then this operation is not allowed.  */
      if (generating_literals)
	{
	  as_bad (_("cannot set literal_prefix inside literal fragment"));
	  return;
	}

      /* Allocate the literal state for this section and push
	 onto the directive stack.  */
      ls = XNEW (lit_state);
      gas_assert (ls);

      *ls = default_lit_sections;
      directive_push (directive_literal_prefix, negated, ls);

      /* Process the new prefix.  */
      xtensa_literal_prefix ();
      break;

    case directive_freeregs:
      /* This information is currently unused, but we'll accept the statement
         and just discard the rest of the line.  This won't check the syntax,
         but it will accept every correct freeregs directive.  */
      input_line_pointer += strcspn (input_line_pointer, "\n");
      directive_push (directive_freeregs, negated, 0);
      break;

    case directive_schedule:
      md_flush_pending_output ();
      frag_var (rs_fill, 0, 0, frag_now->fr_subtype,
		frag_now->fr_symbol, frag_now->fr_offset, NULL);
      directive_push (directive_schedule, negated, 0);
      xtensa_set_frag_assembly_state (frag_now);
      break;

    case directive_density:
      as_warn (_(".begin [no-]density is ignored"));
      break;

    case directive_absolute_literals:
      md_flush_pending_output ();
      if (!absolute_literals_supported && !negated)
	{
	  as_warn (_("Xtensa absolute literals option not supported; ignored"));
	  break;
	}
      xtensa_set_frag_assembly_state (frag_now);
      directive_push (directive, negated, 0);
      break;

    default:
      md_flush_pending_output ();
      xtensa_set_frag_assembly_state (frag_now);
      directive_push (directive, negated, 0);
      break;
    }

  demand_empty_rest_of_line ();
}


static void
xtensa_end_directive (int ignore ATTRIBUTE_UNUSED)
{
  directiveE begin_directive, end_directive;
  bfd_boolean begin_negated, end_negated;
  const char *file;
  unsigned int line;
  emit_state *state;
  emit_state **state_ptr;
  lit_state *s;

  if (cur_vinsn.inside_bundle)
    as_bad (_("directives are not valid inside bundles"));

  get_directive (&end_directive, &end_negated);

  md_flush_pending_output ();

  switch ((int) end_directive)
    {
    case XTENSA_UNDEFINED:
      discard_rest_of_line ();
      return;

    case (int) directive_density:
      as_warn (_(".end [no-]density is ignored"));
      demand_empty_rest_of_line ();
      break;

    case (int) directive_absolute_literals:
      if (!absolute_literals_supported && !end_negated)
	{
	  as_warn (_("Xtensa absolute literals option not supported; ignored"));
	  demand_empty_rest_of_line ();
	  return;
	}
      break;

    default:
      break;
    }

  state_ptr = &state; /* use state_ptr to avoid type-punning warning */
  directive_pop (&begin_directive, &begin_negated, &file, &line,
		 (const void **) state_ptr);

  if (begin_directive != directive_none)
    {
      if (begin_directive != end_directive || begin_negated != end_negated)
	{
	  as_bad (_("does not match begin %s%s at %s:%d"),
		  begin_negated ? "no-" : "",
		  directive_info[begin_directive].name, file, line);
	}
      else
	{
	  switch (end_directive)
	    {
	    case directive_literal:
	      frag_var (rs_fill, 0, 0, 0, NULL, 0, NULL);
	      xtensa_restore_emit_state (state);
	      xtensa_set_frag_assembly_state (frag_now);
	      free (state);
	      if (!inside_directive (directive_literal))
		{
		  /* Restore the list of current labels.  */
		  xtensa_clear_insn_labels ();
		  insn_labels = saved_insn_labels;
		}
	      break;

	    case directive_literal_prefix:
	      /* Restore the default collection sections from saved state.  */
	      s = (lit_state *) state;
	      gas_assert (s);
	      default_lit_sections = *s;

	      /* Free the state storage.  */
	      free (s->lit_prefix);
	      free (s);
	      break;

	    case directive_schedule:
	    case directive_freeregs:
	      break;

	    default:
	      xtensa_set_frag_assembly_state (frag_now);
	      break;
	    }
	}
    }

  demand_empty_rest_of_line ();
}


/* Place an aligned literal fragment at the current location.  */

static void
xtensa_literal_position (int ignore ATTRIBUTE_UNUSED)
{
  md_flush_pending_output ();

  if (inside_directive (directive_literal))
    as_warn (_(".literal_position inside literal directive; ignoring"));
  xtensa_mark_literal_pool_location ();

  demand_empty_rest_of_line ();
  xtensa_clear_insn_labels ();
}


/* Support .literal label, expr, ...  */

static void
xtensa_literal_pseudo (int ignored ATTRIBUTE_UNUSED)
{
  emit_state state;
  char *p, *base_name;
  char c;
  segT dest_seg;

  if (inside_directive (directive_literal))
    {
      as_bad (_(".literal not allowed inside .begin literal region"));
      ignore_rest_of_line ();
      return;
    }

  md_flush_pending_output ();

  /* Previous labels go with whatever follows this directive, not with
     the literal, so save them now.  */
  saved_insn_labels = insn_labels;
  insn_labels = NULL;

  /* If we are using text-section literals, then this is the right value... */
  dest_seg = now_seg;

  base_name = input_line_pointer;

  xtensa_switch_to_literal_fragment (&state);

  /* ...but if we aren't using text-section-literals, then we
     need to put them in the section we just switched to.  */
  if (use_literal_section || directive_state[directive_absolute_literals])
    dest_seg = now_seg;

  /* FIXME, despite the previous comments, dest_seg is unused...  */
  (void) dest_seg;

  /* All literals are aligned to four-byte boundaries.  */
  frag_align (2, 0, 0);
  record_alignment (now_seg, 2);

  c = get_symbol_name (&base_name);
  /* Just after name is now '\0'.  */
  p = input_line_pointer;
  *p = c;
  SKIP_WHITESPACE_AFTER_NAME ();

  if (*input_line_pointer != ',' && *input_line_pointer != ':')
    {
      as_bad (_("expected comma or colon after symbol name; "
		"rest of line ignored"));
      ignore_rest_of_line ();
      xtensa_restore_emit_state (&state);
      return;
    }

  *p = 0;
  colon (base_name);
  *p = c;

  input_line_pointer++;		/* skip ',' or ':' */

  xtensa_elf_cons (4);

  xtensa_restore_emit_state (&state);

  /* Restore the list of current labels.  */
  xtensa_clear_insn_labels ();
  insn_labels = saved_insn_labels;
}


static void
xtensa_literal_prefix (void)
{
  char *name;
  int len;

  /* Parse the new prefix from the input_line_pointer.  */
  SKIP_WHITESPACE ();
  len = strspn (input_line_pointer,
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		"abcdefghijklmnopqrstuvwxyz_/0123456789.$");

  /* Get a null-terminated copy of the name.  */
  name = xmemdup0 (input_line_pointer, len);

  /* Skip the name in the input line.  */
  input_line_pointer += len;

  default_lit_sections.lit_prefix = name;

  /* Clear cached literal sections, since the prefix has changed.  */
  default_lit_sections.lit_seg = NULL;
  default_lit_sections.lit4_seg = NULL;
}


/* Support ".frequency branch_target_frequency fall_through_frequency".  */

static void
xtensa_frequency_pseudo (int ignored ATTRIBUTE_UNUSED)
{
  float fall_through_f, target_f;

  fall_through_f = (float) strtod (input_line_pointer, &input_line_pointer);
  if (fall_through_f < 0)
    {
      as_bad (_("fall through frequency must be greater than 0"));
      ignore_rest_of_line ();
      return;
    }

  target_f = (float) strtod (input_line_pointer, &input_line_pointer);
  if (target_f < 0)
    {
      as_bad (_("branch target frequency must be greater than 0"));
      ignore_rest_of_line ();
      return;
    }

  set_subseg_freq (now_seg, now_subseg, target_f + fall_through_f, target_f);

  demand_empty_rest_of_line ();
}


/* Like normal .long/.short/.word, except support @plt, etc.
   Clobbers input_line_pointer, checks end-of-line.  */

static void
xtensa_elf_cons (int nbytes)
{
  expressionS exp;
  bfd_reloc_code_real_type reloc;

  md_flush_pending_output ();

  if (cur_vinsn.inside_bundle)
    as_bad (_("directives are not valid inside bundles"));

  if (is_it_end_of_statement ())
    {
      demand_empty_rest_of_line ();
      return;
    }

  do
    {
      expression (&exp);
      if (exp.X_op == O_symbol
	  && *input_line_pointer == '@'
	  && ((reloc = xtensa_elf_suffix (&input_line_pointer, &exp))
	      != BFD_RELOC_NONE))
	{
	  reloc_howto_type *reloc_howto =
	    bfd_reloc_type_lookup (stdoutput, reloc);

	  if (reloc == BFD_RELOC_UNUSED || !reloc_howto)
	    as_bad (_("unsupported relocation"));
	  else if ((reloc >= BFD_RELOC_XTENSA_SLOT0_OP
		    && reloc <= BFD_RELOC_XTENSA_SLOT14_OP)
		   || (reloc >= BFD_RELOC_XTENSA_SLOT0_ALT
		       && reloc <= BFD_RELOC_XTENSA_SLOT14_ALT))
	    as_bad (_("opcode-specific %s relocation used outside "
		      "an instruction"), reloc_howto->name);
	  else if (nbytes != (int) bfd_get_reloc_size (reloc_howto))
	    as_bad (_("%s relocations do not fit in %d bytes"),
		    reloc_howto->name, nbytes);
	  else if (reloc == BFD_RELOC_XTENSA_TLS_FUNC
		   || reloc == BFD_RELOC_XTENSA_TLS_ARG
		   || reloc == BFD_RELOC_XTENSA_TLS_CALL)
	    as_bad (_("invalid use of %s relocation"), reloc_howto->name);
	  else
	    {
	      char *p = frag_more ((int) nbytes);
	      xtensa_set_frag_assembly_state (frag_now);
	      fix_new_exp (frag_now, p - frag_now->fr_literal,
			   nbytes, &exp, reloc_howto->pc_relative, reloc);
	    }
	}
      else
	{
	  xtensa_set_frag_assembly_state (frag_now);
	  emit_expr (&exp, (unsigned int) nbytes);
	}
    }
  while (*input_line_pointer++ == ',');

  input_line_pointer--;		/* Put terminator back into stream.  */
  demand_empty_rest_of_line ();
}

static bfd_boolean is_leb128_expr;

static void
xtensa_leb128 (int sign)
{
  is_leb128_expr = TRUE;
  s_leb128 (sign);
  is_leb128_expr = FALSE;
}


/* Parsing and Idiom Translation.  */

/* Parse @plt, etc. and return the desired relocation.  */
static bfd_reloc_code_real_type
xtensa_elf_suffix (char **str_p, expressionS *exp_p)
{
  char ident[20];
  char *str = *str_p;
  char *str2;
  int ch;
  int len;
  unsigned int i;

  if (*str++ != '@')
    return BFD_RELOC_NONE;

  for (ch = *str, str2 = ident;
       (str2 < ident + sizeof (ident) - 1
	&& (ISALNUM (ch) || ch == '@'));
       ch = *++str)
    {
      *str2++ = (ISLOWER (ch)) ? ch : TOLOWER (ch);
    }

  *str2 = '\0';
  len = str2 - ident;

  ch = ident[0];
  for (i = 0; i < ARRAY_SIZE (suffix_relocs); i++)
    if (ch == suffix_relocs[i].suffix[0]
	&& len == suffix_relocs[i].length
	&& memcmp (ident, suffix_relocs[i].suffix, suffix_relocs[i].length) == 0)
      {
	/* Now check for "identifier@suffix+constant".  */
	if (*str == '-' || *str == '+')
	  {
	    char *orig_line = input_line_pointer;
	    expressionS new_exp;

	    input_line_pointer = str;
	    expression (&new_exp);
	    if (new_exp.X_op == O_constant)
	      {
		exp_p->X_add_number += new_exp.X_add_number;
		str = input_line_pointer;
	      }

	    if (&input_line_pointer != str_p)
	      input_line_pointer = orig_line;
	  }

	*str_p = str;
	return suffix_relocs[i].reloc;
      }

  return BFD_RELOC_UNUSED;
}


/* Find the matching operator type.  */
static operatorT
map_suffix_reloc_to_operator (bfd_reloc_code_real_type reloc)
{
  operatorT operator = O_illegal;
  unsigned int i;

  for (i = 0; i < ARRAY_SIZE (suffix_relocs); i++)
    {
      if (suffix_relocs[i].reloc == reloc)
	{
	  operator = suffix_relocs[i].operator;
	  break;
	}
    }
  gas_assert (operator != O_illegal);
  return operator;
}


/* Find the matching reloc type.  */
static bfd_reloc_code_real_type
map_operator_to_reloc (unsigned char operator, bfd_boolean is_literal)
{
  unsigned int i;
  bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;

  for (i = 0; i < ARRAY_SIZE (suffix_relocs); i++)
    {
      if (suffix_relocs[i].operator == operator)
	{
	  reloc = suffix_relocs[i].reloc;
	  break;
	}
    }

  if (is_literal)
    {
      if (reloc == BFD_RELOC_XTENSA_TLS_FUNC)
	return BFD_RELOC_XTENSA_TLSDESC_FN;
      else if (reloc == BFD_RELOC_XTENSA_TLS_ARG)
	return BFD_RELOC_XTENSA_TLSDESC_ARG;
    }

  if (reloc == BFD_RELOC_UNUSED)
    return BFD_RELOC_32;

  return reloc;
}


static const char *
expression_end (const char *name)
{
  while (1)
    {
      switch (*name)
	{
	case '}':
	case ';':
	case '\0':
	case ',':
	case ':':
	  return name;
	case ' ':
	case '\t':
	  ++name;
	  continue;
	default:
	  return 0;
	}
    }
}


#define ERROR_REG_NUM ((unsigned) -1)

static unsigned
tc_get_register (const char *prefix)
{
  unsigned reg;
  const char *next_expr;
  const char *old_line_pointer;

  SKIP_WHITESPACE ();
  old_line_pointer = input_line_pointer;

  if (*input_line_pointer == '$')
    ++input_line_pointer;

  /* Accept "sp" as a synonym for "a1".  */
  if (input_line_pointer[0] == 's' && input_line_pointer[1] == 'p'
      && expression_end (input_line_pointer + 2))
    {
      input_line_pointer += 2;
      return 1;  /* AR[1] */
    }

  while (*input_line_pointer++ == *prefix++)
    ;
  --input_line_pointer;
  --prefix;

  if (*prefix)
    {
      as_bad (_("bad register name: %s"), old_line_pointer);
      return ERROR_REG_NUM;
    }

  if (!ISDIGIT ((unsigned char) *input_line_pointer))
    {
      as_bad (_("bad register number: %s"), input_line_pointer);
      return ERROR_REG_NUM;
    }

  reg = 0;

  while (ISDIGIT ((int) *input_line_pointer))
    reg = reg * 10 + *input_line_pointer++ - '0';

  if (!(next_expr = expression_end (input_line_pointer)))
    {
      as_bad (_("bad register name: %s"), old_line_pointer);
      return ERROR_REG_NUM;
    }

  input_line_pointer = (char *) next_expr;

  return reg;
}


static void
expression_maybe_register (xtensa_opcode opc, int opnd, expressionS *tok)
{
  xtensa_isa isa = xtensa_default_isa;

  /* Check if this is an immediate operand.  */
  if (xtensa_operand_is_register (isa, opc, opnd) == 0)
    {
      bfd_reloc_code_real_type reloc;
      segT t = expression (tok);

      if (t == absolute_section
	  && xtensa_operand_is_PCrelative (isa, opc, opnd) == 1)
	{
	  gas_assert (tok->X_op == O_constant);
	  tok->X_op = O_symbol;
	  tok->X_add_symbol = &abs_symbol;
	}

      if ((tok->X_op == O_constant || tok->X_op == O_symbol)
	  && ((reloc = xtensa_elf_suffix (&input_line_pointer, tok))
	      != BFD_RELOC_NONE))
	{
	  switch (reloc)
	    {
	    case BFD_RELOC_LO16:
	      if (tok->X_op == O_constant)
		{
		  tok->X_add_number &= 0xffff;
		  return;
		}
	      break;
	    case BFD_RELOC_HI16:
	      if (tok->X_op == O_constant)
		{
		  tok->X_add_number = ((unsigned) tok->X_add_number) >> 16;
		  return;
		}
	      break;
	    case BFD_RELOC_UNUSED:
	      as_bad (_("unsupported relocation"));
	      return;
	    case BFD_RELOC_32_PCREL:
	      as_bad (_("pcrel relocation not allowed in an instruction"));
	      return;
	    default:
	      break;
	    }
	  tok->X_op = map_suffix_reloc_to_operator (reloc);
	}
    }
  else
    {
      xtensa_regfile opnd_rf = xtensa_operand_regfile (isa, opc, opnd);
      unsigned reg = tc_get_register (xtensa_regfile_shortname (isa, opnd_rf));

      if (reg != ERROR_REG_NUM)	/* Already errored */
	{
	  uint32 buf = reg;
	  if (xtensa_operand_encode (isa, opc, opnd, &buf))
	    as_bad (_("register number out of range"));
	}

      tok->X_op = O_register;
      tok->X_add_symbol = 0;
      tok->X_add_number = reg;
    }
}


/* Split up the arguments for an opcode or pseudo-op.  */

static int
tokenize_arguments (char **args, char *str)
{
  char *old_input_line_pointer;
  bfd_boolean saw_comma = FALSE;
  bfd_boolean saw_arg = FALSE;
  bfd_boolean saw_colon = FALSE;
  int num_args = 0;
  char *arg_end, *arg;
  int arg_len;

  /* Save and restore input_line_pointer around this function.  */
  old_input_line_pointer = input_line_pointer;
  input_line_pointer = str;

  while (*input_line_pointer)
    {
      SKIP_WHITESPACE ();
      switch (*input_line_pointer)
	{
	case '\0':
	case '}':
	  goto fini;

	case ':':
	  input_line_pointer++;
	  if (saw_comma || saw_colon || !saw_arg)
	    goto err;
	  saw_colon = TRUE;
	  break;

	case ',':
	  input_line_pointer++;
	  if (saw_comma || saw_colon || !saw_arg)
	    goto err;
	  saw_comma = TRUE;
	  break;

	default:
	  if (!saw_comma && !saw_colon && saw_arg)
	    goto err;

	  arg_end = input_line_pointer + 1;
	  while (!expression_end (arg_end))
	    arg_end += 1;

	  arg_len = arg_end - input_line_pointer;
	  arg = XNEWVEC (char, (saw_colon ? 1 : 0) + arg_len + 1);
	  args[num_args] = arg;

	  if (saw_colon)
	    *arg++ = ':';
	  strncpy (arg, input_line_pointer, arg_len);
	  arg[arg_len] = '\0';

	  input_line_pointer = arg_end;
	  num_args += 1;
	  saw_comma = FALSE;
	  saw_colon = FALSE;
	  saw_arg = TRUE;
	  break;
	}
    }

fini:
  if (saw_comma || saw_colon)
    goto err;
  input_line_pointer = old_input_line_pointer;
  return num_args;

err:
  if (saw_comma)
    as_bad (_("extra comma"));
  else if (saw_colon)
    as_bad (_("extra colon"));
  else if (!saw_arg)
    as_bad (_("missing argument"));
  else
    as_bad (_("missing comma or colon"));
  input_line_pointer = old_input_line_pointer;
  return -1;
}


/* Parse the arguments to an opcode.  Return TRUE on error.  */

static bfd_boolean
parse_arguments (TInsn *insn, int num_args, char **arg_strings)
{
  expressionS *tok, *last_tok;
  xtensa_opcode opcode = insn->opcode;
  bfd_boolean had_error = TRUE;
  xtensa_isa isa = xtensa_default_isa;
  int n, num_regs = 0;
  int opcode_operand_count;
  int opnd_cnt, last_opnd_cnt;
  unsigned int next_reg = 0;
  char *old_input_line_pointer;

  if (insn->insn_type == ITYPE_LITERAL)
    opcode_operand_count = 1;
  else
    opcode_operand_count = xtensa_opcode_num_operands (isa, opcode);

  tok = insn->tok;
  memset (tok, 0, sizeof (*tok) * MAX_INSN_ARGS);

  /* Save and restore input_line_pointer around this function.  */
  old_input_line_pointer = input_line_pointer;

  last_tok = 0;
  last_opnd_cnt = -1;
  opnd_cnt = 0;

  /* Skip invisible operands.  */
  while (xtensa_operand_is_visible (isa, opcode, opnd_cnt) == 0)
    {
      opnd_cnt += 1;
      tok++;
    }

  for (n = 0; n < num_args; n++)
    {
      input_line_pointer = arg_strings[n];
      if (*input_line_pointer == ':')
	{
	  xtensa_regfile opnd_rf;
	  input_line_pointer++;
	  if (num_regs == 0)
	    goto err;
	  gas_assert (opnd_cnt > 0);
	  num_regs--;
	  opnd_rf = xtensa_operand_regfile (isa, opcode, last_opnd_cnt);
	  if (next_reg
	      != tc_get_register (xtensa_regfile_shortname (isa, opnd_rf)))
	    as_warn (_("incorrect register number, ignoring"));
	  next_reg++;
	}
      else
	{
	  if (opnd_cnt >= opcode_operand_count)
	    {
	      as_warn (_("too many arguments"));
	      goto err;
	    }
	  gas_assert (opnd_cnt < MAX_INSN_ARGS);

	  expression_maybe_register (opcode, opnd_cnt, tok);
	  next_reg = tok->X_add_number + 1;

	  if (tok->X_op == O_illegal || tok->X_op == O_absent)
	    goto err;
	  if (xtensa_operand_is_register (isa, opcode, opnd_cnt) == 1)
	    {
	      num_regs = xtensa_operand_num_regs (isa, opcode, opnd_cnt) - 1;
	      /* minus 1 because we are seeing one right now */
	    }
	  else
	    num_regs = 0;

	  last_tok = tok;
	  last_opnd_cnt = opnd_cnt;
	  demand_empty_rest_of_line ();

	  do
	    {
	      opnd_cnt += 1;
	      tok++;
	    }
	  while (xtensa_operand_is_visible (isa, opcode, opnd_cnt) == 0);
	}
    }

  if (num_regs > 0 && ((int) next_reg != last_tok->X_add_number + 1))
    goto err;

  insn->ntok = tok - insn->tok;
  had_error = FALSE;

 err:
  input_line_pointer = old_input_line_pointer;
  return had_error;
}


static int
get_invisible_operands (TInsn *insn)
{
  xtensa_isa isa = xtensa_default_isa;
  static xtensa_insnbuf slotbuf = NULL;
  xtensa_format fmt;
  xtensa_opcode opc = insn->opcode;
  int slot, opnd, fmt_found;
  unsigned val;

  if (!slotbuf)
    slotbuf = xtensa_insnbuf_alloc (isa);

  /* Find format/slot where this can be encoded.  */
  fmt_found = 0;
  slot = 0;
  for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++)
    {
      for (slot = 0; slot < xtensa_format_num_slots (isa, fmt); slot++)
	{
	  if (xtensa_opcode_encode (isa, fmt, slot, slotbuf, opc) == 0)
	    {
	      fmt_found = 1;
	      break;
	    }
	}
      if (fmt_found) break;
    }

  if (!fmt_found)
    {
      as_bad (_("cannot encode opcode \"%s\""), xtensa_opcode_name (isa, opc));
      return -1;
    }

  /* First encode all the visible operands
     (to deal with shared field operands).  */
  for (opnd = 0; opnd < insn->ntok; opnd++)
    {
      if (xtensa_operand_is_visible (isa, opc, opnd) == 1
	  && (insn->tok[opnd].X_op == O_register
	      || insn->tok[opnd].X_op == O_constant))
	{
	  val = insn->tok[opnd].X_add_number;
	  xtensa_operand_encode (isa, opc, opnd, &val);
	  xtensa_operand_set_field (isa, opc, opnd, fmt, slot, slotbuf, val);
	}
    }

  /* Then pull out the values for the invisible ones.  */
  for (opnd = 0; opnd < insn->ntok; opnd++)
    {
      if (xtensa_operand_is_visible (isa, opc, opnd) == 0)
	{
	  xtensa_operand_get_field (isa, opc, opnd, fmt, slot, slotbuf, &val);
	  xtensa_operand_decode (isa, opc, opnd, &val);
	  insn->tok[opnd].X_add_number = val;
	  if (xtensa_operand_is_register (isa, opc, opnd) == 1)
	    insn->tok[opnd].X_op = O_register;
	  else
	    insn->tok[opnd].X_op = O_constant;
	}
    }

  return 0;
}


static void
xg_reverse_shift_count (char **cnt_argp)
{
  char *cnt_arg, *new_arg;
  cnt_arg = *cnt_argp;

  /* replace the argument with "31-(argument)" */
  new_arg = concat ("31-(", cnt_arg, ")", (char *) NULL);

  free (cnt_arg);
  *cnt_argp = new_arg;
}


/* If "arg" is a constant expression, return non-zero with the value
   in *valp.  */

static int
xg_arg_is_constant (char *arg, offsetT *valp)
{
  expressionS exp;
  char *save_ptr = input_line_pointer;

  input_line_pointer = arg;
  expression (&exp);
  input_line_pointer = save_ptr;

  if (exp.X_op == O_constant)
    {
      *valp = exp.X_add_number;
      return 1;
    }

  return 0;
}


static void
xg_replace_opname (char **popname, const char *newop)
{
  free (*popname);
  *popname = xstrdup (newop);
}


static int
xg_check_num_args (int *pnum_args,
		   int expected_num,
		   char *opname,
		   char **arg_strings)
{
  int num_args = *pnum_args;

  if (num_args < expected_num)
    {
      as_bad (_("not enough operands (%d) for '%s'; expected %d"),
	      num_args, opname, expected_num);
      return -1;
    }

  if (num_args > expected_num)
    {
      as_warn (_("too many operands (%d) for '%s'; expected %d"),
	       num_args, opname, expected_num);
      while (num_args-- > expected_num)
	{
	  free (arg_strings[num_args]);
	  arg_strings[num_args] = 0;
	}
      *pnum_args = expected_num;
      return -1;
    }

  return 0;
}


/* If the register is not specified as part of the opcode,
   then get it from the operand and move it to the opcode.  */

static int
xg_translate_sysreg_op (char **popname, int *pnum_args, char **arg_strings)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_sysreg sr;
  char *opname, *new_opname;
  const char *sr_name;
  int is_user, is_write;

  opname = *popname;
  if (*opname == '_')
    opname += 1;
  is_user = (opname[1] == 'u');
  is_write = (opname[0] == 'w');

  /* Opname == [rw]ur or [rwx]sr... */

  if (xg_check_num_args (pnum_args, 2, opname, arg_strings))
    return -1;

  /* Check if the argument is a symbolic register name.  */
  sr = xtensa_sysreg_lookup_name (isa, arg_strings[1]);
  /* Handle WSR to "INTSET" as a special case.  */
  if (sr == XTENSA_UNDEFINED && is_write && !is_user
      && !strcasecmp (arg_strings[1], "intset"))
    sr = xtensa_sysreg_lookup_name (isa, "interrupt");
  if (sr == XTENSA_UNDEFINED
      || (xtensa_sysreg_is_user (isa, sr) == 1) != is_user)
    {
      /* Maybe it's a register number.... */
      offsetT val;
      if (!xg_arg_is_constant (arg_strings[1], &val))
	{
	  as_bad (_("invalid register '%s' for '%s' instruction"),
		  arg_strings[1], opname);
	  return -1;
	}
      sr = xtensa_sysreg_lookup (isa, val, is_user);
      if (sr == XTENSA_UNDEFINED)
	{
	  as_bad (_("invalid register number (%ld) for '%s' instruction"),
		  (long) val, opname);
	  return -1;
	}
    }

  /* Remove the last argument, which is now part of the opcode.  */
  free (arg_strings[1]);
  arg_strings[1] = 0;
  *pnum_args = 1;

  /* Translate the opcode.  */
  sr_name = xtensa_sysreg_name (isa, sr);
  /* Another special case for "WSR.INTSET"....  */
  if (is_write && !is_user && !strcasecmp ("interrupt", sr_name))
    sr_name = "intset";
  new_opname = concat (*popname, ".", sr_name, (char *) NULL);
  free (*popname);
  *popname = new_opname;

  return 0;
}


static int
xtensa_translate_old_userreg_ops (char **popname)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_sysreg sr;
  char *opname, *new_opname;
  const char *sr_name;
  bfd_boolean has_underbar = FALSE;

  opname = *popname;
  if (opname[0] == '_')
    {
      has_underbar = TRUE;
      opname += 1;
    }

  sr = xtensa_sysreg_lookup_name (isa, opname + 1);
  if (sr != XTENSA_UNDEFINED)
    {
      /* The new default name ("nnn") is different from the old default
	 name ("URnnn").  The old default is handled below, and we don't
	 want to recognize [RW]nnn, so do nothing if the name is the (new)
	 default.  */
      static char namebuf[10];
      sprintf (namebuf, "%d", xtensa_sysreg_number (isa, sr));
      if (strcmp (namebuf, opname + 1) == 0)
	return 0;
    }
  else
    {
      offsetT val;
      char *end;

      /* Only continue if the reg name is "URnnn".  */
      if (opname[1] != 'u' || opname[2] != 'r')
	return 0;
      val = strtoul (opname + 3, &end, 10);
      if (*end != '\0')
	return 0;

      sr = xtensa_sysreg_lookup (isa, val, 1);
      if (sr == XTENSA_UNDEFINED)
	{
	  as_bad (_("invalid register number (%ld) for '%s'"),
		  (long) val, opname);
	  return -1;
	}
    }

  /* Translate the opcode.  */
  sr_name = xtensa_sysreg_name (isa, sr);
  new_opname = XNEWVEC (char, strlen (sr_name) + 6);
  sprintf (new_opname, "%s%cur.%s", (has_underbar ? "_" : ""),
	   opname[0], sr_name);
  free (*popname);
  *popname = new_opname;

  return 0;
}


static int
xtensa_translate_zero_immed (const char *old_op,
			     const char *new_op,
			     char **popname,
			     int *pnum_args,
			     char **arg_strings)
{
  char *opname;
  offsetT val;

  opname = *popname;
  gas_assert (opname[0] != '_');

  if (strcmp (opname, old_op) != 0)
    return 0;

  if (xg_check_num_args (pnum_args, 3, opname, arg_strings))
    return -1;
  if (xg_arg_is_constant (arg_strings[1], &val) && val == 0)
    {
      xg_replace_opname (popname, new_op);
      free (arg_strings[1]);
      arg_strings[1] = arg_strings[2];
      arg_strings[2] = 0;
      *pnum_args = 2;
    }

  return 0;
}


/* If the instruction is an idiom (i.e., a built-in macro), translate it.
   Returns non-zero if an error was found.  */

static int
xg_translate_idioms (char **popname, int *pnum_args, char **arg_strings)
{
  char *opname = *popname;
  bfd_boolean has_underbar = FALSE;

  if (*opname == '_')
    {
      has_underbar = TRUE;
      opname += 1;
    }

  if (strcmp (opname, "mov") == 0)
    {
      if (use_transform () && !has_underbar && density_supported)
	xg_replace_opname (popname, "mov.n");
      else
	{
	  if (xg_check_num_args (pnum_args, 2, opname, arg_strings))
	    return -1;
	  xg_replace_opname (popname, (has_underbar ? "_or" : "or"));
	  arg_strings[2] = xstrdup (arg_strings[1]);
	  *pnum_args = 3;
	}
      return 0;
    }

  if (strcmp (opname, "bbsi.l") == 0)
    {
      if (xg_check_num_args (pnum_args, 3, opname, arg_strings))
	return -1;
      xg_replace_opname (popname, (has_underbar ? "_bbsi" : "bbsi"));
      if (target_big_endian)
	xg_reverse_shift_count (&arg_strings[1]);
      return 0;
    }

  if (strcmp (opname, "bbci.l") == 0)
    {
      if (xg_check_num_args (pnum_args, 3, opname, arg_strings))
	return -1;
      xg_replace_opname (popname, (has_underbar ? "_bbci" : "bbci"));
      if (target_big_endian)
	xg_reverse_shift_count (&arg_strings[1]);
      return 0;
    }

  /* Don't do anything special with NOPs inside FLIX instructions.  They
     are handled elsewhere.  Real NOP instructions are always available
     in configurations with FLIX, so this should never be an issue but
     check for it anyway.  */
  if (!cur_vinsn.inside_bundle && xtensa_nop_opcode == XTENSA_UNDEFINED
      && strcmp (opname, "nop") == 0)
    {
      if (use_transform () && !has_underbar && density_supported)
	xg_replace_opname (popname, "nop.n");
      else
	{
	  if (xg_check_num_args (pnum_args, 0, opname, arg_strings))
	    return -1;
	  xg_replace_opname (popname, (has_underbar ? "_or" : "or"));
	  arg_strings[0] = xstrdup ("a1");
	  arg_strings[1] = xstrdup ("a1");
	  arg_strings[2] = xstrdup ("a1");
	  *pnum_args = 3;
	}
      return 0;
    }

  /* Recognize [RW]UR and [RWX]SR.  */
  if ((((opname[0] == 'r' || opname[0] == 'w')
	&& (opname[1] == 'u' || opname[1] == 's'))
       || (opname[0] == 'x' && opname[1] == 's'))
      && opname[2] == 'r'
      && opname[3] == '\0')
    return xg_translate_sysreg_op (popname, pnum_args, arg_strings);

  /* Backward compatibility for RUR and WUR: Recognize [RW]UR<nnn> and
     [RW]<name> if <name> is the non-default name of a user register.  */
  if ((opname[0] == 'r' || opname[0] == 'w')
      && xtensa_opcode_lookup (xtensa_default_isa, opname) == XTENSA_UNDEFINED)
    return xtensa_translate_old_userreg_ops (popname);

  /* Relax branches that don't allow comparisons against an immediate value
     of zero to the corresponding branches with implicit zero immediates.  */
  if (!has_underbar && use_transform ())
    {
      if (xtensa_translate_zero_immed ("bnei", "bnez", popname,
				       pnum_args, arg_strings))
	return -1;

      if (xtensa_translate_zero_immed ("beqi", "beqz", popname,
				       pnum_args, arg_strings))
	return -1;

      if (xtensa_translate_zero_immed ("bgei", "bgez", popname,
				       pnum_args, arg_strings))
	return -1;

      if (xtensa_translate_zero_immed ("blti", "bltz", popname,
				       pnum_args, arg_strings))
	return -1;
    }

  return 0;
}


/* Functions for dealing with the Xtensa ISA.  */

/* Currently the assembler only allows us to use a single target per
   fragment.  Because of this, only one operand for a given
   instruction may be symbolic.  If there is a PC-relative operand,
   the last one is chosen.  Otherwise, the result is the number of the
   last immediate operand, and if there are none of those, we fail and
   return -1.  */

static int
get_relaxable_immed (xtensa_opcode opcode)
{
  int last_immed = -1;
  int noperands, opi;

  if (opcode == XTENSA_UNDEFINED)
    return -1;

  noperands = xtensa_opcode_num_operands (xtensa_default_isa, opcode);
  for (opi = noperands - 1; opi >= 0; opi--)
    {
      if (xtensa_operand_is_visible (xtensa_default_isa, opcode, opi) == 0)
	continue;
      if (xtensa_operand_is_PCrelative (xtensa_default_isa, opcode, opi) == 1)
	return opi;
      if (last_immed == -1
	  && xtensa_operand_is_register (xtensa_default_isa, opcode, opi) == 0)
	last_immed = opi;
    }
  return last_immed;
}


static xtensa_opcode
get_opcode_from_buf (const char *buf, int slot)
{
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt;

  if (!insnbuf)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  xtensa_insnbuf_from_chars (isa, insnbuf, (const unsigned char *) buf, 0);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;

  if (slot >= xtensa_format_num_slots (isa, fmt))
    return XTENSA_UNDEFINED;

  xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
  return xtensa_opcode_decode (isa, fmt, slot, slotbuf);
}


#ifdef TENSILICA_DEBUG

/* For debugging, print out the mapping of opcode numbers to opcodes.  */

static void
xtensa_print_insn_table (void)
{
  int num_opcodes, num_operands;
  xtensa_opcode opcode;
  xtensa_isa isa = xtensa_default_isa;

  num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
  for (opcode = 0; opcode < num_opcodes; opcode++)
    {
      int opn;
      fprintf (stderr, "%d: %s: ", opcode, xtensa_opcode_name (isa, opcode));
      num_operands = xtensa_opcode_num_operands (isa, opcode);
      for (opn = 0; opn < num_operands; opn++)
	{
	  if (xtensa_operand_is_visible (isa, opcode, opn) == 0)
	    continue;
	  if (xtensa_operand_is_register (isa, opcode, opn) == 1)
	    {
	      xtensa_regfile opnd_rf =
		xtensa_operand_regfile (isa, opcode, opn);
	      fprintf (stderr, "%s ", xtensa_regfile_shortname (isa, opnd_rf));
	    }
	  else if (xtensa_operand_is_PCrelative (isa, opcode, opn) == 1)
	    fputs ("[lLr] ", stderr);
	  else
	    fputs ("i ", stderr);
	}
      fprintf (stderr, "\n");
    }
}


static void
print_vliw_insn (xtensa_insnbuf vbuf)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format f = xtensa_format_decode (isa, vbuf);
  xtensa_insnbuf sbuf = xtensa_insnbuf_alloc (isa);
  int op;

  fprintf (stderr, "format = %d\n", f);

  for (op = 0; op < xtensa_format_num_slots (isa, f); op++)
    {
      xtensa_opcode opcode;
      const char *opname;
      int operands;

      xtensa_format_get_slot (isa, f, op, vbuf, sbuf);
      opcode = xtensa_opcode_decode (isa, f, op, sbuf);
      opname = xtensa_opcode_name (isa, opcode);

      fprintf (stderr, "op in slot %i is %s;\n", op, opname);
      fprintf (stderr, "   operands = ");
      for (operands = 0;
	   operands < xtensa_opcode_num_operands (isa, opcode);
	   operands++)
	{
	  unsigned int val;
	  if (xtensa_operand_is_visible (isa, opcode, operands) == 0)
	    continue;
	  xtensa_operand_get_field (isa, opcode, operands, f, op, sbuf, &val);
	  xtensa_operand_decode (isa, opcode, operands, &val);
	  fprintf (stderr, "%d ", val);
	}
      fprintf (stderr, "\n");
    }
  xtensa_insnbuf_free (isa, sbuf);
}

#endif /* TENSILICA_DEBUG */


static bfd_boolean
is_direct_call_opcode (xtensa_opcode opcode)
{
  xtensa_isa isa = xtensa_default_isa;
  int n, num_operands;

  if (xtensa_opcode_is_call (isa, opcode) != 1)
    return FALSE;

  num_operands = xtensa_opcode_num_operands (isa, opcode);
  for (n = 0; n < num_operands; n++)
    {
      if (xtensa_operand_is_register (isa, opcode, n) == 0
	  && xtensa_operand_is_PCrelative (isa, opcode, n) == 1)
	return TRUE;
    }
  return FALSE;
}


/* Convert from BFD relocation type code to slot and operand number.
   Returns non-zero on failure.  */

static int
decode_reloc (bfd_reloc_code_real_type reloc, int *slot, bfd_boolean *is_alt)
{
  if (reloc >= BFD_RELOC_XTENSA_SLOT0_OP
      && reloc <= BFD_RELOC_XTENSA_SLOT14_OP)
    {
      *slot = reloc - BFD_RELOC_XTENSA_SLOT0_OP;
      *is_alt = FALSE;
    }
  else if (reloc >= BFD_RELOC_XTENSA_SLOT0_ALT
      && reloc <= BFD_RELOC_XTENSA_SLOT14_ALT)
    {
      *slot = reloc - BFD_RELOC_XTENSA_SLOT0_ALT;
      *is_alt = TRUE;
    }
  else
    return -1;

  return 0;
}


/* Convert from slot number to BFD relocation type code for the
   standard PC-relative relocations.  Return BFD_RELOC_NONE on
   failure.  */

static bfd_reloc_code_real_type
encode_reloc (int slot)
{
  if (slot < 0 || slot > 14)
    return BFD_RELOC_NONE;

  return BFD_RELOC_XTENSA_SLOT0_OP + slot;
}


/* Convert from slot numbers to BFD relocation type code for the
   "alternate" relocations.  Return BFD_RELOC_NONE on failure.  */

static bfd_reloc_code_real_type
encode_alt_reloc (int slot)
{
  if (slot < 0 || slot > 14)
    return BFD_RELOC_NONE;

  return BFD_RELOC_XTENSA_SLOT0_ALT + slot;
}


static void
xtensa_insnbuf_set_operand (xtensa_insnbuf slotbuf,
			    xtensa_format fmt,
			    int slot,
			    xtensa_opcode opcode,
			    int operand,
			    uint32 value,
			    const char *file,
			    unsigned int line)
{
  uint32 valbuf = value;

  if (xtensa_operand_encode (xtensa_default_isa, opcode, operand, &valbuf))
    {
      if (xtensa_operand_is_PCrelative (xtensa_default_isa, opcode, operand)
	  == 1)
	as_bad_where ((char *) file, line,
		      _("operand %d of '%s' has out of range value '%u'"),
		      operand + 1,
		      xtensa_opcode_name (xtensa_default_isa, opcode),
		      value);
      else
	as_bad_where ((char *) file, line,
		      _("operand %d of '%s' has invalid value '%u'"),
		      operand + 1,
		      xtensa_opcode_name (xtensa_default_isa, opcode),
		      value);
      return;
    }

  xtensa_operand_set_field (xtensa_default_isa, opcode, operand, fmt, slot,
			    slotbuf, valbuf);
}


static uint32
xtensa_insnbuf_get_operand (xtensa_insnbuf slotbuf,
			    xtensa_format fmt,
			    int slot,
			    xtensa_opcode opcode,
			    int opnum)
{
  uint32 val = 0;
  (void) xtensa_operand_get_field (xtensa_default_isa, opcode, opnum,
				   fmt, slot, slotbuf, &val);
  (void) xtensa_operand_decode (xtensa_default_isa, opcode, opnum, &val);
  return val;
}


/* Checks for rules from xtensa-relax tables.  */

/* The routine xg_instruction_matches_option_term must return TRUE
   when a given option term is true.  The meaning of all of the option
   terms is given interpretation by this function.  */

static bfd_boolean
xg_instruction_matches_option_term (TInsn *insn, const ReqOrOption *option)
{
  if (strcmp (option->option_name, "realnop") == 0
      || strncmp (option->option_name, "IsaUse", 6) == 0)
    {
      /* These conditions were evaluated statically when building the
	 relaxation table.  There's no need to reevaluate them now.  */
      return TRUE;
    }
  else if (strcmp (option->option_name, "FREEREG") == 0)
    return insn->extra_arg.X_op == O_register;
  else
    {
      as_fatal (_("internal error: unknown option name '%s'"),
		option->option_name);
    }
}


static bfd_boolean
xg_instruction_matches_or_options (TInsn *insn,
				   const ReqOrOptionList *or_option)
{
  const ReqOrOption *option;
  /* Must match each of the AND terms.  */
  for (option = or_option; option != NULL; option = option->next)
    {
      if (xg_instruction_matches_option_term (insn, option))
	return TRUE;
    }
  return FALSE;
}


static bfd_boolean
xg_instruction_matches_options (TInsn *insn, const ReqOptionList *options)
{
  const ReqOption *req_options;
  /* Must match each of the AND terms.  */
  for (req_options = options;
       req_options != NULL;
       req_options = req_options->next)
    {
      /* Must match one of the OR clauses.  */
      if (!xg_instruction_matches_or_options (insn,
					      req_options->or_option_terms))
	return FALSE;
    }
  return TRUE;
}


/* Return the transition rule that matches or NULL if none matches.  */

static bfd_boolean
xg_instruction_matches_rule (TInsn *insn, TransitionRule *rule)
{
  PreconditionList *condition_l;

  if (rule->opcode != insn->opcode)
    return FALSE;

  for (condition_l = rule->conditions;
       condition_l != NULL;
       condition_l = condition_l->next)
    {
      expressionS *exp1;
      expressionS *exp2;
      Precondition *cond = condition_l->precond;

      switch (cond->typ)
	{
	case OP_CONSTANT:
	  /* The expression must be the constant.  */
	  gas_assert (cond->op_num < insn->ntok);
	  exp1 = &insn->tok[cond->op_num];
	  if (expr_is_const (exp1))
	    {
	      switch (cond->cmp)
		{
		case OP_EQUAL:
		  if (get_expr_const (exp1) != cond->op_data)
		    return FALSE;
		  break;
		case OP_NOTEQUAL:
		  if (get_expr_const (exp1) == cond->op_data)
		    return FALSE;
		  break;
		default:
		  return FALSE;
		}
	    }
	  else if (expr_is_register (exp1))
	    {
	      switch (cond->cmp)
		{
		case OP_EQUAL:
		  if (get_expr_register (exp1) != cond->op_data)
		    return FALSE;
		  break;
		case OP_NOTEQUAL:
		  if (get_expr_register (exp1) == cond->op_data)
		    return FALSE;
		  break;
		default:
		  return FALSE;
		}
	    }
	  else
	    return FALSE;
	  break;

	case OP_OPERAND:
	  gas_assert (cond->op_num < insn->ntok);
	  gas_assert (cond->op_data < insn->ntok);
	  exp1 = &insn->tok[cond->op_num];
	  exp2 = &insn->tok[cond->op_data];

	  switch (cond->cmp)
	    {
	    case OP_EQUAL:
	      if (!expr_is_equal (exp1, exp2))
		return FALSE;
	      break;
	    case OP_NOTEQUAL:
	      if (expr_is_equal (exp1, exp2))
		return FALSE;
	      break;
	    }
	  break;

	case OP_LITERAL:
	case OP_LABEL:
	default:
	  return FALSE;
	}
    }
  if (!xg_instruction_matches_options (insn, rule->options))
    return FALSE;

  return TRUE;
}


static int
transition_rule_cmp (const TransitionRule *a, const TransitionRule *b)
{
  bfd_boolean a_greater = FALSE;
  bfd_boolean b_greater = FALSE;

  ReqOptionList *l_a = a->options;
  ReqOptionList *l_b = b->options;

  /* We only care if they both are the same except for
     a const16 vs. an l32r.  */

  while (l_a && l_b && ((l_a->next == NULL) == (l_b->next == NULL)))
    {
      ReqOrOptionList *l_or_a = l_a->or_option_terms;
      ReqOrOptionList *l_or_b = l_b->or_option_terms;
      while (l_or_a && l_or_b && ((l_a->next == NULL) == (l_b->next == NULL)))
	{
	  if (l_or_a->is_true != l_or_b->is_true)
	    return 0;
	  if (strcmp (l_or_a->option_name, l_or_b->option_name) != 0)
	    {
	      /* This is the case we care about.  */
	      if (strcmp (l_or_a->option_name, "IsaUseConst16") == 0
		  && strcmp (l_or_b->option_name, "IsaUseL32R") == 0)
		{
		  if (prefer_const16)
		    a_greater = TRUE;
		  else
		    b_greater = TRUE;
		}
	      else if (strcmp (l_or_a->option_name, "IsaUseL32R") == 0
		       && strcmp (l_or_b->option_name, "IsaUseConst16") == 0)
		{
		  if (prefer_const16)
		    b_greater = TRUE;
		  else
		    a_greater = TRUE;
		}
	      else
		return 0;
	    }
	  l_or_a = l_or_a->next;
	  l_or_b = l_or_b->next;
	}
      if (l_or_a || l_or_b)
	return 0;

      l_a = l_a->next;
      l_b = l_b->next;
    }
  if (l_a || l_b)
    return 0;

  /* Incomparable if the substitution was used differently in two cases.  */
  if (a_greater && b_greater)
    return 0;

  if (b_greater)
    return 1;
  if (a_greater)
    return -1;

  return 0;
}


static TransitionRule *
xg_instruction_match (TInsn *insn)
{
  TransitionTable *table = xg_build_simplify_table (&transition_rule_cmp);
  TransitionList *l;
  gas_assert (insn->opcode < table->num_opcodes);

  /* Walk through all of the possible transitions.  */
  for (l = table->table[insn->opcode]; l != NULL; l = l->next)
    {
      TransitionRule *rule = l->rule;
      if (xg_instruction_matches_rule (insn, rule))
	return rule;
    }
  return NULL;
}


/* Various Other Internal Functions.  */

static bfd_boolean
is_unique_insn_expansion (TransitionRule *r)
{
  if (!r->to_instr || r->to_instr->next != NULL)
    return FALSE;
  if (r->to_instr->typ != INSTR_INSTR)
    return FALSE;
  return TRUE;
}


/* Check if there is exactly one relaxation for INSN that converts it to
   another instruction of equal or larger size.  If so, and if TARG is
   non-null, go ahead and generate the relaxed instruction into TARG.  If
   NARROW_ONLY is true, then only consider relaxations that widen a narrow
   instruction, i.e., ignore relaxations that convert to an instruction of
   equal size.  In some contexts where this function is used, only
   a single widening is allowed and the NARROW_ONLY argument is used to
   exclude cases like ADDI being "widened" to an ADDMI, which may
   later be relaxed to an ADDMI/ADDI pair.  */

bfd_boolean
xg_is_single_relaxable_insn (TInsn *insn, TInsn *targ, bfd_boolean narrow_only)
{
  TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
  TransitionList *l;
  TransitionRule *match = 0;

  gas_assert (insn->insn_type == ITYPE_INSN);
  gas_assert (insn->opcode < table->num_opcodes);

  for (l = table->table[insn->opcode]; l != NULL; l = l->next)
    {
      TransitionRule *rule = l->rule;

      if (xg_instruction_matches_rule (insn, rule)
	  && is_unique_insn_expansion (rule)
	  && (xg_get_single_size (insn->opcode) + (narrow_only ? 1 : 0)
	      <= xg_get_single_size (rule->to_instr->opcode)))
	{
	  if (match)
	    return FALSE;
	  match = rule;
	}
    }
  if (!match)
    return FALSE;

  if (targ)
    xg_build_to_insn (targ, insn, match->to_instr);
  return TRUE;
}


/* Return the maximum number of bytes this opcode can expand to.  */

static int
xg_get_max_insn_widen_size (xtensa_opcode opcode)
{
  TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
  TransitionList *l;
  int max_size = xg_get_single_size (opcode);

  gas_assert (opcode < table->num_opcodes);

  for (l = table->table[opcode]; l != NULL; l = l->next)
    {
      TransitionRule *rule = l->rule;
      BuildInstr *build_list;
      int this_size = 0;

      if (!rule)
	continue;
      build_list = rule->to_instr;
      if (is_unique_insn_expansion (rule))
	{
	  gas_assert (build_list->typ == INSTR_INSTR);
	  this_size = xg_get_max_insn_widen_size (build_list->opcode);
	}
      else
	for (; build_list != NULL; build_list = build_list->next)
	  {
	    switch (build_list->typ)
	      {
	      case INSTR_INSTR:
		this_size += xg_get_single_size (build_list->opcode);
		break;
	      case INSTR_LITERAL_DEF:
	      case INSTR_LABEL_DEF:
	      default:
		break;
	      }
	  }
      if (this_size > max_size)
	max_size = this_size;
    }
  return max_size;
}


/* Return the maximum number of literal bytes this opcode can generate.  */

static int
xg_get_max_insn_widen_literal_size (xtensa_opcode opcode)
{
  TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
  TransitionList *l;
  int max_size = 0;

  gas_assert (opcode < table->num_opcodes);

  for (l = table->table[opcode]; l != NULL; l = l->next)
    {
      TransitionRule *rule = l->rule;
      BuildInstr *build_list;
      int this_size = 0;

      if (!rule)
	continue;
      build_list = rule->to_instr;
      if (is_unique_insn_expansion (rule))
	{
	  gas_assert (build_list->typ == INSTR_INSTR);
	  this_size = xg_get_max_insn_widen_literal_size (build_list->opcode);
	}
      else
	for (; build_list != NULL; build_list = build_list->next)
	  {
	    switch (build_list->typ)
	      {
	      case INSTR_LITERAL_DEF:
		/* Hard-coded 4-byte literal.  */
		this_size += 4;
		break;
	      case INSTR_INSTR:
	      case INSTR_LABEL_DEF:
	      default:
		break;
	      }
	  }
      if (this_size > max_size)
	max_size = this_size;
    }
  return max_size;
}


static bfd_boolean
xg_is_relaxable_insn (TInsn *insn, int lateral_steps)
{
  int steps_taken = 0;
  TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
  TransitionList *l;

  gas_assert (insn->insn_type == ITYPE_INSN);
  gas_assert (insn->opcode < table->num_opcodes);

  for (l = table->table[insn->opcode]; l != NULL; l = l->next)
    {
      TransitionRule *rule = l->rule;

      if (xg_instruction_matches_rule (insn, rule))
	{
	  if (steps_taken == lateral_steps)
	    return TRUE;
	  steps_taken++;
	}
    }
  return FALSE;
}


static symbolS *
get_special_literal_symbol (void)
{
  static symbolS *sym = NULL;

  if (sym == NULL)
    sym = symbol_find_or_make ("SPECIAL_LITERAL0\001");
  return sym;
}


static symbolS *
get_special_label_symbol (void)
{
  static symbolS *sym = NULL;

  if (sym == NULL)
    sym = symbol_find_or_make ("SPECIAL_LABEL0\001");
  return sym;
}


static bfd_boolean
xg_valid_literal_expression (const expressionS *exp)
{
  switch (exp->X_op)
    {
    case O_constant:
    case O_symbol:
    case O_big:
    case O_uminus:
    case O_subtract:
    case O_pltrel:
    case O_pcrel:
    case O_tlsfunc:
    case O_tlsarg:
    case O_tpoff:
    case O_dtpoff:
      return TRUE;
    default:
      return FALSE;
    }
}


/* This will check to see if the value can be converted into the
   operand type.  It will return TRUE if it does not fit.  */

static bfd_boolean
xg_check_operand (int32 value, xtensa_opcode opcode, int operand)
{
  uint32 valbuf = value;
  if (xtensa_operand_encode (xtensa_default_isa, opcode, operand, &valbuf))
    return TRUE;
  return FALSE;
}


/* Assumes: All immeds are constants.  Check that all constants fit
   into their immeds; return FALSE if not.  */

static bfd_boolean
xg_immeds_fit (const TInsn *insn)
{
  xtensa_isa isa = xtensa_default_isa;
  int i;

  int n = insn->ntok;
  gas_assert (insn->insn_type == ITYPE_INSN);
  for (i = 0; i < n; ++i)
    {
      const expressionS *exp = &insn->tok[i];

      if (xtensa_operand_is_register (isa, insn->opcode, i) == 1)
	continue;

      switch (exp->X_op)
	{
	case O_register:
	case O_constant:
	  if (xg_check_operand (exp->X_add_number, insn->opcode, i))
	    return FALSE;
	  break;

	default:
	  /* The symbol should have a fixup associated with it.  */
	  gas_assert (FALSE);
	  break;
	}
    }
  return TRUE;
}


/* This should only be called after we have an initial
   estimate of the addresses.  */

static bfd_boolean
xg_symbolic_immeds_fit (const TInsn *insn,
			segT pc_seg,
			fragS *pc_frag,
			offsetT pc_offset,
			long stretch)
{
  xtensa_isa isa = xtensa_default_isa;
  symbolS *symbolP;
  fragS *sym_frag;
  offsetT target, pc;
  uint32 new_offset;
  int i;
  int n = insn->ntok;

  gas_assert (insn->insn_type == ITYPE_INSN);

  for (i = 0; i < n; ++i)
    {
      const expressionS *exp = &insn->tok[i];

      if (xtensa_operand_is_register (isa, insn->opcode, i) == 1)
	continue;

      switch (exp->X_op)
	{
	case O_register:
	case O_constant:
	  if (xg_check_operand (exp->X_add_number, insn->opcode, i))
	    return FALSE;
	  break;

	case O_lo16:
	case O_hi16:
	  /* Check for the worst case.  */
	  if (xg_check_operand (0xffff, insn->opcode, i))
	    return FALSE;
	  break;

	case O_symbol:
	  /* We only allow symbols for PC-relative references.
	     If pc_frag == 0, then we don't have frag locations yet.  */
	  if (pc_frag == 0
	      || xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 0)
	    return FALSE;

	  /* If it is a weak symbol or a symbol in a different section,
	     it cannot be known to fit at assembly time.  */
	  if (S_IS_WEAK (exp->X_add_symbol)
	      || S_GET_SEGMENT (exp->X_add_symbol) != pc_seg)
	    {
	      /* For a direct call with --no-longcalls, be optimistic and
		 assume it will be in range.  If the symbol is weak and
		 undefined, it may remain undefined at link-time, in which
		 case it will have a zero value and almost certainly be out
		 of range for a direct call; thus, relax for undefined weak
		 symbols even if longcalls is not enabled.  */
	      if (is_direct_call_opcode (insn->opcode)
		  && ! pc_frag->tc_frag_data.use_longcalls
		  && (! S_IS_WEAK (exp->X_add_symbol)
		      || S_IS_DEFINED (exp->X_add_symbol)))
		return TRUE;

	      return FALSE;
	    }

	  symbolP = exp->X_add_symbol;
	  sym_frag = symbol_get_frag (symbolP);
	  target = S_GET_VALUE (symbolP) + exp->X_add_number;
	  pc = pc_frag->fr_address + pc_offset;

	  /* If frag has yet to be reached on this pass, assume it
	     will move by STRETCH just as we did.  If this is not so,
	     it will be because some frag between grows, and that will
	     force another pass.  Beware zero-length frags.  There
	     should be a faster way to do this.  */

	  if (stretch != 0
	      && sym_frag->relax_marker != pc_frag->relax_marker
	      && S_GET_SEGMENT (symbolP) == pc_seg)
	    {
	      target += stretch;
	    }

	  new_offset = target;
	  xtensa_operand_do_reloc (isa, insn->opcode, i, &new_offset, pc);
	  if (xg_check_operand (new_offset, insn->opcode, i))
	    return FALSE;
	  break;

	default:
	  /* The symbol should have a fixup associated with it.  */
	  return FALSE;
	}
    }

  return TRUE;
}


/* Return TRUE on success.  */

static bfd_boolean
xg_build_to_insn (TInsn *targ, TInsn *insn, BuildInstr *bi)
{
  BuildOp *op;
  symbolS *sym;

  tinsn_init (targ);
  targ->debug_line = insn->debug_line;
  targ->loc_directive_seen = insn->loc_directive_seen;
  switch (bi->typ)
    {
    case INSTR_INSTR:
      op = bi->ops;
      targ->opcode = bi->opcode;
      targ->insn_type = ITYPE_INSN;
      targ->is_specific_opcode = FALSE;

      for (; op != NULL; op = op->next)
	{
	  int op_num = op->op_num;
	  int op_data = op->op_data;

	  gas_assert (op->op_num < MAX_INSN_ARGS);

	  if (targ->ntok <= op_num)
	    targ->ntok = op_num + 1;

	  switch (op->typ)
	    {
	    case OP_CONSTANT:
	      set_expr_const (&targ->tok[op_num], op_data);
	      break;
	    case OP_OPERAND:
	      gas_assert (op_data < insn->ntok);
	      copy_expr (&targ->tok[op_num], &insn->tok[op_data]);
	      break;
	    case OP_FREEREG:
	      if (insn->extra_arg.X_op != O_register)
		return FALSE;
	      copy_expr (&targ->tok[op_num], &insn->extra_arg);
	      break;
	    case OP_LITERAL:
	      sym = get_special_literal_symbol ();
	      set_expr_symbol_offset (&targ->tok[op_num], sym, 0);
	      if (insn->tok[op_data].X_op == O_tlsfunc
		  || insn->tok[op_data].X_op == O_tlsarg)
		copy_expr (&targ->extra_arg, &insn->tok[op_data]);
	      break;
	    case OP_LABEL:
	      sym = get_special_label_symbol ();
	      set_expr_symbol_offset (&targ->tok[op_num], sym, 0);
	      break;
	    case OP_OPERAND_HI16U:
	    case OP_OPERAND_LOW16U:
	      gas_assert (op_data < insn->ntok);
	      if (expr_is_const (&insn->tok[op_data]))
		{
		  long val;
		  copy_expr (&targ->tok[op_num], &insn->tok[op_data]);
		  val = xg_apply_userdef_op_fn (op->typ,
						targ->tok[op_num].
						X_add_number);
		  targ->tok[op_num].X_add_number = val;
		}
	      else
		{
		  /* For const16 we can create relocations for these.  */
		  if (targ->opcode == XTENSA_UNDEFINED
		      || (targ->opcode != xtensa_const16_opcode))
		    return FALSE;
		  gas_assert (op_data < insn->ntok);
		  /* Need to build a O_lo16 or O_hi16.  */
		  copy_expr (&targ->tok[op_num], &insn->tok[op_data]);
		  if (targ->tok[op_num].X_op == O_symbol)
		    {
		      if (op->typ == OP_OPERAND_HI16U)
			targ->tok[op_num].X_op = O_hi16;
		      else if (op->typ == OP_OPERAND_LOW16U)
			targ->tok[op_num].X_op = O_lo16;
		      else
			return FALSE;
		    }
		}
	      break;
	    default:
	      /* currently handles:
		 OP_OPERAND_LOW8
		 OP_OPERAND_HI24S
		 OP_OPERAND_F32MINUS */
	      if (xg_has_userdef_op_fn (op->typ))
		{
		  gas_assert (op_data < insn->ntok);
		  if (expr_is_const (&insn->tok[op_data]))
		    {
		      long val;
		      copy_expr (&targ->tok[op_num], &insn->tok[op_data]);
		      val = xg_apply_userdef_op_fn (op->typ,
						    targ->tok[op_num].
						    X_add_number);
		      targ->tok[op_num].X_add_number = val;
		    }
		  else
		    return FALSE; /* We cannot use a relocation for this.  */
		  break;
		}
	      gas_assert (0);
	      break;
	    }
	}
      break;

    case INSTR_LITERAL_DEF:
      op = bi->ops;
      targ->opcode = XTENSA_UNDEFINED;
      targ->insn_type = ITYPE_LITERAL;
      targ->is_specific_opcode = FALSE;
      for (; op != NULL; op = op->next)
	{
	  int op_num = op->op_num;
	  int op_data = op->op_data;
	  gas_assert (op->op_num < MAX_INSN_ARGS);

	  if (targ->ntok <= op_num)
	    targ->ntok = op_num + 1;

	  switch (op->typ)
	    {
	    case OP_OPERAND:
	      gas_assert (op_data < insn->ntok);
	      /* We can only pass resolvable literals through.  */
	      if (!xg_valid_literal_expression (&insn->tok[op_data]))
		return FALSE;
	      copy_expr (&targ->tok[op_num], &insn->tok[op_data]);
	      break;
	    case OP_LITERAL:
	    case OP_CONSTANT:
	    case OP_LABEL:
	    default:
	      gas_assert (0);
	      break;
	    }
	}
      break;

    case INSTR_LABEL_DEF:
      op = bi->ops;
      targ->opcode = XTENSA_UNDEFINED;
      targ->insn_type = ITYPE_LABEL;
      targ->is_specific_opcode = FALSE;
      /* Literal with no ops is a label?  */
      gas_assert (op == NULL);
      break;

    default:
      gas_assert (0);
    }

  return TRUE;
}


/* Return TRUE on success.  */

static bfd_boolean
xg_build_to_stack (IStack *istack, TInsn *insn, BuildInstr *bi)
{
  for (; bi != NULL; bi = bi->next)
    {
      TInsn *next_insn = istack_push_space (istack);

      if (!xg_build_to_insn (next_insn, insn, bi))
	return FALSE;
    }
  return TRUE;
}


/* Return TRUE on valid expansion.  */

static bfd_boolean
xg_expand_to_stack (IStack *istack, TInsn *insn, int lateral_steps)
{
  int stack_size = istack->ninsn;
  int steps_taken = 0;
  TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
  TransitionList *l;

  gas_assert (insn->insn_type == ITYPE_INSN);
  gas_assert (insn->opcode < table->num_opcodes);

  for (l = table->table[insn->opcode]; l != NULL; l = l->next)
    {
      TransitionRule *rule = l->rule;

      if (xg_instruction_matches_rule (insn, rule))
	{
	  if (lateral_steps == steps_taken)
	    {
	      int i;

	      /* This is it.  Expand the rule to the stack.  */
	      if (!xg_build_to_stack (istack, insn, rule->to_instr))
		return FALSE;

	      /* Check to see if it fits.  */
	      for (i = stack_size; i < istack->ninsn; i++)
		{
		  TInsn *tinsn = &istack->insn[i];

		  if (tinsn->insn_type == ITYPE_INSN
		      && !tinsn_has_symbolic_operands (tinsn)
		      && !xg_immeds_fit (tinsn))
		    {
		      istack->ninsn = stack_size;
		      return FALSE;
		    }
		}
	      return TRUE;
	    }
	  steps_taken++;
	}
    }
  return FALSE;
}


/* Relax the assembly instruction at least "min_steps".
   Return the number of steps taken.

   For relaxation to correctly terminate, every relaxation chain must
   terminate in one of two ways:

   1.  If the chain from one instruction to the next consists entirely of
       single instructions, then the chain *must* handle all possible
       immediates without failing.  It must not ever fail because an
       immediate is out of range.  The MOVI.N -> MOVI -> L32R relaxation
       chain is one example.  L32R loads 32 bits, and there cannot be an
       immediate larger than 32 bits, so it satisfies this condition.
       Single instruction relaxation chains are as defined by
       xg_is_single_relaxable_instruction.

   2.  Otherwise, the chain must end in a multi-instruction expansion: e.g.,
       BNEZ.N -> BNEZ -> BNEZ.W15 -> BENZ.N/J

   Strictly speaking, in most cases you can violate condition 1 and be OK
   -- in particular when the last two instructions have the same single
   size.  But nevertheless, you should guarantee the above two conditions.

   We could fix this so that single-instruction expansions correctly
   terminate when they can't handle the range, but the error messages are
   worse, and it actually turns out that in every case but one (18-bit wide
   branches), you need a multi-instruction expansion to get the full range
   anyway.  And because 18-bit branches are handled identically to 15-bit
   branches, there isn't any point in changing it.  */

static int
xg_assembly_relax (IStack *istack,
		   TInsn *insn,
		   segT pc_seg,
		   fragS *pc_frag,	/* if pc_frag == 0, not pc-relative */
		   offsetT pc_offset,	/* offset in fragment */
		   int min_steps,	/* minimum conversion steps */
		   long stretch)	/* number of bytes stretched so far */
{
  int steps_taken = 0;

  /* Some of its immeds don't fit.  Try to build a relaxed version.
     This may go through a couple of stages of single instruction
     transformations before we get there.  */

  TInsn single_target;
  TInsn current_insn;
  int lateral_steps = 0;
  int istack_size = istack->ninsn;

  if (xg_symbolic_immeds_fit (insn, pc_seg, pc_frag, pc_offset, stretch)
      && steps_taken >= min_steps)
    {
      istack_push (istack, insn);
      return steps_taken;
    }
  current_insn = *insn;

  /* Walk through all of the single instruction expansions.  */
  while (xg_is_single_relaxable_insn (&current_insn, &single_target, FALSE))
    {
      steps_taken++;
      if (xg_symbolic_immeds_fit (&single_target, pc_seg, pc_frag, pc_offset,
				  stretch))
	{
	  if (steps_taken >= min_steps)
	    {
	      istack_push (istack, &single_target);
	      return steps_taken;
	    }
	}
      current_insn = single_target;
    }

  /* Now check for a multi-instruction expansion.  */
  while (xg_is_relaxable_insn (&current_insn, lateral_steps))
    {
      if (xg_symbolic_immeds_fit (&current_insn, pc_seg, pc_frag, pc_offset,
				  stretch))
	{
	  if (steps_taken >= min_steps)
	    {
	      istack_push (istack, &current_insn);
	      return steps_taken;
	    }
	}
      steps_taken++;
      if (xg_expand_to_stack (istack, &current_insn, lateral_steps))
	{
	  if (steps_taken >= min_steps)
	    return steps_taken;
	}
      lateral_steps++;
      istack->ninsn = istack_size;
    }

  /* It's not going to work -- use the original.  */
  istack_push (istack, insn);
  return steps_taken;
}


static void
xg_finish_frag (char *last_insn,
		enum xtensa_relax_statesE frag_state,
		enum xtensa_relax_statesE slot0_state,
		int max_growth,
		bfd_boolean is_insn)
{
  /* Finish off this fragment so that it has at LEAST the desired
     max_growth.  If it doesn't fit in this fragment, close this one
     and start a new one.  In either case, return a pointer to the
     beginning of the growth area.  */

  fragS *old_frag;

  frag_grow (max_growth);
  old_frag = frag_now;

  frag_now->fr_opcode = last_insn;
  if (is_insn)
    frag_now->tc_frag_data.is_insn = TRUE;

  frag_var (rs_machine_dependent, max_growth, max_growth,
	    frag_state, frag_now->fr_symbol, frag_now->fr_offset, last_insn);

  old_frag->tc_frag_data.slot_subtypes[0] = slot0_state;
  xtensa_set_frag_assembly_state (frag_now);

  /* Just to make sure that we did not split it up.  */
  gas_assert (old_frag->fr_next == frag_now);
}


/* Return TRUE if the target frag is one of the next non-empty frags.  */

static bfd_boolean
is_next_frag_target (const fragS *fragP, const fragS *target)
{
  if (fragP == NULL)
    return FALSE;

  for (; fragP; fragP = fragP->fr_next)
    {
      if (fragP == target)
	return TRUE;
      if (fragP->fr_fix != 0)
	return FALSE;
      if (fragP->fr_type == rs_fill && fragP->fr_offset != 0)
	return FALSE;
      if ((fragP->fr_type == rs_align || fragP->fr_type == rs_align_code)
	  && ((fragP->fr_address % (1 << fragP->fr_offset)) != 0))
	return FALSE;
      if (fragP->fr_type == rs_space)
	return FALSE;
    }
  return FALSE;
}


static bfd_boolean
is_branch_jmp_to_next (TInsn *insn, fragS *fragP)
{
  xtensa_isa isa = xtensa_default_isa;
  int i;
  int num_ops = xtensa_opcode_num_operands (isa, insn->opcode);
  int target_op = -1;
  symbolS *sym;
  fragS *target_frag;

  if (xtensa_opcode_is_branch (isa, insn->opcode) != 1
      && xtensa_opcode_is_jump (isa, insn->opcode) != 1)
    return FALSE;

  for (i = 0; i < num_ops; i++)
    {
      if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 1)
	{
	  target_op = i;
	  break;
	}
    }
  if (target_op == -1)
    return FALSE;

  if (insn->ntok <= target_op)
    return FALSE;

  if (insn->tok[target_op].X_op != O_symbol)
    return FALSE;

  sym = insn->tok[target_op].X_add_symbol;
  if (sym == NULL)
    return FALSE;

  if (insn->tok[target_op].X_add_number != 0)
    return FALSE;

  target_frag = symbol_get_frag (sym);
  if (target_frag == NULL)
    return FALSE;

  if (is_next_frag_target (fragP->fr_next, target_frag)
      && S_GET_VALUE (sym) == target_frag->fr_address)
    return TRUE;

  return FALSE;
}


static void
xg_add_branch_and_loop_targets (TInsn *insn)
{
  xtensa_isa isa = xtensa_default_isa;
  int num_ops = xtensa_opcode_num_operands (isa, insn->opcode);

  if (xtensa_opcode_is_loop (isa, insn->opcode) == 1)
    {
      int i = 1;
      if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 1
	  && insn->tok[i].X_op == O_symbol)
	symbol_get_tc (insn->tok[i].X_add_symbol)->is_loop_target = TRUE;
      return;
    }

  if (xtensa_opcode_is_branch (isa, insn->opcode) == 1
      || xtensa_opcode_is_loop (isa, insn->opcode) == 1)
    {
      int i;

      for (i = 0; i < insn->ntok && i < num_ops; i++)
	{
	  if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 1
	      && insn->tok[i].X_op == O_symbol)
	    {
	      symbolS *sym = insn->tok[i].X_add_symbol;
	      symbol_get_tc (sym)->is_branch_target = TRUE;
	      if (S_IS_DEFINED (sym))
		symbol_get_frag (sym)->tc_frag_data.is_branch_target = TRUE;
	    }
	}
    }
}


/* Return FALSE if no error.  */

static bfd_boolean
xg_build_token_insn (BuildInstr *instr_spec, TInsn *old_insn, TInsn *new_insn)
{
  int num_ops = 0;
  BuildOp *b_op;

  switch (instr_spec->typ)
    {
    case INSTR_INSTR:
      new_insn->insn_type = ITYPE_INSN;
      new_insn->opcode = instr_spec->opcode;
      break;
    case INSTR_LITERAL_DEF:
      new_insn->insn_type = ITYPE_LITERAL;
      new_insn->opcode = XTENSA_UNDEFINED;
      break;
    case INSTR_LABEL_DEF:
      abort ();
    }
  new_insn->is_specific_opcode = FALSE;
  new_insn->debug_line = old_insn->debug_line;
  new_insn->loc_directive_seen = old_insn->loc_directive_seen;

  for (b_op = instr_spec->ops; b_op != NULL; b_op = b_op->next)
    {
      expressionS *exp;
      const expressionS *src_exp;

      num_ops++;
      switch (b_op->typ)
	{
	case OP_CONSTANT:
	  /* The expression must be the constant.  */
	  gas_assert (b_op->op_num < MAX_INSN_ARGS);
	  exp = &new_insn->tok[b_op->op_num];
	  set_expr_const (exp, b_op->op_data);
	  break;

	case OP_OPERAND:
	  gas_assert (b_op->op_num < MAX_INSN_ARGS);
	  gas_assert (b_op->op_data < (unsigned) old_insn->ntok);
	  src_exp = &old_insn->tok[b_op->op_data];
	  exp = &new_insn->tok[b_op->op_num];
	  copy_expr (exp, src_exp);
	  break;

	case OP_LITERAL:
	case OP_LABEL:
	  as_bad (_("can't handle generation of literal/labels yet"));
	  gas_assert (0);

	default:
	  as_bad (_("can't handle undefined OP TYPE"));
	  gas_assert (0);
	}
    }

  new_insn->ntok = num_ops;
  return FALSE;
}


/* Return TRUE if it was simplified.  */

static bfd_boolean
xg_simplify_insn (TInsn *old_insn, TInsn *new_insn)
{
  TransitionRule *rule;
  BuildInstr *insn_spec;

  if (old_insn->is_specific_opcode || !density_supported)
    return FALSE;

  rule = xg_instruction_match (old_insn);
  if (rule == NULL)
    return FALSE;

  insn_spec = rule->to_instr;
  /* There should only be one.  */
  gas_assert (insn_spec != NULL);
  gas_assert (insn_spec->next == NULL);
  if (insn_spec->next != NULL)
    return FALSE;

  xg_build_token_insn (insn_spec, old_insn, new_insn);

  return TRUE;
}


/* xg_expand_assembly_insn: (1) Simplify the instruction, i.e., l32i ->
   l32i.n. (2) Check the number of operands.  (3) Place the instruction
   tokens into the stack or relax it and place multiple
   instructions/literals onto the stack.  Return FALSE if no error.  */

static bfd_boolean
xg_expand_assembly_insn (IStack *istack, TInsn *orig_insn)
{
  int noperands;
  TInsn new_insn;
  bfd_boolean do_expand;

  tinsn_init (&new_insn);

  /* Narrow it if we can.  xg_simplify_insn now does all the
     appropriate checking (e.g., for the density option).  */
  if (xg_simplify_insn (orig_insn, &new_insn))
    orig_insn = &new_insn;

  noperands = xtensa_opcode_num_operands (xtensa_default_isa,
					  orig_insn->opcode);
  if (orig_insn->ntok < noperands)
    {
      as_bad (_("found %d operands for '%s':  Expected %d"),
	      orig_insn->ntok,
	      xtensa_opcode_name (xtensa_default_isa, orig_insn->opcode),
	      noperands);
      return TRUE;
    }
  if (orig_insn->ntok > noperands)
    as_warn (_("found too many (%d) operands for '%s':  Expected %d"),
	     orig_insn->ntok,
	     xtensa_opcode_name (xtensa_default_isa, orig_insn->opcode),
	     noperands);

  /* If there are not enough operands, we will assert above.  If there
     are too many, just cut out the extras here.  */
  orig_insn->ntok = noperands;

  if (tinsn_has_invalid_symbolic_operands (orig_insn))
    return TRUE;

  /* Special case for extui opcode which has constraints not handled
     by the ordinary operand encoding checks.  The number of operands
     and related syntax issues have already been checked.  */
  if (orig_insn->opcode == xtensa_extui_opcode)
    {
      int shiftimm = orig_insn->tok[2].X_add_number;
      int maskimm = orig_insn->tok[3].X_add_number;
      if (shiftimm + maskimm > 32)
	{
	  as_bad (_("immediate operands sum to greater than 32"));
	  return TRUE;
	}
    }

  /* If the instruction will definitely need to be relaxed, it is better
     to expand it now for better scheduling.  Decide whether to expand
     now....  */
  do_expand = (!orig_insn->is_specific_opcode && use_transform ());

  /* Calls should be expanded to longcalls only in the backend relaxation
     so that the assembly scheduler will keep the L32R/CALLX instructions
     adjacent.  */
  if (is_direct_call_opcode (orig_insn->opcode))
    do_expand = FALSE;

  if (tinsn_has_symbolic_operands (orig_insn))
    {
      /* The values of symbolic operands are not known yet, so only expand
	 now if an operand is "complex" (e.g., difference of symbols) and
	 will have to be stored as a literal regardless of the value.  */
      if (!tinsn_has_complex_operands (orig_insn))
	do_expand = FALSE;
    }
  else if (xg_immeds_fit (orig_insn))
    do_expand = FALSE;

  if (do_expand)
    xg_assembly_relax (istack, orig_insn, 0, 0, 0, 0, 0);
  else
    istack_push (istack, orig_insn);

  return FALSE;
}


/* Return TRUE if the section flags are marked linkonce
   or the name is .gnu.linkonce.*.  */

static int linkonce_len = sizeof (".gnu.linkonce.") - 1;

static bfd_boolean
get_is_linkonce_section (bfd *abfd ATTRIBUTE_UNUSED, segT sec)
{
  flagword flags, link_once_flags;

  flags = bfd_get_section_flags (abfd, sec);
  link_once_flags = (flags & SEC_LINK_ONCE);

  /* Flags might not be set yet.  */
  if (!link_once_flags
      && strncmp (segment_name (sec), ".gnu.linkonce.", linkonce_len) == 0)
    link_once_flags = SEC_LINK_ONCE;

  return (link_once_flags != 0);
}


static void
xtensa_add_literal_sym (symbolS *sym)
{
  sym_list *l;

  l = XNEW (sym_list);
  l->sym = sym;
  l->next = literal_syms;
  literal_syms = l;
}


static symbolS *
xtensa_create_literal_symbol (segT sec, fragS *frag)
{
  static int lit_num = 0;
  static char name[256];
  symbolS *symbolP;

  sprintf (name, ".L_lit_sym%d", lit_num);

  /* Create a local symbol.  If it is in a linkonce section, we have to
     be careful to make sure that if it is used in a relocation that the
     symbol will be in the output file.  */
  if (get_is_linkonce_section (stdoutput, sec))
    {
      symbolP = symbol_new (name, sec, 0, frag);
      S_CLEAR_EXTERNAL (symbolP);
      /* symbolP->local = 1; */
    }
  else
    symbolP = symbol_new (name, sec, 0, frag);

  xtensa_add_literal_sym (symbolP);

  lit_num++;
  return symbolP;
}


/* Currently all literals that are generated here are 32-bit L32R targets.  */

static symbolS *
xg_assemble_literal (/* const */ TInsn *insn)
{
  emit_state state;
  symbolS *lit_sym = NULL;
  bfd_reloc_code_real_type reloc;
  bfd_boolean pcrel = FALSE;
  char *p;

  /* size = 4 for L32R.  It could easily be larger when we move to
     larger constants.  Add a parameter later.  */
  offsetT litsize = 4;
  offsetT litalign = 2;		/* 2^2 = 4 */
  expressionS saved_loc;
  expressionS * emit_val;

  set_expr_symbol_offset (&saved_loc, frag_now->fr_symbol, frag_now_fix ());

  gas_assert (insn->insn_type == ITYPE_LITERAL);
  gas_assert (insn->ntok == 1);	/* must be only one token here */

  xtensa_switch_to_literal_fragment (&state);

  emit_val = &insn->tok[0];
  if (emit_val->X_op == O_big)
    {
      int size = emit_val->X_add_number * CHARS_PER_LITTLENUM;
      if (size > litsize)
	{
	  /* This happens when someone writes a "movi a2, big_number".  */
	  as_bad_where (frag_now->fr_file, frag_now->fr_line,
			_("invalid immediate"));
	  xtensa_restore_emit_state (&state);
	  return NULL;
	}
    }

  /* Force a 4-byte align here.  Note that this opens a new frag, so all
     literals done with this function have a frag to themselves.  That's
     important for the way text section literals work.  */
  frag_align (litalign, 0, 0);
  record_alignment (now_seg, litalign);

  switch (emit_val->X_op)
    {
    case O_pcrel:
      pcrel = TRUE;
      /* fall through */
    case O_pltrel:
    case O_tlsfunc:
    case O_tlsarg:
    case O_tpoff:
    case O_dtpoff:
      p = frag_more (litsize);
      xtensa_set_frag_assembly_state (frag_now);
      reloc = map_operator_to_reloc (emit_val->X_op, TRUE);
      if (emit_val->X_add_symbol)
	emit_val->X_op = O_symbol;
      else
	emit_val->X_op = O_constant;
      fix_new_exp (frag_now, p - frag_now->fr_literal,
		   litsize, emit_val, pcrel, reloc);
      break;

    default:
      emit_expr (emit_val, litsize);
      break;
    }

  gas_assert (frag_now->tc_frag_data.literal_frag == NULL);
  frag_now->tc_frag_data.literal_frag = get_literal_pool_location (now_seg);
  frag_now->fr_symbol = xtensa_create_literal_symbol (now_seg, frag_now);
  lit_sym = frag_now->fr_symbol;

  /* Go back.  */
  xtensa_restore_emit_state (&state);
  return lit_sym;
}


static void
xg_assemble_literal_space (/* const */ int size, int slot)
{
  emit_state state;
  /* We might have to do something about this alignment.  It only
     takes effect if something is placed here.  */
  offsetT litalign = 2;		/* 2^2 = 4 */
  fragS *lit_saved_frag;

  gas_assert (size % 4 == 0);

  xtensa_switch_to_literal_fragment (&state);

  /* Force a 4-byte align here.  */
  frag_align (litalign, 0, 0);
  record_alignment (now_seg, litalign);

  frag_grow (size);

  lit_saved_frag = frag_now;
  frag_now->tc_frag_data.literal_frag = get_literal_pool_location (now_seg);
  frag_now->fr_symbol = xtensa_create_literal_symbol (now_seg, frag_now);
  xg_finish_frag (0, RELAX_LITERAL, 0, size, FALSE);

  /* Go back.  */
  xtensa_restore_emit_state (&state);
  frag_now->tc_frag_data.literal_frags[slot] = lit_saved_frag;
}


/* Put in a fixup record based on the opcode.
   Return TRUE on success.  */

static bfd_boolean
xg_add_opcode_fix (TInsn *tinsn,
		   int opnum,
		   xtensa_format fmt,
		   int slot,
		   expressionS *exp,
		   fragS *fragP,
		   offsetT offset)
{
  xtensa_opcode opcode = tinsn->opcode;
  bfd_reloc_code_real_type reloc;
  reloc_howto_type *howto;
  int fmt_length;
  fixS *the_fix;

  reloc = BFD_RELOC_NONE;

  /* First try the special cases for "alternate" relocs.  */
  if (opcode == xtensa_l32r_opcode)
    {
      if (fragP->tc_frag_data.use_absolute_literals)
	reloc = encode_alt_reloc (slot);
    }
  else if (opcode == xtensa_const16_opcode)
    {
      if (exp->X_op == O_lo16)
	{
	  reloc = encode_reloc (slot);
	  exp->X_op = O_symbol;
	}
      else if (exp->X_op == O_hi16)
	{
	  reloc = encode_alt_reloc (slot);
	  exp->X_op = O_symbol;
	}
    }

  if (opnum != get_relaxable_immed (opcode))
    {
      as_bad (_("invalid relocation for operand %i of '%s'"),
	      opnum + 1, xtensa_opcode_name (xtensa_default_isa, opcode));
      return FALSE;
    }

  /* Handle erroneous "@h" and "@l" expressions here before they propagate
     into the symbol table where the generic portions of the assembler
     won't know what to do with them.  */
  if (exp->X_op == O_lo16 || exp->X_op == O_hi16)
    {
      as_bad (_("invalid expression for operand %i of '%s'"),
	      opnum + 1, xtensa_opcode_name (xtensa_default_isa, opcode));
      return FALSE;
    }

  /* Next try the generic relocs.  */
  if (reloc == BFD_RELOC_NONE)
    reloc = encode_reloc (slot);
  if (reloc == BFD_RELOC_NONE)
    {
      as_bad (_("invalid relocation in instruction slot %i"), slot);
      return FALSE;
    }

  howto = bfd_reloc_type_lookup (stdoutput, reloc);
  if (!howto)
    {
      as_bad (_("undefined symbol for opcode \"%s\""),
	      xtensa_opcode_name (xtensa_default_isa, opcode));
      return FALSE;
    }

  fmt_length = xtensa_format_length (xtensa_default_isa, fmt);
  the_fix = fix_new_exp (fragP, offset, fmt_length, exp,
			 howto->pc_relative, reloc);
  the_fix->fx_no_overflow = 1;
  the_fix->tc_fix_data.X_add_symbol = exp->X_add_symbol;
  the_fix->tc_fix_data.X_add_number = exp->X_add_number;
  the_fix->tc_fix_data.slot = slot;

  return TRUE;
}


static bfd_boolean
xg_emit_insn_to_buf (TInsn *tinsn,
		     char *buf,
		     fragS *fragP,
		     offsetT offset,
		     bfd_boolean build_fix)
{
  static xtensa_insnbuf insnbuf = NULL;
  bfd_boolean has_symbolic_immed = FALSE;
  bfd_boolean ok = TRUE;

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (xtensa_default_isa);

  has_symbolic_immed = tinsn_to_insnbuf (tinsn, insnbuf);
  if (has_symbolic_immed && build_fix)
    {
      /* Add a fixup.  */
      xtensa_format fmt = xg_get_single_format (tinsn->opcode);
      int slot = xg_get_single_slot (tinsn->opcode);
      int opnum = get_relaxable_immed (tinsn->opcode);
      expressionS *exp = &tinsn->tok[opnum];

      if (!xg_add_opcode_fix (tinsn, opnum, fmt, slot, exp, fragP, offset))
	ok = FALSE;
    }
  fragP->tc_frag_data.is_insn = TRUE;
  xtensa_insnbuf_to_chars (xtensa_default_isa, insnbuf,
			   (unsigned char *) buf, 0);
  return ok;
}


static void
xg_resolve_literals (TInsn *insn, symbolS *lit_sym)
{
  symbolS *sym = get_special_literal_symbol ();
  int i;
  if (lit_sym == 0)
    return;
  gas_assert (insn->insn_type == ITYPE_INSN);
  for (i = 0; i < insn->ntok; i++)
    if (insn->tok[i].X_add_symbol == sym)
      insn->tok[i].X_add_symbol = lit_sym;

}


static void
xg_resolve_labels (TInsn *insn, symbolS *label_sym)
{
  symbolS *sym = get_special_label_symbol ();
  int i;
  for (i = 0; i < insn->ntok; i++)
    if (insn->tok[i].X_add_symbol == sym)
      insn->tok[i].X_add_symbol = label_sym;

}


/* Return TRUE if the instruction can write to the specified
   integer register.  */

static bfd_boolean
is_register_writer (const TInsn *insn, const char *regset, int regnum)
{
  int i;
  int num_ops;
  xtensa_isa isa = xtensa_default_isa;

  num_ops = xtensa_opcode_num_operands (isa, insn->opcode);

  for (i = 0; i < num_ops; i++)
    {
      char inout;
      inout = xtensa_operand_inout (isa, insn->opcode, i);
      if ((inout == 'o' || inout == 'm')
	  && xtensa_operand_is_register (isa, insn->opcode, i) == 1)
	{
	  xtensa_regfile opnd_rf =
	    xtensa_operand_regfile (isa, insn->opcode, i);
	  if (!strcmp (xtensa_regfile_shortname (isa, opnd_rf), regset))
	    {
	      if ((insn->tok[i].X_op == O_register)
		  && (insn->tok[i].X_add_number == regnum))
		return TRUE;
	    }
	}
    }
  return FALSE;
}


static bfd_boolean
is_bad_loopend_opcode (const TInsn *tinsn)
{
  xtensa_opcode opcode = tinsn->opcode;

  if (opcode == XTENSA_UNDEFINED)
    return FALSE;

  if (opcode == xtensa_call0_opcode
      || opcode == xtensa_callx0_opcode
      || opcode == xtensa_call4_opcode
      || opcode == xtensa_callx4_opcode
      || opcode == xtensa_call8_opcode
      || opcode == xtensa_callx8_opcode
      || opcode == xtensa_call12_opcode
      || opcode == xtensa_callx12_opcode
      || opcode == xtensa_isync_opcode
      || opcode == xtensa_ret_opcode
      || opcode == xtensa_ret_n_opcode
      || opcode == xtensa_retw_opcode
      || opcode == xtensa_retw_n_opcode
      || opcode == xtensa_waiti_opcode
      || opcode == xtensa_rsr_lcount_opcode)
    return TRUE;

  return FALSE;
}


/* Labels that begin with ".Ln" or ".LM"  are unaligned.
   This allows the debugger to add unaligned labels.
   Also, the assembler generates stabs labels that need
   not be aligned:  FAKE_LABEL_NAME . {"F", "L", "endfunc"}.  */

static bfd_boolean
is_unaligned_label (symbolS *sym)
{
  const char *name = S_GET_NAME (sym);
  static size_t fake_size = 0;

  if (name
      && name[0] == '.'
      && name[1] == 'L' && (name[2] == 'n' || name[2] == 'M'))
    return TRUE;

  /* FAKE_LABEL_NAME followed by "F", "L" or "endfunc" */
  if (fake_size == 0)
    fake_size = strlen (FAKE_LABEL_NAME);

  if (name
      && strncmp (FAKE_LABEL_NAME, name, fake_size) == 0
      && (name[fake_size] == 'F'
	  || name[fake_size] == 'L'
	  || (name[fake_size] == 'e'
	      && strncmp ("endfunc", name+fake_size, 7) == 0)))
    return TRUE;

  return FALSE;
}


static fragS *
next_non_empty_frag (const fragS *fragP)
{
  fragS *next_fragP = fragP->fr_next;

  /* Sometimes an empty will end up here due storage allocation issues.
     So we have to skip until we find something legit.  */
  while (next_fragP && next_fragP->fr_fix == 0)
    next_fragP = next_fragP->fr_next;

  if (next_fragP == NULL || next_fragP->fr_fix == 0)
    return NULL;

  return next_fragP;
}


static bfd_boolean
next_frag_opcode_is_loop (const fragS *fragP, xtensa_opcode *opcode)
{
  xtensa_opcode out_opcode;
  const fragS *next_fragP = next_non_empty_frag (fragP);

  if (next_fragP == NULL)
    return FALSE;

  out_opcode = get_opcode_from_buf (next_fragP->fr_literal, 0);
  if (xtensa_opcode_is_loop (xtensa_default_isa, out_opcode) == 1)
    {
      *opcode = out_opcode;
      return TRUE;
    }
  return FALSE;
}


static int
frag_format_size (const fragS *fragP)
{
  static xtensa_insnbuf insnbuf = NULL;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt;
  int fmt_size;

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (isa);

  if (fragP == NULL)
    return XTENSA_UNDEFINED;

  xtensa_insnbuf_from_chars (isa, insnbuf,
			     (unsigned char *) fragP->fr_literal, 0);

  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;
  fmt_size = xtensa_format_length (isa, fmt);

  /* If the next format won't be changing due to relaxation, just
     return the length of the first format.  */
  if (fragP->fr_opcode != fragP->fr_literal)
    return fmt_size;

  /* If during relaxation we have to pull an instruction out of a
     multi-slot instruction, we will return the more conservative
     number.  This works because alignment on bigger instructions
     is more restrictive than alignment on smaller instructions.
     This is more conservative than we would like, but it happens
     infrequently.  */

  if (xtensa_format_num_slots (xtensa_default_isa, fmt) > 1)
    return fmt_size;

  /* If we aren't doing one of our own relaxations or it isn't
     slot-based, then the insn size won't change.  */
  if (fragP->fr_type != rs_machine_dependent)
    return fmt_size;
  if (fragP->fr_subtype != RELAX_SLOTS)
    return fmt_size;

  /* If an instruction is about to grow, return the longer size.  */
  if (fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED_STEP1
      || fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED_STEP2
      || fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED_STEP3)
    {
      /* For most frags at RELAX_IMMED_STEPX, with X > 0, the first
	 instruction in the relaxed version is of length 3.  (The case
	 where we have to pull the instruction out of a FLIX bundle
	 is handled conservatively above.)  However, frags with opcodes
	 that are expanding to wide branches end up having formats that
	 are not determinable by the RELAX_IMMED_STEPX enumeration, and
	 we can't tell directly what format the relaxer picked.  This
	 is a wart in the design of the relaxer that should someday be
	 fixed, but would require major changes, or at least should
	 be accompanied by major changes to make use of that data.

	 In any event, we can tell that we are expanding from a single-slot
	 format to a wider one with the logic below.  */

      int i;
      int relaxed_size = fmt_size + fragP->tc_frag_data.text_expansion[0];

      for (i = 0; i < xtensa_isa_num_formats (isa); i++)
	{
	  if (relaxed_size == xtensa_format_length (isa, i))
	    return relaxed_size;
	}

      return 3;
    }

  if (fragP->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
    return 2 + fragP->tc_frag_data.text_expansion[0];

  return fmt_size;
}


static int
next_frag_format_size (const fragS *fragP)
{
  const fragS *next_fragP = next_non_empty_frag (fragP);
  return frag_format_size (next_fragP);
}


/* In early Xtensa Processors, for reasons that are unclear, the ISA
   required two-byte instructions to be treated as three-byte instructions
   for loop instruction alignment.  This restriction was removed beginning
   with Xtensa LX.  Now the only requirement on loop instruction alignment
   is that the first instruction of the loop must appear at an address that
   does not cross a fetch boundary.  */

static int
get_loop_align_size (int insn_size)
{
  if (insn_size == XTENSA_UNDEFINED)
    return xtensa_fetch_width;

  if (enforce_three_byte_loop_align && insn_size == 2)
    return 3;

  return insn_size;
}


/* If the next legit fragment is an end-of-loop marker,
   switch its state so it will instantiate a NOP.  */

static void
update_next_frag_state (fragS *fragP)
{
  fragS *next_fragP = fragP->fr_next;
  fragS *new_target = NULL;

  if (align_targets)
    {
      /* We are guaranteed there will be one of these...   */
      while (!(next_fragP->fr_type == rs_machine_dependent
	       && (next_fragP->fr_subtype == RELAX_MAYBE_UNREACHABLE
		   || next_fragP->fr_subtype == RELAX_UNREACHABLE)))
	next_fragP = next_fragP->fr_next;

      gas_assert (next_fragP->fr_type == rs_machine_dependent
	      && (next_fragP->fr_subtype == RELAX_MAYBE_UNREACHABLE
		  || next_fragP->fr_subtype == RELAX_UNREACHABLE));

      /* ...and one of these.  */
      new_target = next_fragP->fr_next;
      while (!(new_target->fr_type == rs_machine_dependent
	       && (new_target->fr_subtype == RELAX_MAYBE_DESIRE_ALIGN
		   || new_target->fr_subtype == RELAX_DESIRE_ALIGN)))
	new_target = new_target->fr_next;

      gas_assert (new_target->fr_type == rs_machine_dependent
	      && (new_target->fr_subtype == RELAX_MAYBE_DESIRE_ALIGN
		  || new_target->fr_subtype == RELAX_DESIRE_ALIGN));
    }

  while (next_fragP && next_fragP->fr_fix == 0)
    {
      if (next_fragP->fr_type == rs_machine_dependent
	  && next_fragP->fr_subtype == RELAX_LOOP_END)
	{
	  next_fragP->fr_subtype = RELAX_LOOP_END_ADD_NOP;
	  return;
	}

      next_fragP = next_fragP->fr_next;
    }
}


static bfd_boolean
next_frag_is_branch_target (const fragS *fragP)
{
  /* Sometimes an empty will end up here due to storage allocation issues,
     so we have to skip until we find something legit.  */
  for (fragP = fragP->fr_next; fragP; fragP = fragP->fr_next)
    {
      if (fragP->tc_frag_data.is_branch_target)
	return TRUE;
      if (fragP->fr_fix != 0)
	break;
    }
  return FALSE;
}


static bfd_boolean
next_frag_is_loop_target (const fragS *fragP)
{
  /* Sometimes an empty will end up here due storage allocation issues.
     So we have to skip until we find something legit. */
  for (fragP = fragP->fr_next; fragP; fragP = fragP->fr_next)
    {
      if (fragP->tc_frag_data.is_loop_target)
	return TRUE;
      if (fragP->fr_fix != 0)
	break;
    }
  return FALSE;
}


/* As specified in the relaxation table, when a loop instruction is
   relaxed, there are 24 bytes between the loop instruction itself and
   the first instruction in the loop.  */

#define RELAXED_LOOP_INSN_BYTES 24

static addressT
next_frag_pre_opcode_bytes (const fragS *fragp)
{
  const fragS *next_fragp = fragp->fr_next;
  xtensa_opcode next_opcode;

  if (!next_frag_opcode_is_loop (fragp, &next_opcode))
    return 0;

  /* Sometimes an empty will end up here due to storage allocation issues,
     so we have to skip until we find something legit.  */
  while (next_fragp->fr_fix == 0)
    next_fragp = next_fragp->fr_next;

  if (next_fragp->fr_type != rs_machine_dependent)
    return 0;

  /* There is some implicit knowledge encoded in here.
     The LOOP instructions that are NOT RELAX_IMMED have
     been relaxed.  Note that we can assume that the LOOP
     instruction is in slot 0 because loops aren't bundleable.  */
  if (next_fragp->tc_frag_data.slot_subtypes[0] > RELAX_IMMED)
      return get_expanded_loop_offset (next_opcode) + RELAXED_LOOP_INSN_BYTES;

  return 0;
}


/* Mark a location where we can later insert literal frags.  Update
   the section's literal_pool_loc, so subsequent literals can be
   placed nearest to their use.  */

static void
xtensa_mark_literal_pool_location (void)
{
  /* Any labels pointing to the current location need
     to be adjusted to after the literal pool.  */
  emit_state s;
  fragS *pool_location;

  if (use_literal_section)
    return;

  /* We stash info in these frags so we can later move the literal's
     fixes into this frchain's fix list.  */
  pool_location = frag_now;
  frag_now->tc_frag_data.lit_frchain = frchain_now;
  frag_now->tc_frag_data.literal_frag = frag_now;
  /* Just record this frag.  */
  xtensa_maybe_create_literal_pool_frag (FALSE, FALSE);
  frag_variant (rs_machine_dependent, 0, 0,
		RELAX_LITERAL_POOL_BEGIN, NULL, 0, NULL);
  xtensa_set_frag_assembly_state (frag_now);
  frag_now->tc_frag_data.lit_seg = now_seg;
  frag_variant (rs_machine_dependent, 0, 0,
		RELAX_LITERAL_POOL_END, NULL, 0, NULL);
  xtensa_set_frag_assembly_state (frag_now);

  /* Now put a frag into the literal pool that points to this location.  */
  set_literal_pool_location (now_seg, pool_location);
  xtensa_switch_to_non_abs_literal_fragment (&s);
  frag_align (2, 0, 0);
  record_alignment (now_seg, 2);

  /* Close whatever frag is there.  */
  frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
  xtensa_set_frag_assembly_state (frag_now);
  frag_now->tc_frag_data.literal_frag = pool_location;
  frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
  xtensa_restore_emit_state (&s);
  xtensa_set_frag_assembly_state (frag_now);
}


/* Build a nop of the correct size into tinsn.  */

static void
build_nop (TInsn *tinsn, int size)
{
  tinsn_init (tinsn);
  switch (size)
    {
    case 2:
      tinsn->opcode = xtensa_nop_n_opcode;
      tinsn->ntok = 0;
      if (tinsn->opcode == XTENSA_UNDEFINED)
	as_fatal (_("opcode 'NOP.N' unavailable in this configuration"));
      break;

    case 3:
      if (xtensa_nop_opcode == XTENSA_UNDEFINED)
	{
	  tinsn->opcode = xtensa_or_opcode;
	  set_expr_const (&tinsn->tok[0], 1);
	  set_expr_const (&tinsn->tok[1], 1);
	  set_expr_const (&tinsn->tok[2], 1);
	  tinsn->ntok = 3;
	}
      else
	tinsn->opcode = xtensa_nop_opcode;

      gas_assert (tinsn->opcode != XTENSA_UNDEFINED);
    }
}


/* Assemble a NOP of the requested size in the buffer.  User must have
   allocated "buf" with at least "size" bytes.  */

static void
assemble_nop (int size, char *buf)
{
  static xtensa_insnbuf insnbuf = NULL;
  TInsn tinsn;

  build_nop (&tinsn, size);

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (xtensa_default_isa);

  tinsn_to_insnbuf (&tinsn, insnbuf);
  xtensa_insnbuf_to_chars (xtensa_default_isa, insnbuf,
			   (unsigned char *) buf, 0);
}


/* Return the number of bytes for the offset of the expanded loop
   instruction.  This should be incorporated into the relaxation
   specification but is hard-coded here.  This is used to auto-align
   the loop instruction.  It is invalid to call this function if the
   configuration does not have loops or if the opcode is not a loop
   opcode.  */

static addressT
get_expanded_loop_offset (xtensa_opcode opcode)
{
  /* This is the OFFSET of the loop instruction in the expanded loop.
     This MUST correspond directly to the specification of the loop
     expansion.  It will be validated on fragment conversion.  */
  gas_assert (opcode != XTENSA_UNDEFINED);
  if (opcode == xtensa_loop_opcode)
    return 0;
  if (opcode == xtensa_loopnez_opcode)
    return 3;
  if (opcode == xtensa_loopgtz_opcode)
    return 6;
  as_fatal (_("get_expanded_loop_offset: invalid opcode"));
  return 0;
}


static fragS *
get_literal_pool_location (segT seg)
{
  struct litpool_seg *lps = litpool_seg_list.next;
  struct litpool_frag *lpf;
  for ( ; lps && lps->seg->id != seg->id; lps = lps->next)
    ;
  if (lps)
    {
      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
	{ /* Skip "candidates" for now.  */
	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN &&
	      lpf->priority == 1)
	    return lpf->fragP;
	}
      /* Must convert a lower-priority pool.  */
      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
	{
	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
	    return lpf->fragP;
	}
      /* Still no match -- try for a low priority pool.  */
      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
	{
	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
	    return lpf->fragP;
	}
    }
  return seg_info (seg)->tc_segment_info_data.literal_pool_loc;
}


static void
set_literal_pool_location (segT seg, fragS *literal_pool_loc)
{
  seg_info (seg)->tc_segment_info_data.literal_pool_loc = literal_pool_loc;
}


/* Set frag assembly state should be called when a new frag is
   opened and after a frag has been closed.  */

static void
xtensa_set_frag_assembly_state (fragS *fragP)
{
  if (!density_supported)
    fragP->tc_frag_data.is_no_density = TRUE;

  /* This function is called from subsegs_finish, which is called
     after xtensa_end, so we can't use "use_transform" or
     "use_schedule" here.  */
  if (!directive_state[directive_transform])
    fragP->tc_frag_data.is_no_transform = TRUE;
  if (directive_state[directive_longcalls])
    fragP->tc_frag_data.use_longcalls = TRUE;
  fragP->tc_frag_data.use_absolute_literals =
    directive_state[directive_absolute_literals];
  fragP->tc_frag_data.is_assembly_state_set = TRUE;
}


static bfd_boolean
relaxable_section (asection *sec)
{
  return ((sec->flags & SEC_DEBUGGING) == 0
	  && strcmp (sec->name, ".eh_frame") != 0);
}


static void
xtensa_mark_frags_for_org (void)
{
  segT *seclist;

  /* Walk over each fragment of all of the current segments.  If we find
     a .org frag in any of the segments, mark all frags prior to it as
     "no transform", which will prevent linker optimizations from messing
     up the .org distance.  This should be done after
     xtensa_find_unmarked_state_frags, because we don't want to worry here
     about that function trashing the data we save here.  */

  for (seclist = &stdoutput->sections;
       seclist && *seclist;
       seclist = &(*seclist)->next)
    {
      segT sec = *seclist;
      segment_info_type *seginfo;
      fragS *fragP;
      flagword flags;
      flags = bfd_get_section_flags (stdoutput, sec);
      if (flags & SEC_DEBUGGING)
	continue;
      if (!(flags & SEC_ALLOC))
	continue;

      seginfo = seg_info (sec);
      if (seginfo && seginfo->frchainP)
	{
	  fragS *last_fragP = seginfo->frchainP->frch_root;
	  for (fragP = seginfo->frchainP->frch_root; fragP;
	       fragP = fragP->fr_next)
	    {
	      /* cvt_frag_to_fill has changed the fr_type of org frags to
		 rs_fill, so use the value as cached in rs_subtype here.  */
	      if (fragP->fr_subtype == RELAX_ORG)
		{
		  while (last_fragP != fragP->fr_next)
		    {
		      last_fragP->tc_frag_data.is_no_transform = TRUE;
		      last_fragP = last_fragP->fr_next;
		    }
		}
	    }
	}
    }
}


static void
xtensa_find_unmarked_state_frags (void)
{
  segT *seclist;

  /* Walk over each fragment of all of the current segments.  For each
     unmarked fragment, mark it with the same info as the previous
     fragment.  */
  for (seclist = &stdoutput->sections;
       seclist && *seclist;
       seclist = &(*seclist)->next)
    {
      segT sec = *seclist;
      segment_info_type *seginfo;
      fragS *fragP;
      flagword flags;
      flags = bfd_get_section_flags (stdoutput, sec);
      if (flags & SEC_DEBUGGING)
	continue;
      if (!(flags & SEC_ALLOC))
	continue;

      seginfo = seg_info (sec);
      if (seginfo && seginfo->frchainP)
	{
	  fragS *last_fragP = 0;
	  for (fragP = seginfo->frchainP->frch_root; fragP;
	       fragP = fragP->fr_next)
	    {
	      if (fragP->fr_fix != 0
		  && !fragP->tc_frag_data.is_assembly_state_set)
		{
		  if (last_fragP == 0)
		    {
		      as_warn_where (fragP->fr_file, fragP->fr_line,
				     _("assembly state not set for first frag in section %s"),
				     sec->name);
		    }
		  else
		    {
		      fragP->tc_frag_data.is_assembly_state_set = TRUE;
		      fragP->tc_frag_data.is_no_density =
			last_fragP->tc_frag_data.is_no_density;
		      fragP->tc_frag_data.is_no_transform =
			last_fragP->tc_frag_data.is_no_transform;
		      fragP->tc_frag_data.use_longcalls =
			last_fragP->tc_frag_data.use_longcalls;
		      fragP->tc_frag_data.use_absolute_literals =
			last_fragP->tc_frag_data.use_absolute_literals;
		    }
		}
	      if (fragP->tc_frag_data.is_assembly_state_set)
		last_fragP = fragP;
	    }
	}
    }
}


static void
xtensa_find_unaligned_branch_targets (bfd *abfd ATTRIBUTE_UNUSED,
				      asection *sec,
				      void *unused ATTRIBUTE_UNUSED)
{
  flagword flags = bfd_get_section_flags (abfd, sec);
  segment_info_type *seginfo = seg_info (sec);
  fragS *frag = seginfo->frchainP->frch_root;

  if (flags & SEC_CODE)
    {
      xtensa_isa isa = xtensa_default_isa;
      xtensa_insnbuf insnbuf = xtensa_insnbuf_alloc (isa);
      while (frag != NULL)
	{
	  if (frag->tc_frag_data.is_branch_target)
	    {
	      int op_size;
	      addressT branch_align, frag_addr;
	      xtensa_format fmt;

	      xtensa_insnbuf_from_chars
		(isa, insnbuf, (unsigned char *) frag->fr_literal, 0);
	      fmt = xtensa_format_decode (isa, insnbuf);
	      op_size = xtensa_format_length (isa, fmt);
	      branch_align = 1 << branch_align_power (sec);
	      frag_addr = frag->fr_address % branch_align;
	      if (frag_addr + op_size > branch_align)
		as_warn_where (frag->fr_file, frag->fr_line,
			       _("unaligned branch target: %d bytes at 0x%lx"),
			       op_size, (long) frag->fr_address);
	    }
	  frag = frag->fr_next;
	}
      xtensa_insnbuf_free (isa, insnbuf);
    }
}


static void
xtensa_find_unaligned_loops (bfd *abfd ATTRIBUTE_UNUSED,
			     asection *sec,
			     void *unused ATTRIBUTE_UNUSED)
{
  flagword flags = bfd_get_section_flags (abfd, sec);
  segment_info_type *seginfo = seg_info (sec);
  fragS *frag = seginfo->frchainP->frch_root;
  xtensa_isa isa = xtensa_default_isa;

  if (flags & SEC_CODE)
    {
      xtensa_insnbuf insnbuf = xtensa_insnbuf_alloc (isa);
      while (frag != NULL)
	{
	  if (frag->tc_frag_data.is_first_loop_insn)
	    {
	      int op_size;
	      addressT frag_addr;
	      xtensa_format fmt;

	      if (frag->fr_fix == 0)
		frag = next_non_empty_frag (frag);

	      if (frag)
		{
		  xtensa_insnbuf_from_chars
		    (isa, insnbuf, (unsigned char *) frag->fr_literal, 0);
		  fmt = xtensa_format_decode (isa, insnbuf);
		  op_size = xtensa_format_length (isa, fmt);
		  frag_addr = frag->fr_address % xtensa_fetch_width;

		  if (frag_addr + op_size > xtensa_fetch_width)
		    as_warn_where (frag->fr_file, frag->fr_line,
				   _("unaligned loop: %d bytes at 0x%lx"),
				   op_size, (long) frag->fr_address);
		}
	    }
	  frag = frag->fr_next;
	}
      xtensa_insnbuf_free (isa, insnbuf);
    }
}


static int
xg_apply_fix_value (fixS *fixP, valueT val)
{
  xtensa_isa isa = xtensa_default_isa;
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  xtensa_format fmt;
  int slot;
  bfd_boolean alt_reloc;
  xtensa_opcode opcode;
  char *const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;

  if (decode_reloc (fixP->fx_r_type, &slot, &alt_reloc)
      || alt_reloc)
    as_fatal (_("unexpected fix"));

  if (!insnbuf)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  xtensa_insnbuf_from_chars (isa, insnbuf, (unsigned char *) fixpos, 0);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED)
    as_fatal (_("undecodable fix"));
  xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
  opcode = xtensa_opcode_decode (isa, fmt, slot, slotbuf);
  if (opcode == XTENSA_UNDEFINED)
    as_fatal (_("undecodable fix"));

  /* CONST16 immediates are not PC-relative, despite the fact that we
     reuse the normal PC-relative operand relocations for the low part
     of a CONST16 operand.  */
  if (opcode == xtensa_const16_opcode)
    return 0;

  xtensa_insnbuf_set_operand (slotbuf, fmt, slot, opcode,
			      get_relaxable_immed (opcode), val,
			      fixP->fx_file, fixP->fx_line);

  xtensa_format_set_slot (isa, fmt, slot, insnbuf, slotbuf);
  xtensa_insnbuf_to_chars (isa, insnbuf, (unsigned char *) fixpos, 0);

  return 1;
}


/* External Functions and Other GAS Hooks.  */

const char *
xtensa_target_format (void)
{
  return (target_big_endian ? "elf32-xtensa-be" : "elf32-xtensa-le");
}


void
xtensa_file_arch_init (bfd *abfd)
{
  bfd_set_private_flags (abfd, 0x100 | 0x200);
}


void
md_number_to_chars (char *buf, valueT val, int n)
{
  if (target_big_endian)
    number_to_chars_bigendian (buf, val, n);
  else
    number_to_chars_littleendian (buf, val, n);
}


/* This function is called once, at assembler startup time.  It should
   set up all the tables, etc. that the MD part of the assembler will
   need.  */

void
md_begin (void)
{
  segT current_section = now_seg;
  int current_subsec = now_subseg;
  xtensa_isa isa;
  int i;

  xtensa_default_isa = xtensa_isa_init (0, 0);
  isa = xtensa_default_isa;

  linkrelax = 1;

  /* Set up the literal sections.  */
  memset (&default_lit_sections, 0, sizeof (default_lit_sections));

  subseg_set (current_section, current_subsec);

  xtensa_addi_opcode = xtensa_opcode_lookup (isa, "addi");
  xtensa_addmi_opcode = xtensa_opcode_lookup (isa, "addmi");
  xtensa_call0_opcode = xtensa_opcode_lookup (isa, "call0");
  xtensa_call4_opcode = xtensa_opcode_lookup (isa, "call4");
  xtensa_call8_opcode = xtensa_opcode_lookup (isa, "call8");
  xtensa_call12_opcode = xtensa_opcode_lookup (isa, "call12");
  xtensa_callx0_opcode = xtensa_opcode_lookup (isa, "callx0");
  xtensa_callx4_opcode = xtensa_opcode_lookup (isa, "callx4");
  xtensa_callx8_opcode = xtensa_opcode_lookup (isa, "callx8");
  xtensa_callx12_opcode = xtensa_opcode_lookup (isa, "callx12");
  xtensa_const16_opcode = xtensa_opcode_lookup (isa, "const16");
  xtensa_entry_opcode = xtensa_opcode_lookup (isa, "entry");
  xtensa_extui_opcode = xtensa_opcode_lookup (isa, "extui");
  xtensa_movi_opcode = xtensa_opcode_lookup (isa, "movi");
  xtensa_movi_n_opcode = xtensa_opcode_lookup (isa, "movi.n");
  xtensa_isync_opcode = xtensa_opcode_lookup (isa, "isync");
  xtensa_j_opcode = xtensa_opcode_lookup (isa, "j");
  xtensa_jx_opcode = xtensa_opcode_lookup (isa, "jx");
  xtensa_l32r_opcode = xtensa_opcode_lookup (isa, "l32r");
  xtensa_loop_opcode = xtensa_opcode_lookup (isa, "loop");
  xtensa_loopnez_opcode = xtensa_opcode_lookup (isa, "loopnez");
  xtensa_loopgtz_opcode = xtensa_opcode_lookup (isa, "loopgtz");
  xtensa_nop_opcode = xtensa_opcode_lookup (isa, "nop");
  xtensa_nop_n_opcode = xtensa_opcode_lookup (isa, "nop.n");
  xtensa_or_opcode = xtensa_opcode_lookup (isa, "or");
  xtensa_ret_opcode = xtensa_opcode_lookup (isa, "ret");
  xtensa_ret_n_opcode = xtensa_opcode_lookup (isa, "ret.n");
  xtensa_retw_opcode = xtensa_opcode_lookup (isa, "retw");
  xtensa_retw_n_opcode = xtensa_opcode_lookup (isa, "retw.n");
  xtensa_rsr_lcount_opcode = xtensa_opcode_lookup (isa, "rsr.lcount");
  xtensa_waiti_opcode = xtensa_opcode_lookup (isa, "waiti");

  for (i = 0; i < xtensa_isa_num_formats (isa); i++)
    {
      int format_slots = xtensa_format_num_slots (isa, i);
      if (format_slots > config_max_slots)
	config_max_slots = format_slots;
    }

  xg_init_vinsn (&cur_vinsn);

  xtensa_num_pipe_stages = xtensa_isa_num_pipe_stages (isa);

  init_op_placement_info_table ();

  /* Set up the assembly state.  */
  if (!frag_now->tc_frag_data.is_assembly_state_set)
    xtensa_set_frag_assembly_state (frag_now);
}


/* TC_INIT_FIX_DATA hook */

void
xtensa_init_fix_data (fixS *x)
{
  x->tc_fix_data.slot = 0;
  x->tc_fix_data.X_add_symbol = NULL;
  x->tc_fix_data.X_add_number = 0;
}


/* tc_frob_label hook */

void
xtensa_frob_label (symbolS *sym)
{
  float freq;

  if (cur_vinsn.inside_bundle)
    {
      as_bad (_("labels are not valid inside bundles"));
      return;
    }

  freq = get_subseg_target_freq (now_seg, now_subseg);

  /* Since the label was already attached to a frag associated with the
     previous basic block, it now needs to be reset to the current frag.  */
  symbol_set_frag (sym, frag_now);
  S_SET_VALUE (sym, (valueT) frag_now_fix ());

  if (generating_literals)
    xtensa_add_literal_sym (sym);
  else
    xtensa_add_insn_label (sym);

  if (symbol_get_tc (sym)->is_loop_target)
    {
      if ((get_last_insn_flags (now_seg, now_subseg)
	  & FLAG_IS_BAD_LOOPEND) != 0)
	as_bad (_("invalid last instruction for a zero-overhead loop"));

      xtensa_set_frag_assembly_state (frag_now);
      frag_var (rs_machine_dependent, 4, 4, RELAX_LOOP_END,
		frag_now->fr_symbol, frag_now->fr_offset, NULL);

      xtensa_set_frag_assembly_state (frag_now);
      xtensa_move_labels (frag_now, 0);
    }

  /* No target aligning in the absolute section.  */
  if (now_seg != absolute_section
      && !is_unaligned_label (sym)
      && !generating_literals)
    {
      xtensa_set_frag_assembly_state (frag_now);

      if (do_align_targets ())
	frag_var (rs_machine_dependent, 0, (int) freq,
		  RELAX_DESIRE_ALIGN_IF_TARGET, frag_now->fr_symbol,
		  frag_now->fr_offset, NULL);
      else
	frag_var (rs_fill, 0, 0, frag_now->fr_subtype,
		  frag_now->fr_symbol, frag_now->fr_offset, NULL);
      xtensa_set_frag_assembly_state (frag_now);
      xtensa_move_labels (frag_now, 0);
    }

  /* We need to mark the following properties even if we aren't aligning.  */

  /* If the label is already known to be a branch target, i.e., a
     forward branch, mark the frag accordingly.  Backward branches
     are handled by xg_add_branch_and_loop_targets.  */
  if (symbol_get_tc (sym)->is_branch_target)
    symbol_get_frag (sym)->tc_frag_data.is_branch_target = TRUE;

  /* Loops only go forward, so they can be identified here.  */
  if (symbol_get_tc (sym)->is_loop_target)
    symbol_get_frag (sym)->tc_frag_data.is_loop_target = TRUE;

  dwarf2_emit_label (sym);
}


/* tc_unrecognized_line hook */

int
xtensa_unrecognized_line (int ch)
{
  switch (ch)
    {
    case '{' :
      if (cur_vinsn.inside_bundle == 0)
	{
	  /* PR8110: Cannot emit line number info inside a FLIX bundle
	     when using --gstabs.  Temporarily disable debug info.  */
	  generate_lineno_debug ();
	  if (debug_type == DEBUG_STABS)
	    {
	      xt_saved_debug_type = debug_type;
	      debug_type = DEBUG_NONE;
	    }

	  cur_vinsn.inside_bundle = 1;
	}
      else
	{
	  as_bad (_("extra opening brace"));
	  return 0;
	}
      break;

    case '}' :
      if (cur_vinsn.inside_bundle)
	finish_vinsn (&cur_vinsn);
      else
	{
	  as_bad (_("extra closing brace"));
	  return 0;
	}
      break;
    default:
      as_bad (_("syntax error"));
      return 0;
    }
  return 1;
}


/* md_flush_pending_output hook */

void
xtensa_flush_pending_output (void)
{
  /* This line fixes a bug where automatically generated gstabs info
     separates a function label from its entry instruction, ending up
     with the literal position between the function label and the entry
     instruction and crashing code.  It only happens with --gstabs and
     --text-section-literals, and when several other obscure relaxation
     conditions are met.  */
  if (outputting_stabs_line_debug)
    return;

  if (cur_vinsn.inside_bundle)
    as_bad (_("missing closing brace"));

  /* If there is a non-zero instruction fragment, close it.  */
  if (frag_now_fix () != 0 && frag_now->tc_frag_data.is_insn)
    {
      frag_wane (frag_now);
      frag_new (0);
      xtensa_set_frag_assembly_state (frag_now);
    }
  frag_now->tc_frag_data.is_insn = FALSE;

  xtensa_clear_insn_labels ();
}


/* We had an error while parsing an instruction.  The string might look
   like this: "insn arg1, arg2 }".  If so, we need to see the closing
   brace and reset some fields.  Otherwise, the vinsn never gets closed
   and the num_slots field will grow past the end of the array of slots,
   and bad things happen.  */

static void
error_reset_cur_vinsn (void)
{
  if (cur_vinsn.inside_bundle)
    {
      if (*input_line_pointer == '}'
	  || *(input_line_pointer - 1) == '}'
	  || *(input_line_pointer - 2) == '}')
	xg_clear_vinsn (&cur_vinsn);
    }
}


void
md_assemble (char *str)
{
  xtensa_isa isa = xtensa_default_isa;
  char *opname;
  unsigned opnamelen;
  bfd_boolean has_underbar = FALSE;
  char *arg_strings[MAX_INSN_ARGS];
  int num_args;
  TInsn orig_insn;		/* Original instruction from the input.  */

  tinsn_init (&orig_insn);

  /* Split off the opcode.  */
  opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/0123456789.");
  opname = xstrndup (str, opnamelen);

  num_args = tokenize_arguments (arg_strings, str + opnamelen);
  if (num_args == -1)
    {
      as_bad (_("syntax error"));
      return;
    }

  if (xg_translate_idioms (&opname, &num_args, arg_strings))
    return;

  /* Check for an underbar prefix.  */
  if (*opname == '_')
    {
      has_underbar = TRUE;
      opname += 1;
    }

  orig_insn.insn_type = ITYPE_INSN;
  orig_insn.ntok = 0;
  orig_insn.is_specific_opcode = (has_underbar || !use_transform ());
  orig_insn.opcode = xtensa_opcode_lookup (isa, opname);

  /* Special case: Check for "CALLXn.TLS" psuedo op.  If found, grab its
     extra argument and set the opcode to "CALLXn".  */
  if (orig_insn.opcode == XTENSA_UNDEFINED
      && strncasecmp (opname, "callx", 5) == 0)
    {
      unsigned long window_size;
      char *suffix;

      window_size = strtoul (opname + 5, &suffix, 10);
      if (suffix != opname + 5
	  && (window_size == 0
	      || window_size == 4
	      || window_size == 8
	      || window_size == 12)
	  && strcasecmp (suffix, ".tls") == 0)
	{
	  switch (window_size)
	    {
	    case 0: orig_insn.opcode = xtensa_callx0_opcode; break;
	    case 4: orig_insn.opcode = xtensa_callx4_opcode; break;
	    case 8: orig_insn.opcode = xtensa_callx8_opcode; break;
	    case 12: orig_insn.opcode = xtensa_callx12_opcode; break;
	    }

	  if (num_args != 2)
	    as_bad (_("wrong number of operands for '%s'"), opname);
	  else
	    {
	      bfd_reloc_code_real_type reloc;
	      char *old_input_line_pointer;
	      expressionS *tok = &orig_insn.extra_arg;

	      old_input_line_pointer = input_line_pointer;
	      input_line_pointer = arg_strings[num_args - 1];

	      expression (tok);
	      if (tok->X_op == O_symbol
		  && ((reloc = xtensa_elf_suffix (&input_line_pointer, tok))
		      == BFD_RELOC_XTENSA_TLS_CALL))
		tok->X_op = map_suffix_reloc_to_operator (reloc);
	      else
		as_bad (_("bad relocation expression for '%s'"), opname);

	      input_line_pointer = old_input_line_pointer;
	      num_args -= 1;
	    }
	}
    }

  /* Special case: Check for "j.l" psuedo op.  */
  if (orig_insn.opcode == XTENSA_UNDEFINED
      && strncasecmp (opname, "j.l", 3) == 0)
    {
      if (num_args != 2)
	as_bad (_("wrong number of operands for '%s'"), opname);
      else
	{
	  char *old_input_line_pointer;
	  expressionS *tok = &orig_insn.extra_arg;

	  old_input_line_pointer = input_line_pointer;
	  input_line_pointer = arg_strings[num_args - 1];

	  expression_maybe_register (xtensa_jx_opcode, 0, tok);
	  input_line_pointer = old_input_line_pointer;

	  num_args -= 1;
	  orig_insn.opcode = xtensa_j_opcode;
	}
    }

  if (orig_insn.opcode == XTENSA_UNDEFINED)
    {
      xtensa_format fmt = xtensa_format_lookup (isa, opname);
      if (fmt == XTENSA_UNDEFINED)
	{
	  as_bad (_("unknown opcode or format name '%s'"), opname);
	  error_reset_cur_vinsn ();
	  return;
	}
      if (!cur_vinsn.inside_bundle)
	{
	  as_bad (_("format names only valid inside bundles"));
	  error_reset_cur_vinsn ();
	  return;
	}
      if (cur_vinsn.format != XTENSA_UNDEFINED)
	as_warn (_("multiple formats specified for one bundle; using '%s'"),
		 opname);
      cur_vinsn.format = fmt;
      free (has_underbar ? opname - 1 : opname);
      error_reset_cur_vinsn ();
      return;
    }

  /* Parse the arguments.  */
  if (parse_arguments (&orig_insn, num_args, arg_strings))
    {
      as_bad (_("syntax error"));
      error_reset_cur_vinsn ();
      return;
    }

  /* Free the opcode and argument strings, now that they've been parsed.  */
  free (has_underbar ? opname - 1 : opname);
  opname = 0;
  while (num_args-- > 0)
    free (arg_strings[num_args]);

  /* Get expressions for invisible operands.  */
  if (get_invisible_operands (&orig_insn))
    {
      error_reset_cur_vinsn ();
      return;
    }

  /* Check for the right number and type of arguments.  */
  if (tinsn_check_arguments (&orig_insn))
    {
      error_reset_cur_vinsn ();
      return;
    }

  /* Record the line number for each TInsn, because a FLIX bundle may be
     spread across multiple input lines and individual instructions may be
     moved around in some cases.  */
  orig_insn.loc_directive_seen = dwarf2_loc_directive_seen;
  dwarf2_where (&orig_insn.debug_line);
  dwarf2_consume_line_info ();

  xg_add_branch_and_loop_targets (&orig_insn);

  /* Check that immediate value for ENTRY is >= 16.  */
  if (orig_insn.opcode == xtensa_entry_opcode && orig_insn.ntok >= 3)
    {
      expressionS *exp = &orig_insn.tok[2];
      if (exp->X_op == O_constant && exp->X_add_number < 16)
	as_warn (_("entry instruction with stack decrement < 16"));
    }

  /* Finish it off:
     assemble_tokens (opcode, tok, ntok);
     expand the tokens from the orig_insn into the
     stack of instructions that will not expand
     unless required at relaxation time.  */

  if (!cur_vinsn.inside_bundle)
    emit_single_op (&orig_insn);
  else /* We are inside a bundle.  */
    {
      cur_vinsn.slots[cur_vinsn.num_slots] = orig_insn;
      cur_vinsn.num_slots++;
      if (*input_line_pointer == '}'
	  || *(input_line_pointer - 1) == '}'
	  || *(input_line_pointer - 2) == '}')
	finish_vinsn (&cur_vinsn);
    }

  /* We've just emitted a new instruction so clear the list of labels.  */
  xtensa_clear_insn_labels ();

  xtensa_check_frag_count ();
}


/* HANDLE_ALIGN hook */

/* For a .align directive, we mark the previous block with the alignment
   information.  This will be placed in the object file in the
   property section corresponding to this section.  */

void
xtensa_handle_align (fragS *fragP)
{
  if (linkrelax
      && ! fragP->tc_frag_data.is_literal
      && (fragP->fr_type == rs_align
	  || fragP->fr_type == rs_align_code)
      && fragP->fr_offset > 0
      && now_seg != bss_section)
    {
      fragP->tc_frag_data.is_align = TRUE;
      fragP->tc_frag_data.alignment = fragP->fr_offset;
    }

  if (fragP->fr_type == rs_align_test)
    {
      int count;
      count = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
      if (count != 0)
	as_bad_where (fragP->fr_file, fragP->fr_line,
		      _("unaligned entry instruction"));
    }

  if (linkrelax && fragP->fr_type == rs_org)
    fragP->fr_subtype = RELAX_ORG;
}


/* TC_FRAG_INIT hook */

void
xtensa_frag_init (fragS *frag)
{
  xtensa_set_frag_assembly_state (frag);
}


symbolS *
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
{
  return NULL;
}


/* Round up a section size to the appropriate boundary.  */

valueT
md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
{
  return size;			/* Byte alignment is fine.  */
}


long
md_pcrel_from (fixS *fixP)
{
  char *insn_p;
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  int opnum;
  uint32 opnd_value;
  xtensa_opcode opcode;
  xtensa_format fmt;
  int slot;
  xtensa_isa isa = xtensa_default_isa;
  valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
  bfd_boolean alt_reloc;

  if (fixP->fx_r_type == BFD_RELOC_XTENSA_ASM_EXPAND)
    return 0;

  if (fixP->fx_r_type == BFD_RELOC_32_PCREL)
    return addr;

  if (!insnbuf)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  insn_p = &fixP->fx_frag->fr_literal[fixP->fx_where];
  xtensa_insnbuf_from_chars (isa, insnbuf, (unsigned char *) insn_p, 0);
  fmt = xtensa_format_decode (isa, insnbuf);

  if (fmt == XTENSA_UNDEFINED)
    as_fatal (_("bad instruction format"));

  if (decode_reloc (fixP->fx_r_type, &slot, &alt_reloc) != 0)
    as_fatal (_("invalid relocation"));

  xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
  opcode = xtensa_opcode_decode (isa, fmt, slot, slotbuf);

  /* Check for "alternate" relocations (operand not specified).  None
     of the current uses for these are really PC-relative.  */
  if (alt_reloc || opcode == xtensa_const16_opcode)
    {
      if (opcode != xtensa_l32r_opcode
	  && opcode != xtensa_const16_opcode)
	as_fatal (_("invalid relocation for '%s' instruction"),
		  xtensa_opcode_name (isa, opcode));
      return 0;
    }

  opnum = get_relaxable_immed (opcode);
  opnd_value = 0;
  if (xtensa_operand_is_PCrelative (isa, opcode, opnum) != 1
      || xtensa_operand_do_reloc (isa, opcode, opnum, &opnd_value, addr))
    {
      as_bad_where (fixP->fx_file,
		    fixP->fx_line,
		    _("invalid relocation for operand %d of '%s'"),
		    opnum, xtensa_opcode_name (isa, opcode));
      return 0;
    }
  return 0 - opnd_value;
}


/* TC_FORCE_RELOCATION hook */

int
xtensa_force_relocation (fixS *fix)
{
  switch (fix->fx_r_type)
    {
    case BFD_RELOC_XTENSA_ASM_EXPAND:
    case BFD_RELOC_XTENSA_SLOT0_ALT:
    case BFD_RELOC_XTENSA_SLOT1_ALT:
    case BFD_RELOC_XTENSA_SLOT2_ALT:
    case BFD_RELOC_XTENSA_SLOT3_ALT:
    case BFD_RELOC_XTENSA_SLOT4_ALT:
    case BFD_RELOC_XTENSA_SLOT5_ALT:
    case BFD_RELOC_XTENSA_SLOT6_ALT:
    case BFD_RELOC_XTENSA_SLOT7_ALT:
    case BFD_RELOC_XTENSA_SLOT8_ALT:
    case BFD_RELOC_XTENSA_SLOT9_ALT:
    case BFD_RELOC_XTENSA_SLOT10_ALT:
    case BFD_RELOC_XTENSA_SLOT11_ALT:
    case BFD_RELOC_XTENSA_SLOT12_ALT:
    case BFD_RELOC_XTENSA_SLOT13_ALT:
    case BFD_RELOC_XTENSA_SLOT14_ALT:
      return 1;
    default:
      break;
    }

  if (linkrelax && fix->fx_addsy
      && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
    return 1;

  return generic_force_reloc (fix);
}


/* TC_VALIDATE_FIX_SUB hook */

int
xtensa_validate_fix_sub (fixS *fix)
{
  segT add_symbol_segment, sub_symbol_segment;

  /* The difference of two symbols should be resolved by the assembler when
     linkrelax is not set.  If the linker may relax the section containing
     the symbols, then an Xtensa DIFF relocation must be generated so that
     the linker knows to adjust the difference value.  */
  if (!linkrelax || fix->fx_addsy == NULL)
    return 0;

  /* Make sure both symbols are in the same segment, and that segment is
     "normal" and relaxable.  If the segment is not "normal", then the
     fix is not valid.  If the segment is not "relaxable", then the fix
     should have been handled earlier.  */
  add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
  if (! SEG_NORMAL (add_symbol_segment) ||
      ! relaxable_section (add_symbol_segment))
    return 0;
  sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
  return (sub_symbol_segment == add_symbol_segment);
}


/* NO_PSEUDO_DOT hook */

/* This function has nothing to do with pseudo dots, but this is the
   nearest macro to where the check needs to take place.  FIXME: This
   seems wrong.  */

bfd_boolean
xtensa_check_inside_bundle (void)
{
  if (cur_vinsn.inside_bundle && input_line_pointer[-1] == '.')
    as_bad (_("directives are not valid inside bundles"));

  /* This function must always return FALSE because it is called via a
     macro that has nothing to do with bundling.  */
  return FALSE;
}


/* md_elf_section_change_hook */

void
xtensa_elf_section_change_hook (void)
{
  /* Set up the assembly state.  */
  if (!frag_now->tc_frag_data.is_assembly_state_set)
    xtensa_set_frag_assembly_state (frag_now);
}


/* tc_fix_adjustable hook */

bfd_boolean
xtensa_fix_adjustable (fixS *fixP)
{
  /* We need the symbol name for the VTABLE entries.  */
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    return 0;

  return 1;
}


/* tc_symbol_new_hook */

symbolS *expr_symbols = NULL;

void
xtensa_symbol_new_hook (symbolS *sym)
{
  if (is_leb128_expr && S_GET_SEGMENT (sym) == expr_section)
    {
      symbol_get_tc (sym)->next_expr_symbol = expr_symbols;
      expr_symbols = sym;
    }
}


void
md_apply_fix (fixS *fixP, valueT *valP, segT seg)
{
  char *const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
  valueT val = 0;

  /* Subtracted symbols are only allowed for a few relocation types, and
     unless linkrelax is enabled, they should not make it to this point.  */
  if (fixP->fx_subsy && !(linkrelax && (fixP->fx_r_type == BFD_RELOC_32
					|| fixP->fx_r_type == BFD_RELOC_16
					|| fixP->fx_r_type == BFD_RELOC_8)))
    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));

  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_32_PCREL:
    case BFD_RELOC_32:
    case BFD_RELOC_16:
    case BFD_RELOC_8:
      if (fixP->fx_subsy)
	{
	  switch (fixP->fx_r_type)
	    {
	    case BFD_RELOC_8:
	      fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8;
	      fixP->fx_signed = 0;
	      break;
	    case BFD_RELOC_16:
	      fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16;
	      fixP->fx_signed = 0;
	      break;
	    case BFD_RELOC_32:
	      fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32;
	      fixP->fx_signed = 0;
	      break;
	    default:
	      break;
	    }

	  val = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
		 - S_GET_VALUE (fixP->fx_subsy));

	  /* The difference value gets written out, and the DIFF reloc
	     identifies the address of the subtracted symbol (i.e., the one
	     with the lowest address).  */
	  *valP = val;
	  fixP->fx_offset -= val;
	  fixP->fx_subsy = NULL;
	}
      else if (! fixP->fx_addsy)
	{
	  val = *valP;
	  fixP->fx_done = 1;
	}
      /* fall through */

    case BFD_RELOC_XTENSA_PLT:
      md_number_to_chars (fixpos, val, fixP->fx_size);
      fixP->fx_no_overflow = 0; /* Use the standard overflow check.  */
      break;

    case BFD_RELOC_XTENSA_TLSDESC_FN:
    case BFD_RELOC_XTENSA_TLSDESC_ARG:
    case BFD_RELOC_XTENSA_TLS_TPOFF:
    case BFD_RELOC_XTENSA_TLS_DTPOFF:
      S_SET_THREAD_LOCAL (fixP->fx_addsy);
      md_number_to_chars (fixpos, 0, fixP->fx_size);
      fixP->fx_no_overflow = 0; /* Use the standard overflow check.  */
      break;

    case BFD_RELOC_XTENSA_SLOT0_OP:
    case BFD_RELOC_XTENSA_SLOT1_OP:
    case BFD_RELOC_XTENSA_SLOT2_OP:
    case BFD_RELOC_XTENSA_SLOT3_OP:
    case BFD_RELOC_XTENSA_SLOT4_OP:
    case BFD_RELOC_XTENSA_SLOT5_OP:
    case BFD_RELOC_XTENSA_SLOT6_OP:
    case BFD_RELOC_XTENSA_SLOT7_OP:
    case BFD_RELOC_XTENSA_SLOT8_OP:
    case BFD_RELOC_XTENSA_SLOT9_OP:
    case BFD_RELOC_XTENSA_SLOT10_OP:
    case BFD_RELOC_XTENSA_SLOT11_OP:
    case BFD_RELOC_XTENSA_SLOT12_OP:
    case BFD_RELOC_XTENSA_SLOT13_OP:
    case BFD_RELOC_XTENSA_SLOT14_OP:
      if (linkrelax)
	{
	  /* Write the tentative value of a PC-relative relocation to a
	     local symbol into the instruction.  The value will be ignored
	     by the linker, and it makes the object file disassembly
	     readable when all branch targets are encoded in relocations.  */

	  gas_assert (fixP->fx_addsy);
	  if (S_GET_SEGMENT (fixP->fx_addsy) == seg
	      && !S_FORCE_RELOC (fixP->fx_addsy, 1))
	    {
	      val = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
		     - md_pcrel_from (fixP));
	      (void) xg_apply_fix_value (fixP, val);
	    }
	}
      else if (! fixP->fx_addsy)
	{
	  val = *valP;
	  if (xg_apply_fix_value (fixP, val))
	    fixP->fx_done = 1;
	}
      break;

    case BFD_RELOC_XTENSA_ASM_EXPAND:
    case BFD_RELOC_XTENSA_TLS_FUNC:
    case BFD_RELOC_XTENSA_TLS_ARG:
    case BFD_RELOC_XTENSA_TLS_CALL:
    case BFD_RELOC_XTENSA_SLOT0_ALT:
    case BFD_RELOC_XTENSA_SLOT1_ALT:
    case BFD_RELOC_XTENSA_SLOT2_ALT:
    case BFD_RELOC_XTENSA_SLOT3_ALT:
    case BFD_RELOC_XTENSA_SLOT4_ALT:
    case BFD_RELOC_XTENSA_SLOT5_ALT:
    case BFD_RELOC_XTENSA_SLOT6_ALT:
    case BFD_RELOC_XTENSA_SLOT7_ALT:
    case BFD_RELOC_XTENSA_SLOT8_ALT:
    case BFD_RELOC_XTENSA_SLOT9_ALT:
    case BFD_RELOC_XTENSA_SLOT10_ALT:
    case BFD_RELOC_XTENSA_SLOT11_ALT:
    case BFD_RELOC_XTENSA_SLOT12_ALT:
    case BFD_RELOC_XTENSA_SLOT13_ALT:
    case BFD_RELOC_XTENSA_SLOT14_ALT:
      /* These all need to be resolved at link-time.  Do nothing now.  */
      break;

    case BFD_RELOC_VTABLE_INHERIT:
    case BFD_RELOC_VTABLE_ENTRY:
      fixP->fx_done = 0;
      break;

    default:
      as_bad (_("unhandled local relocation fix %s"),
	      bfd_get_reloc_code_name (fixP->fx_r_type));
    }
}


const char *
md_atof (int type, char *litP, int *sizeP)
{
  return ieee_md_atof (type, litP, sizeP, target_big_endian);
}


int
md_estimate_size_before_relax (fragS *fragP, segT seg ATTRIBUTE_UNUSED)
{
  return total_frag_text_expansion (fragP);
}


/* Translate internal representation of relocation info to BFD target
   format.  */

arelent *
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
{
  arelent *reloc;

  reloc = XNEW (arelent);
  reloc->sym_ptr_ptr = XNEW (asymbol *);
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;

  /* Make sure none of our internal relocations make it this far.
     They'd better have been fully resolved by this point.  */
  gas_assert ((int) fixp->fx_r_type > 0);

  reloc->addend = fixp->fx_offset;

  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
  if (reloc->howto == NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
		    _("cannot represent `%s' relocation in object file"),
		    bfd_get_reloc_code_name (fixp->fx_r_type));
      free (reloc->sym_ptr_ptr);
      free (reloc);
      return NULL;
    }

  if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
    as_fatal (_("internal error; cannot generate `%s' relocation"),
	      bfd_get_reloc_code_name (fixp->fx_r_type));

  return reloc;
}


/* Checks for resource conflicts between instructions.  */

/* The func unit stuff could be implemented as bit-vectors rather
   than the iterative approach here.  If it ends up being too
   slow, we will switch it.  */

resource_table *
new_resource_table (void *data,
		    int cycles,
		    int nu,
		    unit_num_copies_func uncf,
		    opcode_num_units_func onuf,
		    opcode_funcUnit_use_unit_func ouuf,
		    opcode_funcUnit_use_stage_func ousf)
{
  int i;
  resource_table *rt = XNEW (resource_table);
  rt->data = data;
  rt->cycles = cycles;
  rt->allocated_cycles = cycles;
  rt->num_units = nu;
  rt->unit_num_copies = uncf;
  rt->opcode_num_units = onuf;
  rt->opcode_unit_use = ouuf;
  rt->opcode_unit_stage = ousf;

  rt->units = XCNEWVEC (unsigned char *, cycles);
  for (i = 0; i < cycles; i++)
    rt->units[i] = XCNEWVEC (unsigned char, nu);

  return rt;
}


void
clear_resource_table (resource_table *rt)
{
  int i, j;
  for (i = 0; i < rt->allocated_cycles; i++)
    for (j = 0; j < rt->num_units; j++)
      rt->units[i][j] = 0;
}


/* We never shrink it, just fake it into thinking so.  */

void
resize_resource_table (resource_table *rt, int cycles)
{
  int i, old_cycles;

  rt->cycles = cycles;
  if (cycles <= rt->allocated_cycles)
    return;

  old_cycles = rt->allocated_cycles;
  rt->allocated_cycles = cycles;

  rt->units = XRESIZEVEC (unsigned char *, rt->units, rt->allocated_cycles);
  for (i = 0; i < old_cycles; i++)
    rt->units[i] = XRESIZEVEC (unsigned char, rt->units[i], rt->num_units);
  for (i = old_cycles; i < cycles; i++)
    rt->units[i] = XCNEWVEC (unsigned char, rt->num_units);
}


bfd_boolean
resources_available (resource_table *rt, xtensa_opcode opcode, int cycle)
{
  int i;
  int uses = (rt->opcode_num_units) (rt->data, opcode);

  for (i = 0; i < uses; i++)
    {
      xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i);
      int stage = (rt->opcode_unit_stage) (rt->data, opcode, i);
      int copies_in_use = rt->units[stage + cycle][unit];
      int copies = (rt->unit_num_copies) (rt->data, unit);
      if (copies_in_use >= copies)
	return FALSE;
    }
  return TRUE;
}


void
reserve_resources (resource_table *rt, xtensa_opcode opcode, int cycle)
{
  int i;
  int uses = (rt->opcode_num_units) (rt->data, opcode);

  for (i = 0; i < uses; i++)
    {
      xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i);
      int stage = (rt->opcode_unit_stage) (rt->data, opcode, i);
      /* Note that this allows resources to be oversubscribed.  That's
	 essential to the way the optional scheduler works.
	 resources_available reports when a resource is over-subscribed,
	 so it's easy to tell.  */
      rt->units[stage + cycle][unit]++;
    }
}


void
release_resources (resource_table *rt, xtensa_opcode opcode, int cycle)
{
  int i;
  int uses = (rt->opcode_num_units) (rt->data, opcode);

  for (i = 0; i < uses; i++)
    {
      xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i);
      int stage = (rt->opcode_unit_stage) (rt->data, opcode, i);
      gas_assert (rt->units[stage + cycle][unit] > 0);
      rt->units[stage + cycle][unit]--;
    }
}


/* Wrapper functions make parameterized resource reservation
   more convenient.  */

int
opcode_funcUnit_use_unit (void *data, xtensa_opcode opcode, int idx)
{
  xtensa_funcUnit_use *use = xtensa_opcode_funcUnit_use (data, opcode, idx);
  return use->unit;
}


int
opcode_funcUnit_use_stage (void *data, xtensa_opcode opcode, int idx)
{
  xtensa_funcUnit_use *use = xtensa_opcode_funcUnit_use (data, opcode, idx);
  return use->stage;
}


/* Note that this function does not check issue constraints, but
   solely whether the hardware is available to execute the given
   instructions together.  It also doesn't check if the tinsns
   write the same state, or access the same tieports.  That is
   checked by check_t1_t2_reads_and_writes.  */

static bfd_boolean
resources_conflict (vliw_insn *vinsn)
{
  int i;
  static resource_table *rt = NULL;

  /* This is the most common case by far.  Optimize it.  */
  if (vinsn->num_slots == 1)
    return FALSE;

  if (rt == NULL)
    {
      xtensa_isa isa = xtensa_default_isa;
      rt = new_resource_table
	(isa, xtensa_num_pipe_stages,
	 xtensa_isa_num_funcUnits (isa),
	 (unit_num_copies_func) xtensa_funcUnit_num_copies,
	 (opcode_num_units_func) xtensa_opcode_num_funcUnit_uses,
	 opcode_funcUnit_use_unit,
	 opcode_funcUnit_use_stage);
    }

  clear_resource_table (rt);

  for (i = 0; i < vinsn->num_slots; i++)
    {
      if (!resources_available (rt, vinsn->slots[i].opcode, 0))
	return TRUE;
      reserve_resources (rt, vinsn->slots[i].opcode, 0);
    }

  return FALSE;
}


/* finish_vinsn, emit_single_op and helper functions.  */

static bfd_boolean find_vinsn_conflicts (vliw_insn *);
static xtensa_format xg_find_narrowest_format (vliw_insn *);
static void xg_assemble_vliw_tokens (vliw_insn *);


/* We have reached the end of a bundle; emit into the frag.  */

static void
finish_vinsn (vliw_insn *vinsn)
{
  IStack slotstack;
  int i;

  if (find_vinsn_conflicts (vinsn))
    {
      xg_clear_vinsn (vinsn);
      return;
    }

  /* First, find a format that works.  */
  if (vinsn->format == XTENSA_UNDEFINED)
    vinsn->format = xg_find_narrowest_format (vinsn);

  if (xtensa_format_num_slots (xtensa_default_isa, vinsn->format) > 1
      && produce_flix == FLIX_NONE)
    {
      as_bad (_("The option \"--no-allow-flix\" prohibits multi-slot flix."));
      xg_clear_vinsn (vinsn);
      return;
    }

  if (vinsn->format == XTENSA_UNDEFINED)
    {
      as_bad (_("couldn't find a valid instruction format"));
      fprintf (stderr, _("    ops were: "));
      for (i = 0; i < vinsn->num_slots; i++)
	fprintf (stderr, _(" %s;"),
		 xtensa_opcode_name (xtensa_default_isa,
				     vinsn->slots[i].opcode));
      fprintf (stderr, _("\n"));
      xg_clear_vinsn (vinsn);
      return;
    }

  if (vinsn->num_slots
      != xtensa_format_num_slots (xtensa_default_isa, vinsn->format))
    {
      as_bad (_("format '%s' allows %d slots, but there are %d opcodes"),
	      xtensa_format_name (xtensa_default_isa, vinsn->format),
	      xtensa_format_num_slots (xtensa_default_isa, vinsn->format),
	      vinsn->num_slots);
      xg_clear_vinsn (vinsn);
      return;
    }

  if (resources_conflict (vinsn))
    {
      as_bad (_("illegal resource usage in bundle"));
      fprintf (stderr, "    ops were: ");
      for (i = 0; i < vinsn->num_slots; i++)
	fprintf (stderr, " %s;",
		 xtensa_opcode_name (xtensa_default_isa,
				     vinsn->slots[i].opcode));
      fprintf (stderr, "\n");
      xg_clear_vinsn (vinsn);
      return;
    }

  for (i = 0; i < vinsn->num_slots; i++)
    {
      if (vinsn->slots[i].opcode != XTENSA_UNDEFINED)
	{
	  symbolS *lit_sym = NULL;
	  int j;
	  bfd_boolean e = FALSE;
	  bfd_boolean saved_density = density_supported;

	  /* We don't want to narrow ops inside multi-slot bundles.  */
	  if (vinsn->num_slots > 1)
	    density_supported = FALSE;

	  istack_init (&slotstack);
	  if (vinsn->slots[i].opcode == xtensa_nop_opcode)
	    {
	      vinsn->slots[i].opcode =
		xtensa_format_slot_nop_opcode (xtensa_default_isa,
					       vinsn->format, i);
	      vinsn->slots[i].ntok = 0;
	    }

	  if (xg_expand_assembly_insn (&slotstack, &vinsn->slots[i]))
	    {
	      e = TRUE;
	      continue;
	    }

	  density_supported = saved_density;

	  if (e)
	    {
	      xg_clear_vinsn (vinsn);
	      return;
	    }

	  for (j = 0; j < slotstack.ninsn; j++)
	    {
	      TInsn *insn = &slotstack.insn[j];
	      if (insn->insn_type == ITYPE_LITERAL)
		{
		  gas_assert (lit_sym == NULL);
		  lit_sym = xg_assemble_literal (insn);
		}
	      else
		{
		  gas_assert (insn->insn_type == ITYPE_INSN);
		  if (lit_sym)
		    xg_resolve_literals (insn, lit_sym);
		  if (j != slotstack.ninsn - 1)
		    emit_single_op (insn);
		}
	    }

	  if (vinsn->num_slots > 1)
	    {
	      if (opcode_fits_format_slot
		  (slotstack.insn[slotstack.ninsn - 1].opcode,
		   vinsn->format, i))
		{
		  vinsn->slots[i] = slotstack.insn[slotstack.ninsn - 1];
		}
	      else
		{
		  emit_single_op (&slotstack.insn[slotstack.ninsn - 1]);
		  if (vinsn->format == XTENSA_UNDEFINED)
		    vinsn->slots[i].opcode = xtensa_nop_opcode;
		  else
		    vinsn->slots[i].opcode
		      = xtensa_format_slot_nop_opcode (xtensa_default_isa,
						       vinsn->format, i);

		  vinsn->slots[i].ntok = 0;
		}
	    }
	  else
	    {
	      vinsn->slots[0] = slotstack.insn[slotstack.ninsn - 1];
	      vinsn->format = XTENSA_UNDEFINED;
	    }
	}
    }

  /* Now check resource conflicts on the modified bundle.  */
  if (resources_conflict (vinsn))
    {
      as_bad (_("illegal resource usage in bundle"));
      fprintf (stderr, "    ops were: ");
      for (i = 0; i < vinsn->num_slots; i++)
	fprintf (stderr, " %s;",
		 xtensa_opcode_name (xtensa_default_isa,
				     vinsn->slots[i].opcode));
      fprintf (stderr, "\n");
      xg_clear_vinsn (vinsn);
      return;
    }

  /* First, find a format that works.  */
  if (vinsn->format == XTENSA_UNDEFINED)
      vinsn->format = xg_find_narrowest_format (vinsn);

  xg_assemble_vliw_tokens (vinsn);

  xg_clear_vinsn (vinsn);

  xtensa_check_frag_count ();
}


/* Given an vliw instruction, what conflicts are there in register
   usage and in writes to states and queues?

   This function does two things:
   1. Reports an error when a vinsn contains illegal combinations
      of writes to registers states or queues.
   2. Marks individual tinsns as not relaxable if the combination
      contains antidependencies.

   Job 2 handles things like swap semantics in instructions that need
   to be relaxed.  For example,

	addi a0, a1, 100000

   normally would be relaxed to

	l32r a0, some_label
	add a0, a1, a0

   _but_, if the above instruction is bundled with an a0 reader, e.g.,

	{ addi a0, a1, 10000 ; add a2, a0, a4 ; }

   then we can't relax it into

	l32r a0, some_label
	{ add a0, a1, a0 ; add a2, a0, a4 ; }

   because the value of a0 is trashed before the second add can read it.  */

static char check_t1_t2_reads_and_writes (TInsn *, TInsn *);

static bfd_boolean
find_vinsn_conflicts (vliw_insn *vinsn)
{
  int i, j;
  int branches = 0;
  xtensa_isa isa = xtensa_default_isa;

  gas_assert (!past_xtensa_end);

  for (i = 0 ; i < vinsn->num_slots; i++)
    {
      TInsn *op1 = &vinsn->slots[i];
      if (op1->is_specific_opcode)
	op1->keep_wide = TRUE;
      else
	op1->keep_wide = FALSE;
    }

  for (i = 0 ; i < vinsn->num_slots; i++)
    {
      TInsn *op1 = &vinsn->slots[i];

      if (xtensa_opcode_is_branch (isa, op1->opcode) == 1)
	branches++;

      for (j = 0; j < vinsn->num_slots; j++)
	{
	  if (i != j)
	    {
	      TInsn *op2 = &vinsn->slots[j];
	      char conflict_type = check_t1_t2_reads_and_writes (op1, op2);
	      switch (conflict_type)
		{
		case 'c':
		  as_bad (_("opcodes '%s' (slot %d) and '%s' (slot %d) write the same register"),
			  xtensa_opcode_name (isa, op1->opcode), i,
			  xtensa_opcode_name (isa, op2->opcode), j);
		  return TRUE;
		case 'd':
		  as_bad (_("opcodes '%s' (slot %d) and '%s' (slot %d) write the same state"),
			  xtensa_opcode_name (isa, op1->opcode), i,
			  xtensa_opcode_name (isa, op2->opcode), j);
		  return TRUE;
		case 'e':
		  as_bad (_("opcodes '%s' (slot %d) and '%s' (slot %d) write the same port"),
			  xtensa_opcode_name (isa, op1->opcode), i,
			  xtensa_opcode_name (isa, op2->opcode), j);
		  return TRUE;
		case 'f':
		  as_bad (_("opcodes '%s' (slot %d) and '%s' (slot %d) both have volatile port accesses"),
			  xtensa_opcode_name (isa, op1->opcode), i,
			  xtensa_opcode_name (isa, op2->opcode), j);
		  return TRUE;
		default:
		  /* Everything is OK.  */
		  break;
		}
	      op2->is_specific_opcode = (op2->is_specific_opcode
					 || conflict_type == 'a');
	    }
	}
    }

  if (branches > 1)
    {
      as_bad (_("multiple branches or jumps in the same bundle"));
      return TRUE;
    }

  return FALSE;
}


/* Check how the state used by t1 and t2 relate.
   Cases found are:

   case A: t1 reads a register t2 writes (an antidependency within a bundle)
   case B: no relationship between what is read and written (both could
           read the same reg though)
   case C: t1 writes a register t2 writes (a register conflict within a
           bundle)
   case D: t1 writes a state that t2 also writes
   case E: t1 writes a tie queue that t2 also writes
   case F: two volatile queue accesses
*/

static char
check_t1_t2_reads_and_writes (TInsn *t1, TInsn *t2)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_regfile t1_regfile, t2_regfile;
  int t1_reg, t2_reg;
  int t1_base_reg, t1_last_reg;
  int t2_base_reg, t2_last_reg;
  char t1_inout, t2_inout;
  int i, j;
  char conflict = 'b';
  int t1_states;
  int t2_states;
  int t1_interfaces;
  int t2_interfaces;
  bfd_boolean t1_volatile = FALSE;
  bfd_boolean t2_volatile = FALSE;

  /* Check registers.  */
  for (j = 0; j < t2->ntok; j++)
    {
      if (xtensa_operand_is_register (isa, t2->opcode, j) != 1)
	continue;

      t2_regfile = xtensa_operand_regfile (isa, t2->opcode, j);
      t2_base_reg = t2->tok[j].X_add_number;
      t2_last_reg = t2_base_reg + xtensa_operand_num_regs (isa, t2->opcode, j);

      for (i = 0; i < t1->ntok; i++)
	{
	  if (xtensa_operand_is_register (isa, t1->opcode, i) != 1)
	    continue;

	  t1_regfile = xtensa_operand_regfile (isa, t1->opcode, i);

	  if (t1_regfile != t2_regfile)
	    continue;

	  t1_inout = xtensa_operand_inout (isa, t1->opcode, i);
	  t2_inout = xtensa_operand_inout (isa, t2->opcode, j);

	  if (xtensa_operand_is_known_reg (isa, t1->opcode, i) == 0
	      || xtensa_operand_is_known_reg (isa, t2->opcode, j) == 0)
	    {
	      if (t1_inout == 'm' || t1_inout == 'o'
		  || t2_inout == 'm' || t2_inout == 'o')
		{
		  conflict = 'a';
		  continue;
		}
	    }

	  t1_base_reg = t1->tok[i].X_add_number;
	  t1_last_reg = (t1_base_reg
			 + xtensa_operand_num_regs (isa, t1->opcode, i));

	  for (t1_reg = t1_base_reg; t1_reg < t1_last_reg; t1_reg++)
	    {
	      for (t2_reg = t2_base_reg; t2_reg < t2_last_reg; t2_reg++)
		{
		  if (t1_reg != t2_reg)
		    continue;

		  if (t2_inout == 'i' && (t1_inout == 'm' || t1_inout == 'o'))
		    {
		      conflict = 'a';
		      continue;
		    }

		  if (t1_inout == 'i' && (t2_inout == 'm' || t2_inout == 'o'))
		    {
		      conflict = 'a';
		      continue;
		    }

		  if (t1_inout != 'i' && t2_inout != 'i')
		    return 'c';
		}
	    }
	}
    }

  /* Check states.  */
  t1_states = xtensa_opcode_num_stateOperands (isa, t1->opcode);
  t2_states = xtensa_opcode_num_stateOperands (isa, t2->opcode);
  for (j = 0; j < t2_states; j++)
    {
      xtensa_state t2_so = xtensa_stateOperand_state (isa, t2->opcode, j);
      t2_inout = xtensa_stateOperand_inout (isa, t2->opcode, j);
      for (i = 0; i < t1_states; i++)
	{
	  xtensa_state t1_so = xtensa_stateOperand_state (isa, t1->opcode, i);
	  t1_inout = xtensa_stateOperand_inout (isa, t1->opcode, i);
	  if (t1_so != t2_so || xtensa_state_is_shared_or (isa, t1_so) == 1)
	    continue;

	  if (t2_inout == 'i' && (t1_inout == 'm' || t1_inout == 'o'))
	    {
	      conflict = 'a';
	      continue;
	    }

	  if (t1_inout == 'i' && (t2_inout == 'm' || t2_inout == 'o'))
	    {
	      conflict = 'a';
	      continue;
	    }

	  if (t1_inout != 'i' && t2_inout != 'i')
	    return 'd';
	}
    }

  /* Check tieports.  */
  t1_interfaces = xtensa_opcode_num_interfaceOperands (isa, t1->opcode);
  t2_interfaces = xtensa_opcode_num_interfaceOperands (isa, t2->opcode);
  for (j = 0; j < t2_interfaces; j++)
    {
      xtensa_interface t2_int
	= xtensa_interfaceOperand_interface (isa, t2->opcode, j);
      int t2_class = xtensa_interface_class_id (isa, t2_int);

      t2_inout = xtensa_interface_inout (isa, t2_int);
      if (xtensa_interface_has_side_effect (isa, t2_int) == 1)
	t2_volatile = TRUE;

      for (i = 0; i < t1_interfaces; i++)
	{
	  xtensa_interface t1_int
	    = xtensa_interfaceOperand_interface (isa, t1->opcode, j);
	  int t1_class = xtensa_interface_class_id (isa, t1_int);

	  t1_inout = xtensa_interface_inout (isa, t1_int);
	  if (xtensa_interface_has_side_effect (isa, t1_int) == 1)
	    t1_volatile = TRUE;

	  if (t1_volatile && t2_volatile && (t1_class == t2_class))
	    return 'f';

	  if (t1_int != t2_int)
	    continue;

	  if (t2_inout == 'i' && t1_inout == 'o')
	    {
	      conflict = 'a';
	      continue;
	    }

	  if (t1_inout == 'i' && t2_inout == 'o')
	    {
	      conflict = 'a';
	      continue;
	    }

	  if (t1_inout != 'i' && t2_inout != 'i')
	    return 'e';
	}
    }

  return conflict;
}


static xtensa_format
xg_find_narrowest_format (vliw_insn *vinsn)
{
  /* Right now we assume that the ops within the vinsn are properly
     ordered for the slots that the programmer wanted them in.  In
     other words, we don't rearrange the ops in hopes of finding a
     better format.  The scheduler handles that.  */

  xtensa_isa isa = xtensa_default_isa;
  xtensa_format format;
  xtensa_opcode nop_opcode = xtensa_nop_opcode;

  if (vinsn->num_slots == 1)
    return xg_get_single_format (vinsn->slots[0].opcode);

  for (format = 0; format < xtensa_isa_num_formats (isa); format++)
    {
      vliw_insn v_copy;
      xg_copy_vinsn (&v_copy, vinsn);
      if (xtensa_format_num_slots (isa, format) == v_copy.num_slots)
	{
	  int slot;
	  int fit = 0;
	  for (slot = 0; slot < v_copy.num_slots; slot++)
	    {
	      if (v_copy.slots[slot].opcode == nop_opcode)
		{
		  v_copy.slots[slot].opcode =
		    xtensa_format_slot_nop_opcode (isa, format, slot);
		  v_copy.slots[slot].ntok = 0;
		}

	      if (opcode_fits_format_slot (v_copy.slots[slot].opcode,
					   format, slot))
		fit++;
	      else if (v_copy.num_slots > 1)
		{
		  TInsn widened;
		  /* Try the widened version.  */
		  if (!v_copy.slots[slot].keep_wide
		      && !v_copy.slots[slot].is_specific_opcode
		      && xg_is_single_relaxable_insn (&v_copy.slots[slot],
						      &widened, TRUE)
		      && opcode_fits_format_slot (widened.opcode,
						  format, slot))
		    {
		      v_copy.slots[slot] = widened;
		      fit++;
		    }
		}
	    }
	  if (fit == v_copy.num_slots)
	    {
	      xg_copy_vinsn (vinsn, &v_copy);
	      xtensa_format_encode (isa, format, vinsn->insnbuf);
	      vinsn->format = format;
	      break;
	    }
	}
    }

  if (format == xtensa_isa_num_formats (isa))
    return XTENSA_UNDEFINED;

  return format;
}


/* Return the additional space needed in a frag
   for possible relaxations of any ops in a VLIW insn.
   Also fill out the relaxations that might be required of
   each tinsn in the vinsn.  */

static int
relaxation_requirements (vliw_insn *vinsn, bfd_boolean *pfinish_frag)
{
  bfd_boolean finish_frag = FALSE;
  int extra_space = 0;
  int slot;

  for (slot = 0; slot < vinsn->num_slots; slot++)
    {
      TInsn *tinsn = &vinsn->slots[slot];
      if (!tinsn_has_symbolic_operands (tinsn))
	{
	  /* A narrow instruction could be widened later to help
	     alignment issues.  */
	  if (xg_is_single_relaxable_insn (tinsn, 0, TRUE)
	      && !tinsn->is_specific_opcode
	      && vinsn->num_slots == 1)
	    {
	      /* Difference in bytes between narrow and wide insns...  */
	      extra_space += 1;
	      tinsn->subtype = RELAX_NARROW;
	    }
	}
      else
	{
	  if (workaround_b_j_loop_end
	      && tinsn->opcode == xtensa_jx_opcode
	      && use_transform ())
	    {
	      /* Add 2 of these.  */
	      extra_space += 3; /* for the nop size */
	      tinsn->subtype = RELAX_ADD_NOP_IF_PRE_LOOP_END;
	    }

	  /* Need to assemble it with space for the relocation.  */
	  if (xg_is_relaxable_insn (tinsn, 0)
	      && !tinsn->is_specific_opcode)
	    {
	      int max_size = xg_get_max_insn_widen_size (tinsn->opcode);
	      int max_literal_size =
		xg_get_max_insn_widen_literal_size (tinsn->opcode);

	      tinsn->literal_space = max_literal_size;

	      tinsn->subtype = RELAX_IMMED;
	      extra_space += max_size;
	    }
	  else
	    {
	      /* A fix record will be added for this instruction prior
		 to relaxation, so make it end the frag.  */
	      finish_frag = TRUE;
	    }
	}
    }
  *pfinish_frag = finish_frag;
  return extra_space;
}


static void
bundle_tinsn (TInsn *tinsn, vliw_insn *vinsn)
{
  xtensa_isa isa = xtensa_default_isa;
  int slot, chosen_slot;

  vinsn->format = xg_get_single_format (tinsn->opcode);
  gas_assert (vinsn->format != XTENSA_UNDEFINED);
  vinsn->num_slots = xtensa_format_num_slots (isa, vinsn->format);

  chosen_slot = xg_get_single_slot (tinsn->opcode);
  for (slot = 0; slot < vinsn->num_slots; slot++)
    {
      if (slot == chosen_slot)
	vinsn->slots[slot] = *tinsn;
      else
	{
	  vinsn->slots[slot].opcode =
	    xtensa_format_slot_nop_opcode (isa, vinsn->format, slot);
	  vinsn->slots[slot].ntok = 0;
	  vinsn->slots[slot].insn_type = ITYPE_INSN;
	}
    }
}


static bfd_boolean
emit_single_op (TInsn *orig_insn)
{
  int i;
  IStack istack;		/* put instructions into here */
  symbolS *lit_sym = NULL;
  symbolS *label_sym = NULL;

  istack_init (&istack);

  /* Special-case for "movi aX, foo" which is guaranteed to need relaxing.
     Because the scheduling and bundling characteristics of movi and
     l32r or const16 are so different, we can do much better if we relax
     it prior to scheduling and bundling, rather than after.  */
  if ((orig_insn->opcode == xtensa_movi_opcode
       || orig_insn->opcode == xtensa_movi_n_opcode)
      && !cur_vinsn.inside_bundle
      && (orig_insn->tok[1].X_op == O_symbol
	  || orig_insn->tok[1].X_op == O_pltrel
	  || orig_insn->tok[1].X_op == O_tlsfunc
	  || orig_insn->tok[1].X_op == O_tlsarg
	  || orig_insn->tok[1].X_op == O_tpoff
	  || orig_insn->tok[1].X_op == O_dtpoff)
      && !orig_insn->is_specific_opcode && use_transform ())
    xg_assembly_relax (&istack, orig_insn, now_seg, frag_now, 0, 1, 0);
  else
    if (xg_expand_assembly_insn (&istack, orig_insn))
      return TRUE;

  for (i = 0; i < istack.ninsn; i++)
    {
      TInsn *insn = &istack.insn[i];
      switch (insn->insn_type)
	{
	case ITYPE_LITERAL:
	  gas_assert (lit_sym == NULL);
	  lit_sym = xg_assemble_literal (insn);
	  break;
	case ITYPE_LABEL:
	  {
	    static int relaxed_sym_idx = 0;
	    char *label = XNEWVEC (char, strlen (FAKE_LABEL_NAME) + 12);
	    sprintf (label, "%s_rl_%x", FAKE_LABEL_NAME, relaxed_sym_idx++);
	    colon (label);
	    gas_assert (label_sym == NULL);
	    label_sym = symbol_find_or_make (label);
	    gas_assert (label_sym);
	    free (label);
	  }
	  break;
	case ITYPE_INSN:
	  {
	    vliw_insn v;
	    if (lit_sym)
	      xg_resolve_literals (insn, lit_sym);
	    if (label_sym)
	      xg_resolve_labels (insn, label_sym);
	    xg_init_vinsn (&v);
	    bundle_tinsn (insn, &v);
	    finish_vinsn (&v);
	    xg_free_vinsn (&v);
	  }
	  break;
	default:
	  gas_assert (0);
	  break;
	}
    }
  return FALSE;
}


static int
total_frag_text_expansion (fragS *fragP)
{
  int slot;
  int total_expansion = 0;

  for (slot = 0; slot < config_max_slots; slot++)
    total_expansion += fragP->tc_frag_data.text_expansion[slot];

  return total_expansion;
}


/* Emit a vliw instruction to the current fragment.  */

static void
xg_assemble_vliw_tokens (vliw_insn *vinsn)
{
  bfd_boolean finish_frag;
  bfd_boolean is_jump = FALSE;
  bfd_boolean is_branch = FALSE;
  xtensa_isa isa = xtensa_default_isa;
  int insn_size;
  int extra_space;
  char *f = NULL;
  int slot;
  struct dwarf2_line_info debug_line;
  bfd_boolean loc_directive_seen = FALSE;
  TInsn *tinsn;

  memset (&debug_line, 0, sizeof (struct dwarf2_line_info));

  if (generating_literals)
    {
      static int reported = 0;
      if (reported < 4)
	as_bad_where (frag_now->fr_file, frag_now->fr_line,
		      _("cannot assemble into a literal fragment"));
      if (reported == 3)
	as_bad (_("..."));
      reported++;
      return;
    }

  if (frag_now_fix () != 0
      && (! frag_now->tc_frag_data.is_insn
 	  || (vinsn_has_specific_opcodes (vinsn) && use_transform ())
 	  || (!use_transform ()) != frag_now->tc_frag_data.is_no_transform
 	  || (directive_state[directive_longcalls]
	      != frag_now->tc_frag_data.use_longcalls)
 	  || (directive_state[directive_absolute_literals]
	      != frag_now->tc_frag_data.use_absolute_literals)))
    {
      frag_wane (frag_now);
      frag_new (0);
      xtensa_set_frag_assembly_state (frag_now);
    }

  if (workaround_a0_b_retw
      && vinsn->num_slots == 1
      && (get_last_insn_flags (now_seg, now_subseg) & FLAG_IS_A0_WRITER) != 0
      && xtensa_opcode_is_branch (isa, vinsn->slots[0].opcode) == 1
      && use_transform ())
    {
      has_a0_b_retw = TRUE;

      /* Mark this fragment with the special RELAX_ADD_NOP_IF_A0_B_RETW.
	 After the first assembly pass we will check all of them and
	 add a nop if needed.  */
      frag_now->tc_frag_data.is_insn = TRUE;
      frag_var (rs_machine_dependent, 4, 4,
		RELAX_ADD_NOP_IF_A0_B_RETW,
		frag_now->fr_symbol,
		frag_now->fr_offset,
		NULL);
      xtensa_set_frag_assembly_state (frag_now);
      frag_now->tc_frag_data.is_insn = TRUE;
      frag_var (rs_machine_dependent, 4, 4,
		RELAX_ADD_NOP_IF_A0_B_RETW,
		frag_now->fr_symbol,
		frag_now->fr_offset,
		NULL);
      xtensa_set_frag_assembly_state (frag_now);
    }

  for (slot = 0; slot < vinsn->num_slots; slot++)
    {
      tinsn = &vinsn->slots[slot];

      /* See if the instruction implies an aligned section.  */
      if (xtensa_opcode_is_loop (isa, tinsn->opcode) == 1)
	record_alignment (now_seg, 2);

      /* Determine the best line number for debug info.  */
      if ((tinsn->loc_directive_seen || !loc_directive_seen)
	  && (tinsn->debug_line.filenum != debug_line.filenum
	      || tinsn->debug_line.line < debug_line.line
	      || tinsn->debug_line.column < debug_line.column))
	debug_line = tinsn->debug_line;
      if (tinsn->loc_directive_seen)
	loc_directive_seen = TRUE;
    }

  /* Special cases for instructions that force an alignment... */
  /* None of these opcodes are bundle-able.  */
  if (xtensa_opcode_is_loop (isa, vinsn->slots[0].opcode) == 1)
    {
      int max_fill;

      /* Remember the symbol that marks the end of the loop in the frag
	 that marks the start of the loop.  This way we can easily find
	 the end of the loop at the beginning, without adding special code
	 to mark the loop instructions themselves.  */
      symbolS *target_sym = NULL;
      if (vinsn->slots[0].tok[1].X_op == O_symbol)
	target_sym = vinsn->slots[0].tok[1].X_add_symbol;

      xtensa_set_frag_assembly_state (frag_now);
      frag_now->tc_frag_data.is_insn = TRUE;

      max_fill = get_text_align_max_fill_size
	(get_text_align_power (xtensa_fetch_width),
	 TRUE, frag_now->tc_frag_data.is_no_density);

      if (use_transform ())
	frag_var (rs_machine_dependent, max_fill, max_fill,
		  RELAX_ALIGN_NEXT_OPCODE, target_sym, 0, NULL);
      else
	frag_var (rs_machine_dependent, 0, 0,
		  RELAX_CHECK_ALIGN_NEXT_OPCODE, target_sym, 0, NULL);
      xtensa_set_frag_assembly_state (frag_now);
    }

  if (vinsn->slots[0].opcode == xtensa_entry_opcode
      && !vinsn->slots[0].is_specific_opcode)
    {
      xtensa_mark_literal_pool_location ();
      xtensa_move_labels (frag_now, 0);
      frag_var (rs_align_test, 1, 1, 0, NULL, 2, NULL);
    }

  if (vinsn->num_slots == 1)
    {
      if (workaround_a0_b_retw && use_transform ())
	set_last_insn_flags (now_seg, now_subseg, FLAG_IS_A0_WRITER,
			     is_register_writer (&vinsn->slots[0], "a", 0));

      set_last_insn_flags (now_seg, now_subseg, FLAG_IS_BAD_LOOPEND,
			   is_bad_loopend_opcode (&vinsn->slots[0]));
    }
  else
    set_last_insn_flags (now_seg, now_subseg, FLAG_IS_BAD_LOOPEND, FALSE);

  insn_size = xtensa_format_length (isa, vinsn->format);

  extra_space = relaxation_requirements (vinsn, &finish_frag);

  /* vinsn_to_insnbuf will produce the error.  */
  if (vinsn->format != XTENSA_UNDEFINED)
    {
      f = frag_more (insn_size + extra_space);
      xtensa_set_frag_assembly_state (frag_now);
      frag_now->tc_frag_data.is_insn = TRUE;
    }

  vinsn_to_insnbuf (vinsn, f, frag_now, FALSE);
  if (vinsn->format == XTENSA_UNDEFINED)
    return;

  xtensa_insnbuf_to_chars (isa, vinsn->insnbuf, (unsigned char *) f, 0);

  if (debug_type == DEBUG_DWARF2 || loc_directive_seen)
    dwarf2_gen_line_info (frag_now_fix () - (insn_size + extra_space),
			  &debug_line);

  for (slot = 0; slot < vinsn->num_slots; slot++)
    {
      tinsn = &vinsn->slots[slot];
      frag_now->tc_frag_data.slot_subtypes[slot] = tinsn->subtype;
      frag_now->tc_frag_data.slot_symbols[slot] = tinsn->symbol;
      frag_now->tc_frag_data.slot_offsets[slot] = tinsn->offset;
      frag_now->tc_frag_data.literal_frags[slot] = tinsn->literal_frag;
      if (tinsn->opcode == xtensa_l32r_opcode)
	{
	  frag_now->tc_frag_data.literal_frags[slot] =
		  tinsn->tok[1].X_add_symbol->sy_frag;
	}
      if (tinsn->literal_space != 0)
	xg_assemble_literal_space (tinsn->literal_space, slot);
      frag_now->tc_frag_data.free_reg[slot] = tinsn->extra_arg;

      if (tinsn->subtype == RELAX_NARROW)
	gas_assert (vinsn->num_slots == 1);
      if (xtensa_opcode_is_jump (isa, tinsn->opcode) == 1)
	is_jump = TRUE;
      if (xtensa_opcode_is_branch (isa, tinsn->opcode) == 1)
	is_branch = TRUE;

      if (tinsn->subtype || tinsn->symbol || tinsn->offset
	  || tinsn->literal_frag || is_jump || is_branch)
	finish_frag = TRUE;
    }

  if (vinsn_has_specific_opcodes (vinsn) && use_transform ())
    frag_now->tc_frag_data.is_specific_opcode = TRUE;

  if (finish_frag)
    {
      frag_variant (rs_machine_dependent,
		    extra_space, extra_space, RELAX_SLOTS,
		    frag_now->fr_symbol, frag_now->fr_offset, f);
      xtensa_set_frag_assembly_state (frag_now);
    }

  /* Special cases for loops:
     close_loop_end should be inserted AFTER short_loop.
     Make sure that CLOSE loops are processed BEFORE short_loops
     when converting them.  */

  /* "short_loop": Add a NOP if the loop is < 4 bytes.  */
  if (xtensa_opcode_is_loop (isa, vinsn->slots[0].opcode) == 1
      && !vinsn->slots[0].is_specific_opcode)
    {
      if (workaround_short_loop && use_transform ())
	{
	  maybe_has_short_loop = TRUE;
	  frag_now->tc_frag_data.is_insn = TRUE;
	  frag_var (rs_machine_dependent, 4, 4,
		    RELAX_ADD_NOP_IF_SHORT_LOOP,
		    frag_now->fr_symbol, frag_now->fr_offset, NULL);
	  frag_now->tc_frag_data.is_insn = TRUE;
	  frag_var (rs_machine_dependent, 4, 4,
		    RELAX_ADD_NOP_IF_SHORT_LOOP,
		    frag_now->fr_symbol, frag_now->fr_offset, NULL);
	}

      /* "close_loop_end": Add up to 12 bytes of NOPs to keep a
	 loop at least 12 bytes away from another loop's end.  */
      if (workaround_close_loop_end && use_transform ())
	{
	  maybe_has_close_loop_end = TRUE;
	  frag_now->tc_frag_data.is_insn = TRUE;
	  frag_var (rs_machine_dependent, 12, 12,
		    RELAX_ADD_NOP_IF_CLOSE_LOOP_END,
		    frag_now->fr_symbol, frag_now->fr_offset, NULL);
	}
    }

  if (use_transform ())
    {
      if (is_jump)
	{
	  gas_assert (finish_frag);
	  frag_var (rs_machine_dependent,
		    xtensa_fetch_width, xtensa_fetch_width,
		    RELAX_UNREACHABLE,
		    frag_now->fr_symbol, frag_now->fr_offset, NULL);
	  xtensa_set_frag_assembly_state (frag_now);
	  xtensa_maybe_create_trampoline_frag ();
	  /* Always create one here.  */
	  xtensa_maybe_create_literal_pool_frag (TRUE, FALSE);
	}
      else if (is_branch && do_align_targets ())
	{
	  gas_assert (finish_frag);
	  frag_var (rs_machine_dependent,
		    xtensa_fetch_width, xtensa_fetch_width,
		    RELAX_MAYBE_UNREACHABLE,
		    frag_now->fr_symbol, frag_now->fr_offset, NULL);
	  xtensa_set_frag_assembly_state (frag_now);
	  frag_var (rs_machine_dependent,
		    0, 0,
		    RELAX_MAYBE_DESIRE_ALIGN,
		    frag_now->fr_symbol, frag_now->fr_offset, NULL);
	  xtensa_set_frag_assembly_state (frag_now);
	}
    }

  /* Now, if the original opcode was a call...  */
  if (do_align_targets ()
      && xtensa_opcode_is_call (isa, vinsn->slots[0].opcode) == 1)
    {
      float freq = get_subseg_total_freq (now_seg, now_subseg);
      frag_now->tc_frag_data.is_insn = TRUE;
      frag_var (rs_machine_dependent, 4, (int) freq, RELAX_DESIRE_ALIGN,
		frag_now->fr_symbol, frag_now->fr_offset, NULL);
      xtensa_set_frag_assembly_state (frag_now);
    }

  if (vinsn_has_specific_opcodes (vinsn) && use_transform ())
    {
      frag_wane (frag_now);
      frag_new (0);
      xtensa_set_frag_assembly_state (frag_now);
    }
}


/* xtensa_end and helper functions.  */

static void xtensa_cleanup_align_frags (void);
static void xtensa_fix_target_frags (void);
static void xtensa_mark_narrow_branches (void);
static void xtensa_mark_zcl_first_insns (void);
static void xtensa_mark_difference_of_two_symbols (void);
static void xtensa_fix_a0_b_retw_frags (void);
static void xtensa_fix_b_j_loop_end_frags (void);
static void xtensa_fix_close_loop_end_frags (void);
static void xtensa_fix_short_loop_frags (void);
static void xtensa_sanity_check (void);
static void xtensa_add_config_info (void);

void
xtensa_end (void)
{
  directive_balance ();
  xtensa_flush_pending_output ();

  past_xtensa_end = TRUE;

  xtensa_move_literals ();

  xtensa_reorder_segments ();
  xtensa_cleanup_align_frags ();
  xtensa_fix_target_frags ();
  if (workaround_a0_b_retw && has_a0_b_retw)
    xtensa_fix_a0_b_retw_frags ();
  if (workaround_b_j_loop_end)
    xtensa_fix_b_j_loop_end_frags ();

  /* "close_loop_end" should be processed BEFORE "short_loop".  */
  if (workaround_close_loop_end && maybe_has_close_loop_end)
    xtensa_fix_close_loop_end_frags ();

  if (workaround_short_loop && maybe_has_short_loop)
    xtensa_fix_short_loop_frags ();
  if (align_targets)
    xtensa_mark_narrow_branches ();
  xtensa_mark_zcl_first_insns ();

  xtensa_sanity_check ();

  xtensa_add_config_info ();

  xtensa_check_frag_count ();
}


struct trampoline_frag
{
  struct trampoline_frag *next;
  bfd_boolean needs_jump_around;
  fragS *fragP;
  fixS *fixP;
};

struct trampoline_seg
{
  struct trampoline_seg *next;
  asection *seg;
  struct trampoline_frag trampoline_list;
};

static struct trampoline_seg trampoline_seg_list;
#define J_RANGE (128 * 1024)

static int unreachable_count = 0;


static void
xtensa_maybe_create_trampoline_frag (void)
{
  if (!use_trampolines)
    return;

  /* We create an area for possible trampolines every 10 unreachable frags.
     These are preferred over the ones not preceded by an unreachable frag,
     because we don't have to jump around them. This function is called after
     each RELAX_UNREACHABLE frag is created.  */

  if (++unreachable_count > 10)
    {
      xtensa_create_trampoline_frag (FALSE);
      clear_frag_count ();
      unreachable_count = 0;
    }
}

static void
xtensa_check_frag_count (void)
{
  if (!use_trampolines || frag_now->tc_frag_data.is_no_transform)
    return;

  /* We create an area for possible trampolines every 8000 frags or so. This
     is an estimate based on the max range of a "j" insn (+/-128K) divided
     by a typical frag byte count (16), minus a few for safety. This function
     is called after each source line is processed.  */

  if (get_frag_count () > 8000)
    {
      xtensa_create_trampoline_frag (TRUE);
      clear_frag_count ();
      unreachable_count = 0;
    }

  /* We create an area for a possible literal pool every N (default 5000)
     frags or so.  */
  xtensa_maybe_create_literal_pool_frag (TRUE, TRUE);
}

static xtensa_insnbuf trampoline_buf = NULL;
static xtensa_insnbuf trampoline_slotbuf = NULL;

static xtensa_insnbuf litpool_buf = NULL;
static xtensa_insnbuf litpool_slotbuf = NULL;

#define TRAMPOLINE_FRAG_SIZE 3000

static void
xtensa_create_trampoline_frag (bfd_boolean needs_jump_around)
{
  /* Emit a frag where we can place intermediate jump instructions,
     in case we need to jump farther than 128K bytes.
     Each jump instruction takes three bytes.
     We allocate enough for 1000 trampolines in each frag.
     If that's not enough, oh well.  */

  struct trampoline_seg *ts = trampoline_seg_list.next;
  struct trampoline_frag *tf;
  char *varP;
  fragS *fragP;
  int size = TRAMPOLINE_FRAG_SIZE;

  for ( ; ts; ts = ts->next)
    {
      if (ts->seg == now_seg)
	break;
    }

  if (ts == NULL)
    {
      ts = XCNEW(struct trampoline_seg);
      ts->next = trampoline_seg_list.next;
      trampoline_seg_list.next = ts;
      ts->seg = now_seg;
    }

  frag_wane (frag_now);
  frag_new (0);
  xtensa_set_frag_assembly_state (frag_now);
  varP = frag_var (rs_machine_dependent, size, size, RELAX_TRAMPOLINE, NULL, 0, NULL);
  fragP = (fragS *)(varP - SIZEOF_STRUCT_FRAG);
  if (trampoline_buf == NULL)
    {
      trampoline_buf = xtensa_insnbuf_alloc (xtensa_default_isa);
      trampoline_slotbuf = xtensa_insnbuf_alloc (xtensa_default_isa);
    }
  tf = XNEW (struct trampoline_frag);
  tf->next = ts->trampoline_list.next;
  ts->trampoline_list.next = tf;
  tf->needs_jump_around = needs_jump_around;
  tf->fragP = fragP;
  tf->fixP = NULL;
}


static struct trampoline_seg *
find_trampoline_seg (asection *seg)
{
  struct trampoline_seg *ts = trampoline_seg_list.next;

  for ( ; ts; ts = ts->next)
    {
      if (ts->seg == seg)
	return ts;
    }

  return NULL;
}


void dump_trampolines (void);

void
dump_trampolines (void)
{
  struct trampoline_seg *ts = trampoline_seg_list.next;

  for ( ; ts; ts = ts->next)
    {
      asection *seg = ts->seg;

      if (seg == NULL)
	continue;
      fprintf(stderr, "SECTION %s\n", seg->name);
      struct trampoline_frag *tf = ts->trampoline_list.next;
      for ( ; tf; tf = tf->next)
	{
	  if (tf->fragP == NULL)
	    continue;
	  fprintf(stderr, "   0x%08x: fix=%d, jump_around=%s\n",
		  (int)tf->fragP->fr_address, (int)tf->fragP->fr_fix,
		  tf->needs_jump_around ? "T" : "F");
	}
    }
}

static void dump_litpools (void) __attribute__ ((unused));

static void
dump_litpools (void)
{
  struct litpool_seg *lps = litpool_seg_list.next;
  struct litpool_frag *lpf;

  for ( ; lps ; lps = lps->next )
    {
      printf("litpool seg %s\n", lps->seg->name);
      for ( lpf = lps->frag_list.next; lpf->fragP; lpf = lpf->next )
	{
	  fragS *litfrag = lpf->fragP->fr_next;
	  int count = 0;
	  while (litfrag && litfrag->fr_subtype != RELAX_LITERAL_POOL_END)
	    {
	      if (litfrag->fr_fix == 4)
		count++;
	      litfrag = litfrag->fr_next;
	    }
	  printf("   %ld <%d:%d> (%d) [%d]: ",
		 lpf->addr, lpf->priority, lpf->original_priority,
		 lpf->fragP->fr_line, count);
	  //dump_frag(lpf->fragP);
	}
    }
}

static void
xtensa_maybe_create_literal_pool_frag (bfd_boolean create,
				       bfd_boolean only_if_needed)
{
  struct litpool_seg *lps = litpool_seg_list.next;
  fragS *fragP;
  struct litpool_frag *lpf;
  bfd_boolean needed = FALSE;

  if (use_literal_section || !auto_litpools)
    return;

  for ( ; lps ; lps = lps->next )
    {
      if (lps->seg == now_seg)
	break;
    }

  if (lps == NULL)
    {
      lps = XCNEW (struct litpool_seg);
      lps->next = litpool_seg_list.next;
      litpool_seg_list.next = lps;
      lps->seg = now_seg;
      lps->frag_list.next = &lps->frag_list;
      lps->frag_list.prev = &lps->frag_list;
    }

  lps->frag_count++;

  if (create)
    {
      if (only_if_needed)
	{
	  if (past_xtensa_end || !use_transform() ||
	      frag_now->tc_frag_data.is_no_transform)
	    {
	      return;
	    }
	  if (auto_litpool_limit <= 0)
	    {
	      /* Don't create a litpool based only on frag count.  */
	      return;
	    }
	  else if (lps->frag_count > auto_litpool_limit)
	    {
	      needed = TRUE;
	    }
	  else
	    {
	      return;
	    }
	}
      else
	{
	  needed = TRUE;
	}
    }

  if (needed)
    {
      int size = (only_if_needed) ? 3 : 0; /* Space for a "j" insn.  */
      /* Create a potential site for a literal pool.  */
      frag_wane (frag_now);
      frag_new (0);
      xtensa_set_frag_assembly_state (frag_now);
      fragP = frag_now;
      fragP->tc_frag_data.lit_frchain = frchain_now;
      fragP->tc_frag_data.literal_frag = fragP;
      frag_var (rs_machine_dependent, size, size,
		    (only_if_needed) ?
		        RELAX_LITERAL_POOL_CANDIDATE_BEGIN :
		        RELAX_LITERAL_POOL_BEGIN,
		    NULL, 0, NULL);
      frag_now->tc_frag_data.lit_seg = now_seg;
      frag_variant (rs_machine_dependent, 0, 0,
		    RELAX_LITERAL_POOL_END, NULL, 0, NULL);
      xtensa_set_frag_assembly_state (frag_now);
    }
  else
    {
      /* RELAX_LITERAL_POOL_BEGIN frag is being created;
	 just record it here.  */
      fragP = frag_now;
    }

  lpf = XNEW (struct litpool_frag);
  /* Insert at tail of circular list.  */
  lpf->addr = 0;
  lps->frag_list.prev->next = lpf;
  lpf->next = &lps->frag_list;
  lpf->prev = lps->frag_list.prev;
  lps->frag_list.prev = lpf;
  lpf->fragP = fragP;
  lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1;
  lpf->original_priority = lpf->priority;

  lps->frag_count = 0;
}

static void
xtensa_cleanup_align_frags (void)
{
  frchainS *frchP;
  asection *s;

  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;
	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if ((fragP->fr_type == rs_align
		 || fragP->fr_type == rs_align_code
		 || (fragP->fr_type == rs_machine_dependent
		     && (fragP->fr_subtype == RELAX_DESIRE_ALIGN
			 || fragP->fr_subtype == RELAX_DESIRE_ALIGN_IF_TARGET)))
		&& fragP->fr_fix == 0)
	      {
		fragS *next = fragP->fr_next;

		while (next
		       && next->fr_fix == 0
		       && next->fr_type == rs_machine_dependent
		       && next->fr_subtype == RELAX_DESIRE_ALIGN_IF_TARGET)
		  {
		    frag_wane (next);
		    next = next->fr_next;
		  }
	      }
	    /* If we don't widen branch targets, then they
	       will be easier to align.  */
	    if (fragP->tc_frag_data.is_branch_target
		&& fragP->fr_opcode == fragP->fr_literal
		&& fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_SLOTS
		&& fragP->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
	      frag_wane (fragP);
	    if (fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_UNREACHABLE)
	      fragP->tc_frag_data.is_unreachable = TRUE;
	  }
      }
}


/* Re-process all of the fragments looking to convert all of the
   RELAX_DESIRE_ALIGN_IF_TARGET fragments.  If there is a branch
   target in the next fragment, convert this to RELAX_DESIRE_ALIGN.
   Otherwise, convert to a .fill 0.  */

static void
xtensa_fix_target_frags (void)
{
  frchainS *frchP;
  asection *s;

  /* When this routine is called, all of the subsections are still intact
     so we walk over subsections instead of sections.  */
  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;

	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if (fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_DESIRE_ALIGN_IF_TARGET)
	      {
		if (next_frag_is_branch_target (fragP))
		  fragP->fr_subtype = RELAX_DESIRE_ALIGN;
		else
		  frag_wane (fragP);
	      }
	  }
      }
}


static bfd_boolean is_narrow_branch_guaranteed_in_range (fragS *, TInsn *);

static void
xtensa_mark_narrow_branches (void)
{
  frchainS *frchP;
  asection *s;

  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;
	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if (fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_SLOTS
		&& fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED)
	      {
		vliw_insn vinsn;

		vinsn_from_chars (&vinsn, fragP->fr_opcode);
		tinsn_immed_from_frag (&vinsn.slots[0], fragP, 0);

		if (vinsn.num_slots == 1
		    && xtensa_opcode_is_branch (xtensa_default_isa,
						vinsn.slots[0].opcode) == 1
		    && xg_get_single_size (vinsn.slots[0].opcode) == 2
		    && is_narrow_branch_guaranteed_in_range (fragP,
							     &vinsn.slots[0]))
		  {
		    fragP->fr_subtype = RELAX_SLOTS;
		    fragP->tc_frag_data.slot_subtypes[0] = RELAX_NARROW;
		    fragP->tc_frag_data.is_aligning_branch = 1;
		  }
	      }
	  }
      }
}


/* A branch is typically widened only when its target is out of
   range.  However, we would like to widen them to align a subsequent
   branch target when possible.

   Because the branch relaxation code is so convoluted, the optimal solution
   (combining the two cases) is difficult to get right in all circumstances.
   We therefore go with an "almost as good" solution, where we only
   use for alignment narrow branches that definitely will not expand to a
   jump and a branch.  These functions find and mark these cases.  */

/* The range in bytes of BNEZ.N and BEQZ.N.  The target operand is encoded
   as PC + 4 + imm6, where imm6 is a 6-bit immediate ranging from 0 to 63.
   We start counting beginning with the frag after the 2-byte branch, so the
   maximum offset is (4 - 2) + 63 = 65.  */
#define MAX_IMMED6 65

static offsetT unrelaxed_frag_max_size (fragS *);

static bfd_boolean
is_narrow_branch_guaranteed_in_range (fragS *fragP, TInsn *tinsn)
{
  const expressionS *exp = &tinsn->tok[1];
  symbolS *symbolP = exp->X_add_symbol;
  offsetT max_distance = exp->X_add_number;
  fragS *target_frag;

  if (exp->X_op != O_symbol)
    return FALSE;

  target_frag = symbol_get_frag (symbolP);

  max_distance += (S_GET_VALUE (symbolP) - target_frag->fr_address);
  if (is_branch_jmp_to_next (tinsn, fragP))
    return FALSE;

  /* The branch doesn't branch over it's own frag,
     but over the subsequent ones.  */
  fragP = fragP->fr_next;
  while (fragP != NULL && fragP != target_frag && max_distance <= MAX_IMMED6)
    {
      max_distance += unrelaxed_frag_max_size (fragP);
      fragP = fragP->fr_next;
    }
  if (max_distance <= MAX_IMMED6 && fragP == target_frag)
    return TRUE;
  return FALSE;
}


static void
xtensa_mark_zcl_first_insns (void)
{
  frchainS *frchP;
  asection *s;

  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;
	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if (fragP->fr_type == rs_machine_dependent
		&& (fragP->fr_subtype == RELAX_ALIGN_NEXT_OPCODE
		    || fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE))
	      {
		/* Find the loop frag.  */
		fragS *loop_frag = next_non_empty_frag (fragP);
		/* Find the first insn frag.  */
		fragS *targ_frag = next_non_empty_frag (loop_frag);

	      /* Handle a corner case that comes up in hardware
		 diagnostics.  The original assembly looks like this:

		 loop aX, LabelA
		 <empty_frag>--not found by next_non_empty_frag
		 loop aY, LabelB

		 Depending on the start address, the assembler may or
		 may not change it to look something like this:

		 loop aX, LabelA
		 nop--frag isn't empty anymore
		 loop aY, LabelB

		 So set up to check the alignment of the nop if it
		 exists  */
		while (loop_frag != targ_frag)
		  {
		    if (loop_frag->fr_type == rs_machine_dependent
			&& (loop_frag->fr_subtype == RELAX_ALIGN_NEXT_OPCODE
			    || loop_frag->fr_subtype
			    == RELAX_CHECK_ALIGN_NEXT_OPCODE))
		      targ_frag = loop_frag;
		    else
		      loop_frag = loop_frag->fr_next;
		  }

		/* Of course, sometimes (mostly for toy test cases) a
		   zero-cost loop instruction is the last in a section.  */
		if (targ_frag)
		  {
		    targ_frag->tc_frag_data.is_first_loop_insn = TRUE;
		    /* Do not widen a frag that is the first instruction of a
		       zero-cost loop.  It makes that loop harder to align.  */
		    if (targ_frag->fr_type == rs_machine_dependent
			&& targ_frag->fr_subtype == RELAX_SLOTS
			&& (targ_frag->tc_frag_data.slot_subtypes[0]
			    == RELAX_NARROW))
		      {
			if (targ_frag->tc_frag_data.is_aligning_branch)
			  targ_frag->tc_frag_data.slot_subtypes[0] = RELAX_IMMED;
			else
			  {
			    frag_wane (targ_frag);
			    targ_frag->tc_frag_data.slot_subtypes[0] = 0;
			  }
		      }
		  }
		if (fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE)
		  frag_wane (fragP);
	      }
	  }
      }
}


/* When a difference-of-symbols expression is encoded as a uleb128 or
   sleb128 value, the linker is unable to adjust that value to account for
   link-time relaxation.  Mark all the code between such symbols so that
   its size cannot be changed by linker relaxation.  */

static void
xtensa_mark_difference_of_two_symbols (void)
{
  symbolS *expr_sym;

  for (expr_sym = expr_symbols; expr_sym;
       expr_sym = symbol_get_tc (expr_sym)->next_expr_symbol)
    {
      expressionS *exp = symbol_get_value_expression (expr_sym);

      if (exp->X_op == O_subtract)
	{
	  symbolS *left = exp->X_add_symbol;
	  symbolS *right = exp->X_op_symbol;

	  /* Difference of two symbols not in the same section
	     are handled with relocations in the linker.  */
	  if (S_GET_SEGMENT (left) == S_GET_SEGMENT (right))
	    {
	      fragS *start;
	      fragS *end;
	      fragS *walk;

	      if (symbol_get_frag (left)->fr_address
		  <= symbol_get_frag (right)->fr_address)
		{
		  start = symbol_get_frag (left);
		  end = symbol_get_frag (right);
		}
	      else
		{
		  start = symbol_get_frag (right);
		  end = symbol_get_frag (left);
		}

	      if (start->tc_frag_data.no_transform_end != NULL)
		walk = start->tc_frag_data.no_transform_end;
	      else
		walk = start;
	      do
		{
		  walk->tc_frag_data.is_no_transform = 1;
		  walk = walk->fr_next;
		}
	      while (walk && walk->fr_address < end->fr_address);

	      start->tc_frag_data.no_transform_end = walk;
	    }
	}
    }
}


/* Re-process all of the fragments looking to convert all of the
   RELAX_ADD_NOP_IF_A0_B_RETW.  If the next instruction is a
   conditional branch or a retw/retw.n, convert this frag to one that
   will generate a NOP.  In any case close it off with a .fill 0.  */

static bfd_boolean next_instrs_are_b_retw (fragS *);

static void
xtensa_fix_a0_b_retw_frags (void)
{
  frchainS *frchP;
  asection *s;

  /* When this routine is called, all of the subsections are still intact
     so we walk over subsections instead of sections.  */
  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;

	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if (fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_ADD_NOP_IF_A0_B_RETW)
	      {
		if (next_instrs_are_b_retw (fragP))
		  {
		    if (fragP->tc_frag_data.is_no_transform)
		      as_bad (_("instruction sequence (write a0, branch, retw) may trigger hardware errata"));
		    else
		      relax_frag_add_nop (fragP);
		  }
		frag_wane (fragP);
	      }
	  }
      }
}


static bfd_boolean
next_instrs_are_b_retw (fragS *fragP)
{
  xtensa_opcode opcode;
  xtensa_format fmt;
  const fragS *next_fragP = next_non_empty_frag (fragP);
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  xtensa_isa isa = xtensa_default_isa;
  int offset = 0;
  int slot;
  bfd_boolean branch_seen = FALSE;

  if (!insnbuf)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  if (next_fragP == NULL)
    return FALSE;

  /* Check for the conditional branch.  */
  xtensa_insnbuf_from_chars
    (isa, insnbuf, (unsigned char *) &next_fragP->fr_literal[offset], 0);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED)
    return FALSE;

  for (slot = 0; slot < xtensa_format_num_slots (isa, fmt); slot++)
    {
      xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
      opcode = xtensa_opcode_decode (isa, fmt, slot, slotbuf);

      branch_seen = (branch_seen
		     || xtensa_opcode_is_branch (isa, opcode) == 1);
    }

  if (!branch_seen)
    return FALSE;

  offset += xtensa_format_length (isa, fmt);
  if (offset == next_fragP->fr_fix)
    {
      next_fragP = next_non_empty_frag (next_fragP);
      offset = 0;
    }

  if (next_fragP == NULL)
    return FALSE;

  /* Check for the retw/retw.n.  */
  xtensa_insnbuf_from_chars
    (isa, insnbuf, (unsigned char *) &next_fragP->fr_literal[offset], 0);
  fmt = xtensa_format_decode (isa, insnbuf);

  /* Because RETW[.N] is not bundleable, a VLIW bundle here means that we
     have no problems.  */
  if (fmt == XTENSA_UNDEFINED
      || xtensa_format_num_slots (isa, fmt) != 1)
    return FALSE;

  xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf);
  opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);

  if (opcode == xtensa_retw_opcode || opcode == xtensa_retw_n_opcode)
    return TRUE;

  return FALSE;
}


/* Re-process all of the fragments looking to convert all of the
   RELAX_ADD_NOP_IF_PRE_LOOP_END.  If there is one instruction and a
   loop end label, convert this frag to one that will generate a NOP.
   In any case close it off with a .fill 0.  */

static bfd_boolean next_instr_is_loop_end (fragS *);

static void
xtensa_fix_b_j_loop_end_frags (void)
{
  frchainS *frchP;
  asection *s;

  /* When this routine is called, all of the subsections are still intact
     so we walk over subsections instead of sections.  */
  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;

	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if (fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_ADD_NOP_IF_PRE_LOOP_END)
	      {
		if (next_instr_is_loop_end (fragP))
		  {
		    if (fragP->tc_frag_data.is_no_transform)
		      as_bad (_("branching or jumping to a loop end may trigger hardware errata"));
		    else
		      relax_frag_add_nop (fragP);
		  }
		frag_wane (fragP);
	      }
	  }
      }
}


static bfd_boolean
next_instr_is_loop_end (fragS *fragP)
{
  const fragS *next_fragP;

  if (next_frag_is_loop_target (fragP))
    return FALSE;

  next_fragP = next_non_empty_frag (fragP);
  if (next_fragP == NULL)
    return FALSE;

  if (!next_frag_is_loop_target (next_fragP))
    return FALSE;

  /* If the size is >= 3 then there is more than one instruction here.
     The hardware bug will not fire.  */
  if (next_fragP->fr_fix > 3)
    return FALSE;

  return TRUE;
}


/* Re-process all of the fragments looking to convert all of the
   RELAX_ADD_NOP_IF_CLOSE_LOOP_END.  If there is an loop end that is
   not MY loop's loop end within 12 bytes, add enough nops here to
   make it at least 12 bytes away.  In any case close it off with a
   .fill 0.  */

static offsetT min_bytes_to_other_loop_end
  (fragS *, fragS *, offsetT);

static void
xtensa_fix_close_loop_end_frags (void)
{
  frchainS *frchP;
  asection *s;

  /* When this routine is called, all of the subsections are still intact
     so we walk over subsections instead of sections.  */
  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;

	fragS *current_target = NULL;

	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if (fragP->fr_type == rs_machine_dependent
		&& ((fragP->fr_subtype == RELAX_ALIGN_NEXT_OPCODE)
		    || (fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE)))
	      current_target = symbol_get_frag (fragP->fr_symbol);

	    if (current_target
		&& fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_ADD_NOP_IF_CLOSE_LOOP_END)
	      {
		offsetT min_bytes;
		int bytes_added = 0;

#define REQUIRED_LOOP_DIVIDING_BYTES 12
		/* Max out at 12.  */
		min_bytes = min_bytes_to_other_loop_end
		  (fragP->fr_next, current_target, REQUIRED_LOOP_DIVIDING_BYTES);

		if (min_bytes < REQUIRED_LOOP_DIVIDING_BYTES)
		  {
		    if (fragP->tc_frag_data.is_no_transform)
		      as_bad (_("loop end too close to another loop end may trigger hardware errata"));
		    else
		      {
			while (min_bytes + bytes_added
			       < REQUIRED_LOOP_DIVIDING_BYTES)
			  {
			    int length = 3;

			    if (fragP->fr_var < length)
			      as_fatal (_("fr_var %lu < length %d"),
					(long) fragP->fr_var, length);
			    else
			      {
				assemble_nop (length,
					      fragP->fr_literal + fragP->fr_fix);
				fragP->fr_fix += length;
				fragP->fr_var -= length;
			      }
			    bytes_added += length;
			  }
		      }
		  }
		frag_wane (fragP);
	      }
	    gas_assert (fragP->fr_type != rs_machine_dependent
		    || fragP->fr_subtype != RELAX_ADD_NOP_IF_CLOSE_LOOP_END);
	  }
      }
}


static offsetT unrelaxed_frag_min_size (fragS *);

static offsetT
min_bytes_to_other_loop_end (fragS *fragP,
			     fragS *current_target,
			     offsetT max_size)
{
  offsetT offset = 0;
  fragS *current_fragP;

  for (current_fragP = fragP;
       current_fragP;
       current_fragP = current_fragP->fr_next)
    {
      if (current_fragP->tc_frag_data.is_loop_target
	  && current_fragP != current_target)
	return offset;

      offset += unrelaxed_frag_min_size (current_fragP);

      if (offset >= max_size)
	return max_size;
    }
  return max_size;
}


static offsetT
unrelaxed_frag_min_size (fragS *fragP)
{
  offsetT size = fragP->fr_fix;

  /* Add fill size.  */
  if (fragP->fr_type == rs_fill)
    size += fragP->fr_offset;

  return size;
}


static offsetT
unrelaxed_frag_max_size (fragS *fragP)
{
  offsetT size = fragP->fr_fix;
  switch (fragP->fr_type)
    {
    case 0:
      /* Empty frags created by the obstack allocation scheme
	 end up with type 0.  */
      break;
    case rs_fill:
    case rs_org:
    case rs_space:
      size += fragP->fr_offset;
      break;
    case rs_align:
    case rs_align_code:
    case rs_align_test:
    case rs_leb128:
    case rs_cfa:
    case rs_dwarf2dbg:
      /* No further adjustments needed.  */
      break;
    case rs_machine_dependent:
      if (fragP->fr_subtype != RELAX_DESIRE_ALIGN)
	size += fragP->fr_var;
      break;
    default:
      /* We had darn well better know how big it is.  */
      gas_assert (0);
      break;
    }

  return size;
}


/* Re-process all of the fragments looking to convert all
   of the RELAX_ADD_NOP_IF_SHORT_LOOP.  If:

   A)
     1) the instruction size count to the loop end label
        is too short (<= 2 instructions),
     2) loop has a jump or branch in it

   or B)
     1) workaround_all_short_loops is TRUE
     2) The generating loop was a  'loopgtz' or 'loopnez'
     3) the instruction size count to the loop end label is too short
        (<= 2 instructions)
   then convert this frag (and maybe the next one) to generate a NOP.
   In any case close it off with a .fill 0.  */

static int count_insns_to_loop_end (fragS *, bfd_boolean, int);
static bfd_boolean branch_before_loop_end (fragS *);

static void
xtensa_fix_short_loop_frags (void)
{
  frchainS *frchP;
  asection *s;

  /* When this routine is called, all of the subsections are still intact
     so we walk over subsections instead of sections.  */
  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;
	xtensa_opcode current_opcode = XTENSA_UNDEFINED;

	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if (fragP->fr_type == rs_machine_dependent
		&& ((fragP->fr_subtype == RELAX_ALIGN_NEXT_OPCODE)
		    || (fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE)))
	      {
		TInsn t_insn;
		fragS *loop_frag = next_non_empty_frag (fragP);
		tinsn_from_chars (&t_insn, loop_frag->fr_opcode, 0);
		current_opcode = t_insn.opcode;
		gas_assert (xtensa_opcode_is_loop (xtensa_default_isa,
					       current_opcode) == 1);
	      }

	    if (fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_ADD_NOP_IF_SHORT_LOOP)
	      {
		if (count_insns_to_loop_end (fragP->fr_next, TRUE, 3) < 3
		    && (branch_before_loop_end (fragP->fr_next)
			|| (workaround_all_short_loops
			    && current_opcode != XTENSA_UNDEFINED
			    && current_opcode != xtensa_loop_opcode)))
		  {
		    if (fragP->tc_frag_data.is_no_transform)
		      as_bad (_("loop containing less than three instructions may trigger hardware errata"));
		    else
		      relax_frag_add_nop (fragP);
		  }
		frag_wane (fragP);
	      }
	  }
      }
}


static int unrelaxed_frag_min_insn_count (fragS *);

static int
count_insns_to_loop_end (fragS *base_fragP,
			 bfd_boolean count_relax_add,
			 int max_count)
{
  fragS *fragP = NULL;
  int insn_count = 0;

  fragP = base_fragP;

  for (; fragP && !fragP->tc_frag_data.is_loop_target; fragP = fragP->fr_next)
    {
      insn_count += unrelaxed_frag_min_insn_count (fragP);
      if (insn_count >= max_count)
	return max_count;

      if (count_relax_add)
	{
	  if (fragP->fr_type == rs_machine_dependent
	      && fragP->fr_subtype == RELAX_ADD_NOP_IF_SHORT_LOOP)
	    {
	      /* In order to add the appropriate number of
	         NOPs, we count an instruction for downstream
	         occurrences.  */
	      insn_count++;
	      if (insn_count >= max_count)
		return max_count;
	    }
	}
    }
  return insn_count;
}


static int
unrelaxed_frag_min_insn_count (fragS *fragP)
{
  xtensa_isa isa = xtensa_default_isa;
  static xtensa_insnbuf insnbuf = NULL;
  int insn_count = 0;
  int offset = 0;

  if (!fragP->tc_frag_data.is_insn)
    return insn_count;

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (isa);

  /* Decode the fixed instructions.  */
  while (offset < fragP->fr_fix)
    {
      xtensa_format fmt;

      xtensa_insnbuf_from_chars
	(isa, insnbuf, (unsigned char *) fragP->fr_literal + offset, 0);
      fmt = xtensa_format_decode (isa, insnbuf);

      if (fmt == XTENSA_UNDEFINED)
	{
	  as_fatal (_("undecodable instruction in instruction frag"));
	  return insn_count;
	}
      offset += xtensa_format_length (isa, fmt);
      insn_count++;
    }

  return insn_count;
}


static bfd_boolean unrelaxed_frag_has_b_j (fragS *);

static bfd_boolean
branch_before_loop_end (fragS *base_fragP)
{
  fragS *fragP;

  for (fragP = base_fragP;
       fragP && !fragP->tc_frag_data.is_loop_target;
       fragP = fragP->fr_next)
    {
      if (unrelaxed_frag_has_b_j (fragP))
	return TRUE;
    }
  return FALSE;
}


static bfd_boolean
unrelaxed_frag_has_b_j (fragS *fragP)
{
  static xtensa_insnbuf insnbuf = NULL;
  xtensa_isa isa = xtensa_default_isa;
  int offset = 0;

  if (!fragP->tc_frag_data.is_insn)
    return FALSE;

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (isa);

  /* Decode the fixed instructions.  */
  while (offset < fragP->fr_fix)
    {
      xtensa_format fmt;
      int slot;

      xtensa_insnbuf_from_chars
	(isa, insnbuf, (unsigned char *) fragP->fr_literal + offset, 0);
      fmt = xtensa_format_decode (isa, insnbuf);
      if (fmt == XTENSA_UNDEFINED)
	return FALSE;

      for (slot = 0; slot < xtensa_format_num_slots (isa, fmt); slot++)
	{
	  xtensa_opcode opcode =
	    get_opcode_from_buf (fragP->fr_literal + offset, slot);
	  if (xtensa_opcode_is_branch (isa, opcode) == 1
	      || xtensa_opcode_is_jump (isa, opcode) == 1)
	    return TRUE;
	}
      offset += xtensa_format_length (isa, fmt);
    }
  return FALSE;
}


/* Checks to be made after initial assembly but before relaxation.  */

static bfd_boolean is_empty_loop (const TInsn *, fragS *);
static bfd_boolean is_local_forward_loop (const TInsn *, fragS *);

static void
xtensa_sanity_check (void)
{
  const char *file_name;
  unsigned line;
  frchainS *frchP;
  asection *s;

  file_name = as_where (&line);
  for (s = stdoutput->sections; s; s = s->next)
    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
      {
	fragS *fragP;

	/* Walk over all of the fragments in a subsection.  */
	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	  {
	    if (fragP->fr_type == rs_machine_dependent
		&& fragP->fr_subtype == RELAX_SLOTS
		&& fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED)
	      {
		static xtensa_insnbuf insnbuf = NULL;
		TInsn t_insn;

		if (fragP->fr_opcode != NULL)
		  {
		    if (!insnbuf)
		      insnbuf = xtensa_insnbuf_alloc (xtensa_default_isa);
		    tinsn_from_chars (&t_insn, fragP->fr_opcode, 0);
		    tinsn_immed_from_frag (&t_insn, fragP, 0);

		    if (xtensa_opcode_is_loop (xtensa_default_isa,
					       t_insn.opcode) == 1)
		      {
			if (is_empty_loop (&t_insn, fragP))
			  {
			    new_logical_line (fragP->fr_file, fragP->fr_line);
			    as_bad (_("invalid empty loop"));
			  }
			if (!is_local_forward_loop (&t_insn, fragP))
			  {
			    new_logical_line (fragP->fr_file, fragP->fr_line);
			    as_bad (_("loop target does not follow "
				      "loop instruction in section"));
			  }
		      }
		  }
	      }
	  }
      }
  new_logical_line (file_name, line);
}


#define LOOP_IMMED_OPN 1

/* Return TRUE if the loop target is the next non-zero fragment.  */

static bfd_boolean
is_empty_loop (const TInsn *insn, fragS *fragP)
{
  const expressionS *exp;
  symbolS *symbolP;
  fragS *next_fragP;

  if (insn->insn_type != ITYPE_INSN)
    return FALSE;

  if (xtensa_opcode_is_loop (xtensa_default_isa, insn->opcode) != 1)
    return FALSE;

  if (insn->ntok <= LOOP_IMMED_OPN)
    return FALSE;

  exp = &insn->tok[LOOP_IMMED_OPN];

  if (exp->X_op != O_symbol)
    return FALSE;

  symbolP = exp->X_add_symbol;
  if (!symbolP)
    return FALSE;

  if (symbol_get_frag (symbolP) == NULL)
    return FALSE;

  if (S_GET_VALUE (symbolP) != 0)
    return FALSE;

  /* Walk through the zero-size fragments from this one.  If we find
     the target fragment, then this is a zero-size loop.  */

  for (next_fragP = fragP->fr_next;
       next_fragP != NULL;
       next_fragP = next_fragP->fr_next)
    {
      if (next_fragP == symbol_get_frag (symbolP))
	return TRUE;
      if (next_fragP->fr_fix != 0)
	return FALSE;
    }
  return FALSE;
}


static bfd_boolean
is_local_forward_loop (const TInsn *insn, fragS *fragP)
{
  const expressionS *exp;
  symbolS *symbolP;
  fragS *next_fragP;

  if (insn->insn_type != ITYPE_INSN)
    return FALSE;

  if (xtensa_opcode_is_loop (xtensa_default_isa, insn->opcode) != 1)
    return FALSE;

  if (insn->ntok <= LOOP_IMMED_OPN)
    return FALSE;

  exp = &insn->tok[LOOP_IMMED_OPN];

  if (exp->X_op != O_symbol)
    return FALSE;

  symbolP = exp->X_add_symbol;
  if (!symbolP)
    return FALSE;

  if (symbol_get_frag (symbolP) == NULL)
    return FALSE;

  /* Walk through fragments until we find the target.
     If we do not find the target, then this is an invalid loop.  */

  for (next_fragP = fragP->fr_next;
       next_fragP != NULL;
       next_fragP = next_fragP->fr_next)
    {
      if (next_fragP == symbol_get_frag (symbolP))
	return TRUE;
    }

  return FALSE;
}


#define XTINFO_NAME "Xtensa_Info"
#define XTINFO_NAMESZ 12
#define XTINFO_TYPE 1

static void
xtensa_add_config_info (void)
{
  asection *info_sec;
  char *data, *p;
  int sz;

  info_sec = subseg_new (".xtensa.info", 0);
  bfd_set_section_flags (stdoutput, info_sec, SEC_HAS_CONTENTS | SEC_READONLY);

  data = XNEWVEC (char, 100);
  sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n",
	   XSHAL_USE_ABSOLUTE_LITERALS, XSHAL_ABI);
  sz = strlen (data) + 1;

  /* Add enough null terminators to pad to a word boundary.  */
  do
    data[sz++] = 0;
  while ((sz & 3) != 0);

  /* Follow the standard note section layout:
     First write the length of the name string.  */
  p = frag_more (4);
  md_number_to_chars (p, (valueT) XTINFO_NAMESZ, 4);

  /* Next comes the length of the "descriptor", i.e., the actual data.  */
  p = frag_more (4);
  md_number_to_chars (p, (valueT) sz, 4);

  /* Write the note type.  */
  p = frag_more (4);
  md_number_to_chars (p, (valueT) XTINFO_TYPE, 4);

  /* Write the name field.  */
  p = frag_more (XTINFO_NAMESZ);
  memcpy (p, XTINFO_NAME, XTINFO_NAMESZ);

  /* Finally, write the descriptor.  */
  p = frag_more (sz);
  memcpy (p, data, sz);

  free (data);
}


/* Alignment Functions.  */

static int
get_text_align_power (unsigned target_size)
{
  if (target_size <= 4)
    return 2;

  if (target_size <= 8)
    return 3;

  if (target_size <= 16)
    return 4;

  if (target_size <= 32)
    return 5;

  if (target_size <= 64)
    return 6;

  if (target_size <= 128)
    return 7;

  if (target_size <= 256)
    return 8;

  if (target_size <= 512)
    return 9;

  if (target_size <= 1024)
    return 10;

  gas_assert (0);
  return 0;
}


static int
get_text_align_max_fill_size (int align_pow,
			      bfd_boolean use_nops,
			      bfd_boolean use_no_density)
{
  if (!use_nops)
    return (1 << align_pow);
  if (use_no_density)
    return 3 * (1 << align_pow);

  return 1 + (1 << align_pow);
}


/* Calculate the minimum bytes of fill needed at "address" to align a
   target instruction of size "target_size" so that it does not cross a
   power-of-two boundary specified by "align_pow".  If "use_nops" is FALSE,
   the fill can be an arbitrary number of bytes.  Otherwise, the space must
   be filled by NOP instructions.  */

static int
get_text_align_fill_size (addressT address,
			  int align_pow,
			  int target_size,
			  bfd_boolean use_nops,
			  bfd_boolean use_no_density)
{
  addressT alignment, fill, fill_limit, fill_step;
  bfd_boolean skip_one = FALSE;

  alignment = (1 << align_pow);
  gas_assert (target_size > 0 && alignment >= (addressT) target_size);

  if (!use_nops)
    {
      fill_limit = alignment;
      fill_step = 1;
    }
  else if (!use_no_density)
    {
      /* Combine 2- and 3-byte NOPs to fill anything larger than one.  */
      fill_limit = alignment * 2;
      fill_step = 1;
      skip_one = TRUE;
    }
  else
    {
      /* Fill with 3-byte NOPs -- can only fill multiples of 3.  */
      fill_limit = alignment * 3;
      fill_step = 3;
    }

  /* Try all fill sizes until finding one that works.  */
  for (fill = 0; fill < fill_limit; fill += fill_step)
    {
      if (skip_one && fill == 1)
	continue;
      if ((address + fill) >> align_pow
	  == (address + fill + target_size - 1) >> align_pow)
	return fill;
    }
  gas_assert (0);
  return 0;
}


static int
branch_align_power (segT sec)
{
  /* If the Xtensa processor has a fetch width of X, and
     the section is aligned to at least that boundary, then a branch
     target need only fit within that aligned block of memory to avoid
     a stall.  Otherwise, try to fit branch targets within 4-byte
     aligned blocks (which may be insufficient, e.g., if the section
     has no alignment, but it's good enough).  */
  int fetch_align = get_text_align_power(xtensa_fetch_width);
  int sec_align = get_recorded_alignment (sec);

  if (sec_align >= fetch_align)
    return fetch_align;

  return 2;
}


/* This will assert if it is not possible.  */

static int
get_text_align_nop_count (offsetT fill_size, bfd_boolean use_no_density)
{
  int count = 0;

  if (use_no_density)
    {
      gas_assert (fill_size % 3 == 0);
      return (fill_size / 3);
    }

  gas_assert (fill_size != 1);	/* Bad argument.  */

  while (fill_size > 1)
    {
      int insn_size = 3;
      if (fill_size == 2 || fill_size == 4)
	insn_size = 2;
      fill_size -= insn_size;
      count++;
    }
  gas_assert (fill_size != 1);	/* Bad algorithm.  */
  return count;
}


static int
get_text_align_nth_nop_size (offsetT fill_size,
			     int n,
			     bfd_boolean use_no_density)
{
  int count = 0;

  if (use_no_density)
    return 3;

  gas_assert (fill_size != 1);	/* Bad argument.  */

  while (fill_size > 1)
    {
      int insn_size = 3;
      if (fill_size == 2 || fill_size == 4)
	insn_size = 2;
      fill_size -= insn_size;
      count++;
      if (n + 1 == count)
	return insn_size;
    }
  gas_assert (0);
  return 0;
}


/* For the given fragment, find the appropriate address
   for it to begin at if we are using NOPs to align it.  */

static addressT
get_noop_aligned_address (fragS *fragP, addressT address)
{
  /* The rule is: get next fragment's FIRST instruction.  Find
     the smallest number of bytes that need to be added to
     ensure that the next fragment's FIRST instruction will fit
     in a single word.

     E.G.,   2 bytes : 0, 1, 2 mod 4
	     3 bytes: 0, 1 mod 4

     If the FIRST instruction MIGHT be relaxed,
     assume that it will become a 3-byte instruction.

     Note again here that LOOP instructions are not bundleable,
     and this relaxation only applies to LOOP opcodes.  */

  int fill_size = 0;
  int first_insn_size;
  int loop_insn_size;
  addressT pre_opcode_bytes;
  int align_power;
  fragS *first_insn;
  xtensa_opcode opcode;
  bfd_boolean is_loop;

  gas_assert (fragP->fr_type == rs_machine_dependent);
  gas_assert (fragP->fr_subtype == RELAX_ALIGN_NEXT_OPCODE);

  /* Find the loop frag.  */
  first_insn = next_non_empty_frag (fragP);
  /* Now find the first insn frag.  */
  first_insn = next_non_empty_frag (first_insn);

  is_loop = next_frag_opcode_is_loop (fragP, &opcode);
  gas_assert (is_loop);
  loop_insn_size = xg_get_single_size (opcode);

  pre_opcode_bytes = next_frag_pre_opcode_bytes (fragP);
  pre_opcode_bytes += loop_insn_size;

  /* For loops, the alignment depends on the size of the
     instruction following the loop, not the LOOP instruction.  */

  if (first_insn == NULL)
    first_insn_size = xtensa_fetch_width;
  else
    first_insn_size = get_loop_align_size (frag_format_size (first_insn));

  /* If it was 8, then we'll need a larger alignment for the section.  */
  align_power = get_text_align_power (first_insn_size);
  record_alignment (now_seg, align_power);

  fill_size = get_text_align_fill_size
    (address + pre_opcode_bytes, align_power, first_insn_size, TRUE,
     fragP->tc_frag_data.is_no_density);

  return address + fill_size;
}


/* 3 mechanisms for relaxing an alignment:

   Align to a power of 2.
   Align so the next fragment's instruction does not cross a word boundary.
   Align the current instruction so that if the next instruction
       were 3 bytes, it would not cross a word boundary.

   We can align with:

   zeros    - This is easy; always insert zeros.
   nops     - 3-byte and 2-byte instructions
              2 - 2-byte nop
              3 - 3-byte nop
              4 - 2 2-byte nops
              >=5 : 3-byte instruction + fn (n-3)
   widening - widen previous instructions.  */

static offsetT
get_aligned_diff (fragS *fragP, addressT address, offsetT *max_diff)
{
  addressT target_address, loop_insn_offset;
  int target_size;
  xtensa_opcode loop_opcode;
  bfd_boolean is_loop;
  int align_power;
  offsetT opt_diff;
  offsetT branch_align;
  fragS *loop_frag;

  gas_assert (fragP->fr_type == rs_machine_dependent);
  switch (fragP->fr_subtype)
    {
    case RELAX_DESIRE_ALIGN:
      target_size = next_frag_format_size (fragP);
      if (target_size == XTENSA_UNDEFINED)
	target_size = 3;
      align_power = branch_align_power (now_seg);
      branch_align = 1 << align_power;
      /* Don't count on the section alignment being as large as the target.  */
      if (target_size > branch_align)
	target_size = branch_align;
      opt_diff = get_text_align_fill_size (address, align_power,
					   target_size, FALSE, FALSE);

      *max_diff = (opt_diff + branch_align
		   - (target_size + ((address + opt_diff) % branch_align)));
      gas_assert (*max_diff >= opt_diff);
      return opt_diff;

    case RELAX_ALIGN_NEXT_OPCODE:
      /* The next non-empty frag after this one holds the LOOP instruction
	 that needs to be aligned.  The required alignment depends on the
	 size of the next non-empty frag after the loop frag, i.e., the
	 first instruction in the loop.  */
      loop_frag = next_non_empty_frag (fragP);
      target_size = get_loop_align_size (next_frag_format_size (loop_frag));
      loop_insn_offset = 0;
      is_loop = next_frag_opcode_is_loop (fragP, &loop_opcode);
      gas_assert (is_loop);

      /* If the loop has been expanded then the LOOP instruction
	 could be at an offset from this fragment.  */
      if (loop_frag->tc_frag_data.slot_subtypes[0] != RELAX_IMMED)
	loop_insn_offset = get_expanded_loop_offset (loop_opcode);

      /* In an ideal world, which is what we are shooting for here,
	 we wouldn't need to use any NOPs immediately prior to the
	 LOOP instruction.  If this approach fails, relax_frag_loop_align
	 will call get_noop_aligned_address.  */
      target_address =
	address + loop_insn_offset + xg_get_single_size (loop_opcode);
      align_power = get_text_align_power (target_size);
      opt_diff = get_text_align_fill_size (target_address, align_power,
					   target_size, FALSE, FALSE);

      *max_diff = xtensa_fetch_width
	- ((target_address + opt_diff) % xtensa_fetch_width)
	- target_size + opt_diff;
      gas_assert (*max_diff >= opt_diff);
      return opt_diff;

    default:
      break;
    }
  gas_assert (0);
  return 0;
}


/* md_relax_frag Hook and Helper Functions.  */

static long relax_frag_loop_align (fragS *, long);
static long relax_frag_for_align (fragS *, long);
static long relax_frag_immed
  (segT, fragS *, long, int, xtensa_format, int, int *, bfd_boolean);

typedef struct cached_fixup cached_fixupS;
struct cached_fixup
{
  int addr;
  int target;
  int delta;
  fixS *fixP;
};

typedef struct fixup_cache fixup_cacheS;
struct fixup_cache
{
  cached_fixupS *fixups;
  unsigned n_fixups;
  unsigned n_max;

  segT seg;
  fragS *first_frag;
};

static int fixup_order (const void *a, const void *b)
{
  const cached_fixupS *pa = a;
  const cached_fixupS *pb = b;

  if (pa->addr == pb->addr)
    {
      if (pa->target == pb->target)
	{
	  if (pa->fixP->fx_r_type == pb->fixP->fx_r_type)
	    return 0;
	  return pa->fixP->fx_r_type < pb->fixP->fx_r_type ?  -1 : 1;
	}
      return pa->target - pb->target;
    }
  return pa->addr - pb->addr;
}

static bfd_boolean xtensa_make_cached_fixup (cached_fixupS *o, fixS *fixP)
{
  xtensa_isa isa = xtensa_default_isa;
  int addr = fixP->fx_frag->fr_address;
  int target;
  int delta;
  symbolS *s = fixP->fx_addsy;
  int slot;
  xtensa_format fmt;
  xtensa_opcode opcode;

  if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP ||
      fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP)
    return FALSE;
  target = S_GET_VALUE (s);
  delta = target - addr;

  if (abs(delta) < J_RANGE / 2)
    return FALSE;

  xtensa_insnbuf_from_chars (isa, trampoline_buf,
			     (unsigned char *) fixP->fx_frag->fr_literal +
			     fixP->fx_where, 0);
  fmt = xtensa_format_decode (isa, trampoline_buf);
  gas_assert (fmt != XTENSA_UNDEFINED);
  slot = fixP->tc_fix_data.slot;
  xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf);
  opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf);
  if (opcode != xtensa_j_opcode)
    return FALSE;

  o->addr = addr;
  o->target = target;
  o->delta = delta;
  o->fixP = fixP;

  return TRUE;
}

static void xtensa_realloc_fixup_cache (fixup_cacheS *cache, unsigned add)
{
  if (cache->n_fixups + add > cache->n_max)
    {
      cache->n_max = (cache->n_fixups + add) * 2;
      cache->fixups = XRESIZEVEC (cached_fixupS, cache->fixups, cache->n_max);
    }
}

static void xtensa_cache_relaxable_fixups (fixup_cacheS *cache,
					   segment_info_type *seginfo)
{
  fixS *fixP;

  cache->n_fixups = 0;

  for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next)
    {
      xtensa_realloc_fixup_cache (cache, 1);

      if (xtensa_make_cached_fixup (cache->fixups + cache->n_fixups, fixP))
	++cache->n_fixups;
    }
  qsort (cache->fixups, cache->n_fixups, sizeof (*cache->fixups), fixup_order);
}

static unsigned xtensa_find_first_cached_fixup (const fixup_cacheS *cache,
						int addr)
{
  unsigned a = 0;
  unsigned b = cache->n_fixups;

  while (b - a > 1)
    {
      unsigned c = (a + b) / 2;

      if (cache->fixups[c].addr < addr)
	a = c;
      else
	b = c;
    }
  return a;
}

static void xtensa_delete_cached_fixup (fixup_cacheS *cache, unsigned i)
{
  memmove (cache->fixups + i, cache->fixups + i + 1,
	   (cache->n_fixups - i - 1) * sizeof (*cache->fixups));
  --cache->n_fixups;
}

static bfd_boolean xtensa_add_cached_fixup (fixup_cacheS *cache, fixS *fixP)
{
  cached_fixupS o;
  unsigned i;

  if (!xtensa_make_cached_fixup (&o, fixP))
    return FALSE;
  xtensa_realloc_fixup_cache (cache, 1);
  i = xtensa_find_first_cached_fixup (cache, o.addr);
  if (i < cache->n_fixups)
    {
      ++i;
      memmove (cache->fixups + i + 1, cache->fixups + i,
	       (cache->n_fixups - i) * sizeof (*cache->fixups));
    }
  cache->fixups[i] = o;
  ++cache->n_fixups;
  return TRUE;
}

/* Return the number of bytes added to this fragment, given that the
   input has been stretched already by "stretch".  */

long
xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p)
{
  xtensa_isa isa = xtensa_default_isa;
  int unreported = fragP->tc_frag_data.unreported_expansion;
  long new_stretch = 0;
  const char *file_name;
  unsigned line;
  int lit_size;
  static xtensa_insnbuf vbuf = NULL;
  int slot, num_slots;
  xtensa_format fmt;

  file_name = as_where (&line);
  new_logical_line (fragP->fr_file, fragP->fr_line);

  fragP->tc_frag_data.unreported_expansion = 0;

  switch (fragP->fr_subtype)
    {
    case RELAX_ALIGN_NEXT_OPCODE:
      /* Always convert.  */
      if (fragP->tc_frag_data.relax_seen)
	new_stretch = relax_frag_loop_align (fragP, stretch);
      break;

    case RELAX_LOOP_END:
      /* Do nothing.  */
      break;

    case RELAX_LOOP_END_ADD_NOP:
      /* Add a NOP and switch to .fill 0.  */
      new_stretch = relax_frag_add_nop (fragP);
      frag_wane (fragP);
      break;

    case RELAX_DESIRE_ALIGN:
      /* Do nothing. The narrowing before this frag will either align
         it or not.  */
      break;

    case RELAX_LITERAL:
    case RELAX_LITERAL_FINAL:
      return 0;

    case RELAX_LITERAL_NR:
      lit_size = 4;
      fragP->fr_subtype = RELAX_LITERAL_FINAL;
      gas_assert (unreported == lit_size);
      memset (&fragP->fr_literal[fragP->fr_fix], 0, 4);
      fragP->fr_var -= lit_size;
      fragP->fr_fix += lit_size;
      new_stretch = 4;
      break;

    case RELAX_SLOTS:
      if (vbuf == NULL)
	vbuf = xtensa_insnbuf_alloc (isa);

      xtensa_insnbuf_from_chars
	(isa, vbuf, (unsigned char *) fragP->fr_opcode, 0);
      fmt = xtensa_format_decode (isa, vbuf);
      num_slots = xtensa_format_num_slots (isa, fmt);

      for (slot = 0; slot < num_slots; slot++)
	{
	  switch (fragP->tc_frag_data.slot_subtypes[slot])
	    {
	    case RELAX_NARROW:
	      if (fragP->tc_frag_data.relax_seen)
		new_stretch += relax_frag_for_align (fragP, stretch);
	      break;

	    case RELAX_IMMED:
	    case RELAX_IMMED_STEP1:
	    case RELAX_IMMED_STEP2:
	    case RELAX_IMMED_STEP3:
	      /* Place the immediate.  */
	      new_stretch += relax_frag_immed
		(now_seg, fragP, stretch,
		 fragP->tc_frag_data.slot_subtypes[slot] - RELAX_IMMED,
		 fmt, slot, stretched_p, FALSE);
	      break;

	    default:
	      /* This is OK; see the note in xg_assemble_vliw_tokens.  */
	      break;
	    }
	}
      break;

    case RELAX_LITERAL_POOL_BEGIN:
      if (fragP->fr_var != 0)
	{
	  /* We have a converted "candidate" literal pool;
	     assemble a jump around it.  */
	  TInsn insn;
	  if (!litpool_slotbuf)
	    {
	      litpool_buf = xtensa_insnbuf_alloc (isa);
	      litpool_slotbuf = xtensa_insnbuf_alloc (isa);
	    }
	  new_stretch += 3;
	  fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass.  */
	  fragP->tc_frag_data.is_insn = TRUE;
	  tinsn_init (&insn);
	  insn.insn_type = ITYPE_INSN;
	  insn.opcode = xtensa_j_opcode;
	  insn.ntok = 1;
	  set_expr_symbol_offset (&insn.tok[0], fragP->fr_symbol,
				  fragP->fr_fix);
	  fmt = xg_get_single_format (xtensa_j_opcode);
	  tinsn_to_slotbuf (fmt, 0, &insn, litpool_slotbuf);
	  xtensa_format_set_slot (isa, fmt, 0, litpool_buf, litpool_slotbuf);
	  xtensa_insnbuf_to_chars (isa, litpool_buf,
				   (unsigned char *)fragP->fr_literal +
				   fragP->fr_fix, 3);
	  fragP->fr_fix += 3;
	  fragP->fr_var -= 3;
	  /* Add a fix-up.  */
	  fix_new (fragP, 0, 3, fragP->fr_symbol, 0, TRUE,
		   BFD_RELOC_XTENSA_SLOT0_OP);
	}
      break;

    case RELAX_LITERAL_POOL_END:
    case RELAX_LITERAL_POOL_CANDIDATE_BEGIN:
    case RELAX_MAYBE_UNREACHABLE:
    case RELAX_MAYBE_DESIRE_ALIGN:
      /* No relaxation required.  */
      break;

    case RELAX_FILL_NOP:
    case RELAX_UNREACHABLE:
      if (fragP->tc_frag_data.relax_seen)
	new_stretch += relax_frag_for_align (fragP, stretch);
      break;

    case RELAX_TRAMPOLINE:
      if (fragP->tc_frag_data.relax_seen)
        {
	  static fixup_cacheS fixup_cache;
	  segment_info_type *seginfo = seg_info (now_seg);
	  int trampaddr = fragP->fr_address + fragP->fr_fix;
	  int searchaddr = trampaddr < J_RANGE ? 0 : trampaddr - J_RANGE;
	  unsigned i;

	  if (now_seg != fixup_cache.seg ||
	      fragP == fixup_cache.first_frag ||
	      fixup_cache.first_frag == NULL)
	    {
	      xtensa_cache_relaxable_fixups (&fixup_cache, seginfo);
	      fixup_cache.seg = now_seg;
	      fixup_cache.first_frag = fragP;
	    }

          /* Scan for jumps that will not reach.  */
          for (i = xtensa_find_first_cached_fixup (&fixup_cache, searchaddr);
	       i < fixup_cache.n_fixups; ++i)

            {
	      fixS *fixP = fixup_cache.fixups[i].fixP;
	      int target = fixup_cache.fixups[i].target;
	      int addr = fixup_cache.fixups[i].addr;
	      int delta = fixup_cache.fixups[i].delta + stretch;

	      trampaddr = fragP->fr_address + fragP->fr_fix;

	      if (addr + J_RANGE < trampaddr)
		continue;
	      if (addr > trampaddr + J_RANGE)
		break;
	      if (abs (delta) < J_RANGE)
		continue;

	      slot = fixP->tc_fix_data.slot;

              if (delta > J_RANGE  || delta < -1 * J_RANGE)
                { /* Found an out-of-range jump; scan the list of trampolines for the best match.  */
		  struct trampoline_seg *ts = find_trampoline_seg (now_seg);
		  struct trampoline_frag *tf = ts->trampoline_list.next;
		  struct trampoline_frag *prev = &ts->trampoline_list;
		  int lower = (target < addr) ? target : addr;
		  int upper = (target > addr) ? target : addr;
		  int midpoint = lower + (upper - lower) / 2;

		  if ((upper - lower) > 2 * J_RANGE)
		    {
		      /* One trampoline won't suffice; we need multiple jumps.
			 Jump to the trampoline that's farthest, but still in
			 range relative to the original "j" instruction.  */
		      for ( ; tf; prev = tf, tf = tf->next )
			{
			  int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix;
			  int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0 ;

			  if (addr == lower)
			    {
			      /* Forward jump.  */
			      if (this_addr - addr < J_RANGE)
				break;
			    }
			  else
			    {
			      /* Backward jump.  */
			      if (next_addr == 0 || addr - next_addr > J_RANGE)
				break;
			    }
			}
		    }
		  else
		    {
		      struct trampoline_frag *best_tf = NULL;
		      int best_delta = 0;

		      for ( ; tf; prev = tf, tf = tf->next )
			{
			  int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix;
			  int this_delta = abs (this_addr - midpoint);

			  if (!best_tf || this_delta < best_delta)
			    {
			       best_tf = tf;
			       best_delta = this_delta;
			    }
			}
		      tf = best_tf;
		    }
		  if (tf->fragP == fragP)
		    {
		      if (abs (addr - trampaddr) < J_RANGE)
			{ /* The trampoline is in range of original; fix it!  */
			  fixS *newfixP;
			  int offset;
			  TInsn insn;
			  symbolS *lsym;
			  fragS *fP; /* The out-of-range jump.  */

			  new_stretch += init_trampoline_frag (tf);
			  offset = fragP->fr_fix; /* Where to assemble the j insn.  */
			  lsym = fragP->fr_symbol;
			  fP = fixP->fx_frag;
			  /* Assemble a jump to the target label here.  */
			  tinsn_init (&insn);
			  insn.insn_type = ITYPE_INSN;
			  insn.opcode = xtensa_j_opcode;
			  insn.ntok = 1;
			  set_expr_symbol_offset (&insn.tok[0], lsym, offset);
			  fmt = xg_get_single_format (xtensa_j_opcode);
			  tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf);
			  xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf);
			  xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fragP->fr_literal + offset, 3);
			  fragP->fr_fix += 3;
			  fragP->fr_var -= 3;
			  /* Add a fix-up for the original j insn.  */
			  newfixP = fix_new (fP, fixP->fx_where, fixP->fx_size, lsym, fragP->fr_fix - 3, TRUE, fixP->fx_r_type);
			  newfixP->fx_no_overflow = 1;
			  newfixP->tc_fix_data.X_add_symbol = lsym;
			  newfixP->tc_fix_data.X_add_number = offset;
			  newfixP->tc_fix_data.slot = slot;

			  xtensa_delete_cached_fixup (&fixup_cache, i);
			  xtensa_add_cached_fixup (&fixup_cache, newfixP);

			  /* Move the fix-up from the original j insn to this one.  */
			  fixP->fx_frag = fragP;
			  fixP->fx_where = fragP->fr_fix - 3;
			  fixP->tc_fix_data.slot = 0;

			  xtensa_add_cached_fixup (&fixup_cache, fixP);

			  /* re-do current fixup */
			  --i;

			  /* Adjust the jump around this trampoline (if present).  */
			  if (tf->fixP != NULL)
			    {
			      tf->fixP->fx_offset += 3;
			    }
			  new_stretch += 3;
			  fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass.  */
			  /* Do we have room for more?  */
			  if (fragP->fr_var < 3)
			    { /* No, convert to fill.  */
			      frag_wane (fragP);
			      fragP->fr_subtype = 0;
			      /* Remove from the trampoline_list.  */
			      prev->next = tf->next;
			      if (fragP == fixup_cache.first_frag)
				fixup_cache.first_frag = NULL;
			      break;
			    }
			}
		    }
                }
            }
        }
      break;

    default:
      as_bad (_("bad relaxation state"));
    }

  /* Tell gas we need another relaxation pass.  */
  if (! fragP->tc_frag_data.relax_seen)
    {
      fragP->tc_frag_data.relax_seen = TRUE;
      *stretched_p = 1;
    }

  new_logical_line (file_name, line);
  return new_stretch;
}


static long
relax_frag_loop_align (fragS *fragP, long stretch)
{
  addressT old_address, old_next_address, old_size;
  addressT new_address, new_next_address, new_size;
  addressT growth;

  /* All the frags with relax_frag_for_alignment prior to this one in the
     section have been done, hopefully eliminating the need for a NOP here.
     But, this will put it in if necessary.  */

  /* Calculate the old address of this fragment and the next fragment.  */
  old_address = fragP->fr_address - stretch;
  old_next_address = (fragP->fr_address - stretch + fragP->fr_fix +
		      fragP->tc_frag_data.text_expansion[0]);
  old_size = old_next_address - old_address;

  /* Calculate the new address of this fragment and the next fragment.  */
  new_address = fragP->fr_address;
  new_next_address =
    get_noop_aligned_address (fragP, fragP->fr_address + fragP->fr_fix);
  new_size = new_next_address - new_address;

  growth = new_size - old_size;

  /* Fix up the text_expansion field and return the new growth.  */
  fragP->tc_frag_data.text_expansion[0] += growth;
  return growth;
}


/* Add a NOP instruction.  */

static long
relax_frag_add_nop (fragS *fragP)
{
  char *nop_buf = fragP->fr_literal + fragP->fr_fix;
  int length = fragP->tc_frag_data.is_no_density ? 3 : 2;
  assemble_nop (length, nop_buf);
  fragP->tc_frag_data.is_insn = TRUE;

  if (fragP->fr_var < length)
    {
      as_fatal (_("fr_var (%ld) < length (%d)"), (long) fragP->fr_var, length);
      return 0;
    }

  fragP->fr_fix += length;
  fragP->fr_var -= length;
  return length;
}


static long future_alignment_required (fragS *, long);

static long
relax_frag_for_align (fragS *fragP, long stretch)
{
  /* Overview of the relaxation procedure for alignment:
     We can widen with NOPs or by widening instructions or by filling
     bytes after jump instructions.  Find the opportune places and widen
     them if necessary.  */

  long stretch_me;
  long diff;

  gas_assert (fragP->fr_subtype == RELAX_FILL_NOP
	  || fragP->fr_subtype == RELAX_UNREACHABLE
	  || (fragP->fr_subtype == RELAX_SLOTS
	      && fragP->tc_frag_data.slot_subtypes[0] == RELAX_NARROW));

  stretch_me = future_alignment_required (fragP, stretch);
  diff = stretch_me - fragP->tc_frag_data.text_expansion[0];
  if (diff == 0)
    return 0;

  if (diff < 0)
    {
      /* We expanded on a previous pass.  Can we shrink now?  */
      long shrink = fragP->tc_frag_data.text_expansion[0] - stretch_me;
      if (shrink <= stretch && stretch > 0)
	{
	  fragP->tc_frag_data.text_expansion[0] = stretch_me;
	  return -shrink;
	}
      return 0;
    }

  /* Below here, diff > 0.  */
  fragP->tc_frag_data.text_expansion[0] = stretch_me;

  return diff;
}


/* Return the address of the next frag that should be aligned.

   By "address" we mean the address it _would_ be at if there
   is no action taken to align it between here and the target frag.
   In other words, if no narrows and no fill nops are used between
   here and the frag to align, _even_if_ some of the frags we use
   to align targets have already expanded on a previous relaxation
   pass.

   Also, count each frag that may be used to help align the target.

   Return 0 if there are no frags left in the chain that need to be
   aligned.  */

static addressT
find_address_of_next_align_frag (fragS **fragPP,
				 int *wide_nops,
				 int *narrow_nops,
				 int *widens,
				 bfd_boolean *paddable)
{
  fragS *fragP = *fragPP;
  addressT address = fragP->fr_address;

  /* Do not reset the counts to 0.  */

  while (fragP)
    {
      /* Limit this to a small search.  */
      if (*widens >= (int) xtensa_fetch_width)
	{
	  *fragPP = fragP;
	  return 0;
	}
      address += fragP->fr_fix;

      if (fragP->fr_type == rs_fill)
	address += fragP->fr_offset * fragP->fr_var;
      else if (fragP->fr_type == rs_machine_dependent)
	{
	  switch (fragP->fr_subtype)
	    {
	    case RELAX_UNREACHABLE:
	      *paddable = TRUE;
	      break;

	    case RELAX_FILL_NOP:
	      (*wide_nops)++;
	      if (!fragP->tc_frag_data.is_no_density)
		(*narrow_nops)++;
	      break;

	    case RELAX_SLOTS:
	      if (fragP->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
		{
		  (*widens)++;
		  break;
		}
	      address += total_frag_text_expansion (fragP);
	      break;

	    case RELAX_IMMED:
	      address += fragP->tc_frag_data.text_expansion[0];
	      break;

	    case RELAX_ALIGN_NEXT_OPCODE:
	    case RELAX_DESIRE_ALIGN:
	      *fragPP = fragP;
	      return address;

	    case RELAX_MAYBE_UNREACHABLE:
	    case RELAX_MAYBE_DESIRE_ALIGN:
	      /* Do nothing.  */
	      break;

	    default:
	      /* Just punt if we don't know the type.  */
	      *fragPP = fragP;
	      return 0;
	    }
	}
      else
	{
	  /* Just punt if we don't know the type.  */
	  *fragPP = fragP;
	  return 0;
	}
      fragP = fragP->fr_next;
    }

  *fragPP = fragP;
  return 0;
}


static long bytes_to_stretch (fragS *, int, int, int, int);

static long
future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
{
  fragS *this_frag = fragP;
  long address;
  int num_widens = 0;
  int wide_nops = 0;
  int narrow_nops = 0;
  bfd_boolean paddable = FALSE;
  offsetT local_opt_diff;
  offsetT opt_diff;
  offsetT max_diff;
  int stretch_amount = 0;
  int local_stretch_amount;
  int global_stretch_amount;

  address = find_address_of_next_align_frag
    (&fragP, &wide_nops, &narrow_nops, &num_widens, &paddable);

  if (!address)
    {
      if (this_frag->tc_frag_data.is_aligning_branch)
	this_frag->tc_frag_data.slot_subtypes[0] = RELAX_IMMED;
      else
	frag_wane (this_frag);
    }
  else
    {
      local_opt_diff = get_aligned_diff (fragP, address, &max_diff);
      opt_diff = local_opt_diff;
      gas_assert (opt_diff >= 0);
      gas_assert (max_diff >= opt_diff);
      if (max_diff == 0)
	return 0;

      if (fragP)
	fragP = fragP->fr_next;

      while (fragP && opt_diff < max_diff && address)
	{
	  /* We only use these to determine if we can exit early
	     because there will be plenty of ways to align future
	     align frags.  */
	  int glob_widens = 0;
	  int dnn = 0;
	  int dw = 0;
	  bfd_boolean glob_pad = 0;
	  address = find_address_of_next_align_frag
	    (&fragP, &glob_widens, &dnn, &dw, &glob_pad);
	  /* If there is a padable portion, then skip.  */
	  if (glob_pad || glob_widens >= (1 << branch_align_power (now_seg)))
	    address = 0;

	  if (address)
	    {
	      offsetT next_m_diff;
	      offsetT next_o_diff;

	      /* Downrange frags haven't had stretch added to them yet.  */
	      address += stretch;

	      /* The address also includes any text expansion from this
		 frag in a previous pass, but we don't want that.  */
	      address -= this_frag->tc_frag_data.text_expansion[0];

	      /* Assume we are going to move at least opt_diff.  In
		 reality, we might not be able to, but assuming that
		 we will helps catch cases where moving opt_diff pushes
		 the next target from aligned to unaligned.  */
	      address += opt_diff;

	      next_o_diff = get_aligned_diff (fragP, address, &next_m_diff);

	      /* Now cleanup for the adjustments to address.  */
	      next_o_diff += opt_diff;
	      next_m_diff += opt_diff;
	      if (next_o_diff <= max_diff && next_o_diff > opt_diff)
		opt_diff = next_o_diff;
	      if (next_m_diff < max_diff)
		max_diff = next_m_diff;
	      fragP = fragP->fr_next;
	    }
	}

      /* If there are enough wideners in between, do it.  */
      if (paddable)
	{
	  if (this_frag->fr_subtype == RELAX_UNREACHABLE)
	    {
	      gas_assert (opt_diff <= (signed) xtensa_fetch_width);
	      return opt_diff;
	    }
	  return 0;
	}
      local_stretch_amount
	= bytes_to_stretch (this_frag, wide_nops, narrow_nops,
			    num_widens, local_opt_diff);
      global_stretch_amount
	= bytes_to_stretch (this_frag, wide_nops, narrow_nops,
			    num_widens, opt_diff);
      /* If the condition below is true, then the frag couldn't
	 stretch the correct amount for the global case, so we just
	 optimize locally.  We'll rely on the subsequent frags to get
	 the correct alignment in the global case.  */
      if (global_stretch_amount < local_stretch_amount)
	stretch_amount = local_stretch_amount;
      else
	stretch_amount = global_stretch_amount;

      if (this_frag->fr_subtype == RELAX_SLOTS
	  && this_frag->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
	gas_assert (stretch_amount <= 1);
      else if (this_frag->fr_subtype == RELAX_FILL_NOP)
	{
	  if (this_frag->tc_frag_data.is_no_density)
	    gas_assert (stretch_amount == 3 || stretch_amount == 0);
	  else
	    gas_assert (stretch_amount <= 3);
	}
    }
  return stretch_amount;
}


/* The idea: widen everything you can to get a target or loop aligned,
   then start using NOPs.

   wide_nops   = the number of wide NOPs available for aligning
   narrow_nops = the number of narrow NOPs available for aligning
		 (a subset of wide_nops)
   widens      = the number of narrow instructions that should be widened

*/

static long
bytes_to_stretch (fragS *this_frag,
		  int wide_nops,
		  int narrow_nops,
		  int num_widens,
		  int desired_diff)
{
  int nops_needed;
  int nop_bytes;
  int extra_bytes;
  int bytes_short = desired_diff - num_widens;

  gas_assert (desired_diff >= 0
	      && desired_diff < (signed) xtensa_fetch_width);
  if (desired_diff == 0)
    return 0;

  gas_assert (wide_nops > 0 || num_widens > 0);

  /* Always prefer widening to NOP-filling.  */
  if (bytes_short < 0)
    {
      /* There are enough RELAX_NARROW frags after this one
	 to align the target without widening this frag in any way.  */
      return 0;
    }

  if (bytes_short == 0)
    {
      /* Widen every narrow between here and the align target
	 and the align target will be properly aligned.  */
      if (this_frag->fr_subtype == RELAX_FILL_NOP)
	return 0;
      else
	return 1;
    }

  /* From here we will need at least one NOP to get an alignment.
     However, we may not be able to align at all, in which case,
     don't widen.  */
  nops_needed = desired_diff / 3;

  /* If there aren't enough nops, don't widen.  */
  if (nops_needed > wide_nops)
    return 0;

  /* First try it with all wide nops.  */
  nop_bytes = nops_needed * 3;
  extra_bytes = desired_diff - nop_bytes;

  if (nop_bytes + num_widens >= desired_diff)
    {
      if (this_frag->fr_subtype == RELAX_FILL_NOP)
	return 3;
      else if (num_widens == extra_bytes)
	return 1;
      return 0;
    }

  /* Add a narrow nop.  */
  nops_needed++;
  nop_bytes += 2;
  extra_bytes -= 2;
  if (narrow_nops == 0 || nops_needed > wide_nops)
    return 0;

  if (nop_bytes + num_widens >= desired_diff && extra_bytes >= 0)
    {
      if (this_frag->fr_subtype == RELAX_FILL_NOP)
	return !this_frag->tc_frag_data.is_no_density ? 2 : 3;
      else if (num_widens == extra_bytes)
	return 1;
      return 0;
    }

  /* Replace a wide nop with a narrow nop--we can get here if
     extra_bytes was negative in the previous conditional.  */
  if (narrow_nops == 1)
    return 0;
  nop_bytes--;
  extra_bytes++;
  if (nop_bytes + num_widens >= desired_diff)
    {
      if (this_frag->fr_subtype == RELAX_FILL_NOP)
	return !this_frag->tc_frag_data.is_no_density ? 2 : 3;
      else if (num_widens == extra_bytes)
	return 1;
      return 0;
    }

  /* If we can't satisfy any of the above cases, then we can't align
     using padding or fill nops.  */
  return 0;
}


static struct trampoline_frag *
search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only)
{
  struct trampoline_seg *ts = find_trampoline_seg (now_seg);
  struct trampoline_frag *tf = (ts) ? ts->trampoline_list.next : NULL;
  struct trampoline_frag *best_tf = NULL;
  int best_delta = 0;
  int best_addr = 0;
  symbolS *sym = tinsn->tok[0].X_add_symbol;
  offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number;
  offsetT addr = fragP->fr_address;
  offsetT lower = (addr < target) ? addr : target;
  offsetT upper = (addr > target) ? addr : target;
  int delta = upper - lower;
  offsetT midpoint = lower + delta / 2;
  int this_delta = -1;
  int this_addr = -1;

  if (delta > 2 * J_RANGE)
    {
      /* One trampoline won't do; we need multiple.
	 Choose the farthest trampoline that's still in range of the original
	 and let a later pass finish the job.  */
      for ( ; tf; tf = tf->next)
	{
	  int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0;

	  this_addr = tf->fragP->fr_address + tf->fragP->fr_fix;
	  if (lower == addr)
	    {
	      /* Forward jump.  */
	      if (this_addr - addr < J_RANGE)
		break;
	    }
	  else
	    {
	      /* Backward jump.  */
	      if (next_addr == 0 || addr - next_addr > J_RANGE)
		break;
	    }
	}
      if (abs (addr - this_addr) < J_RANGE)
	return tf;

      return NULL;
    }
  for ( ; tf; tf = tf->next)
    {
      this_addr = tf->fragP->fr_address + tf->fragP->fr_fix;
      this_delta = abs (this_addr - midpoint);
      if (unreachable_only && tf->needs_jump_around)
	continue;
      if (!best_tf || this_delta < best_delta)
        {
	  best_tf = tf;
	  best_delta = this_delta;
	  best_addr = this_addr;
        }
    }

  if (best_tf &&
      best_delta < J_RANGE &&
      abs(best_addr - lower) < J_RANGE &&
      abs(best_addr - upper) < J_RANGE)
    return best_tf;

  return NULL; /* No suitable trampoline found.  */
}


static struct trampoline_frag *
get_best_trampoline (TInsn *tinsn, fragS *fragP)
{
  struct trampoline_frag *tf = NULL;

  tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first.  */

  if (tf == NULL)
    tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too.  */

  return tf;
}


static void
check_and_update_trampolines (void)
{
  struct trampoline_seg *ts = find_trampoline_seg (now_seg);
  struct trampoline_frag *tf = ts->trampoline_list.next;
  struct trampoline_frag *prev = &ts->trampoline_list;

  for ( ; tf; prev = tf, tf = tf->next)
    {
      if (tf->fragP->fr_var < 3)
	{
	  frag_wane (tf->fragP);
	  prev->next = tf->next;
	  tf->fragP = NULL;
	}
    }
}


static int
init_trampoline_frag (struct trampoline_frag *trampP)
{
  fragS *fp = trampP->fragP;
  int growth = 0;

  if (fp->fr_fix == 0)
    {
      symbolS *lsym;
      char label[10 + 2 * sizeof(fp)];
      sprintf (label, ".L0_TR_%p", fp);

      lsym = (symbolS *)local_symbol_make (label, now_seg, 0, fp);
      fp->fr_symbol = lsym;
      if (trampP->needs_jump_around)
        {
	  /* Add a jump around this block of jumps, in case
	     control flows into this block.  */
	  fixS *fixP;
	  TInsn insn;
	  xtensa_format fmt;
	  xtensa_isa isa = xtensa_default_isa;

	  fp->tc_frag_data.is_insn = 1;
	  /* Assemble a jump insn.  */
	  tinsn_init (&insn);
	  insn.insn_type = ITYPE_INSN;
	  insn.opcode = xtensa_j_opcode;
	  insn.ntok = 1;
	  set_expr_symbol_offset (&insn.tok[0], lsym, 3);
	  fmt = xg_get_single_format (xtensa_j_opcode);
	  tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf);
	  xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf);
	  xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fp->fr_literal, 3);
	  fp->fr_fix += 3;
	  fp->fr_var -= 3;
	  growth = 3;
	  fixP = fix_new (fp, 0, 3, lsym, 3, TRUE, BFD_RELOC_XTENSA_SLOT0_OP);
	  trampP->fixP = fixP;
        }
    }
  return growth;
}


static int
add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag)
{
  fragS *tramp = trampP->fragP;
  fixS *fixP;
  int offset = tramp->fr_fix; /* Where to assemble the j insn.  */
  TInsn insn;
  symbolS *lsym;
  symbolS *tsym;
  int toffset;
  xtensa_format fmt;
  xtensa_isa isa = xtensa_default_isa;
  int growth = 0;

  lsym = tramp->fr_symbol;
  /* Assemble a jump to the target label in the trampoline frag.  */
  tsym = origfrag->tc_frag_data.slot_symbols[0];
  toffset = origfrag-> tc_frag_data.slot_offsets[0];
  tinsn_init (&insn);
  insn.insn_type = ITYPE_INSN;
  insn.opcode = xtensa_j_opcode;
  insn.ntok = 1;
  set_expr_symbol_offset (&insn.tok[0], tsym, toffset);
  fmt = xg_get_single_format (xtensa_j_opcode);
  tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf);
  xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf);
  xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)tramp->fr_literal + offset, 3);
  tramp->fr_fix += 3;
  tramp->fr_var -= 3;
  growth = 3;
  /* add a fix-up for the trampoline jump.  */
  fixP = fix_new (tramp, tramp->fr_fix - 3, 3, tsym, toffset, TRUE, BFD_RELOC_XTENSA_SLOT0_OP);
  /* Modify the jump at the start of this trampoline to point past the newly-added jump.  */
  fixP = trampP->fixP;
  if (fixP)
    fixP->fx_offset += 3;
  /* Modify the original j to point here.  */
  origfrag->tc_frag_data.slot_symbols[0] = lsym;
  origfrag->tc_frag_data.slot_offsets[0] = tramp->fr_fix - 3;
  /* If trampoline is full, remove it from the list.  */
  check_and_update_trampolines ();

  return growth;
}


static long
relax_frag_immed (segT segP,
		  fragS *fragP,
		  long stretch,
		  int min_steps,
		  xtensa_format fmt,
		  int slot,
		  int *stretched_p,
		  bfd_boolean estimate_only)
{
  TInsn tinsn;
  int old_size;
  bfd_boolean negatable_branch = FALSE;
  bfd_boolean branch_jmp_to_next = FALSE;
  bfd_boolean from_wide_insn = FALSE;
  xtensa_isa isa = xtensa_default_isa;
  IStack istack;
  offsetT frag_offset;
  int num_steps;
  int num_text_bytes, num_literal_bytes;
  int literal_diff, total_text_diff, this_text_diff;

  gas_assert (fragP->fr_opcode != NULL);

  xg_clear_vinsn (&cur_vinsn);
  vinsn_from_chars (&cur_vinsn, fragP->fr_opcode);
  if (cur_vinsn.num_slots > 1)
    from_wide_insn = TRUE;

  tinsn = cur_vinsn.slots[slot];
  tinsn_immed_from_frag (&tinsn, fragP, slot);

  if (estimate_only && xtensa_opcode_is_loop (isa, tinsn.opcode) == 1)
    return 0;

  if (workaround_b_j_loop_end && ! fragP->tc_frag_data.is_no_transform)
    branch_jmp_to_next = is_branch_jmp_to_next (&tinsn, fragP);

  negatable_branch = (xtensa_opcode_is_branch (isa, tinsn.opcode) == 1);

  old_size = xtensa_format_length (isa, fmt);

  /* Special case: replace a branch to the next instruction with a NOP.
     This is required to work around a hardware bug in T1040.0 and also
     serves as an optimization.  */

  if (branch_jmp_to_next
      && ((old_size == 2) || (old_size == 3))
      && !next_frag_is_loop_target (fragP))
    return 0;

  /* Here is the fun stuff: Get the immediate field from this
     instruction.  If it fits, we are done.  If not, find the next
     instruction sequence that fits.  */

  frag_offset = fragP->fr_opcode - fragP->fr_literal;
  istack_init (&istack);
  num_steps = xg_assembly_relax (&istack, &tinsn, segP, fragP, frag_offset,
				 min_steps, stretch);
  gas_assert (num_steps >= min_steps && num_steps <= RELAX_IMMED_MAXSTEPS);

  fragP->tc_frag_data.slot_subtypes[slot] = (int) RELAX_IMMED + num_steps;

  /* Figure out the number of bytes needed.  */
  num_literal_bytes = get_num_stack_literal_bytes (&istack);
  literal_diff
    = num_literal_bytes - fragP->tc_frag_data.literal_expansion[slot];
  num_text_bytes = get_num_stack_text_bytes (&istack);

  if (from_wide_insn)
    {
      int first = 0;
      while (istack.insn[first].opcode == XTENSA_UNDEFINED)
	first++;

      num_text_bytes += old_size;
      if (opcode_fits_format_slot (istack.insn[first].opcode, fmt, slot))
	num_text_bytes -= xg_get_single_size (istack.insn[first].opcode);
      else
	{
	  /* The first instruction in the relaxed sequence will go after
	     the current wide instruction, and thus its symbolic immediates
	     might not fit.  */

	  istack_init (&istack);
	  num_steps = xg_assembly_relax (&istack, &tinsn, segP, fragP,
					 frag_offset + old_size,
					 min_steps, stretch + old_size);
	  gas_assert (num_steps >= min_steps && num_steps <= RELAX_IMMED_MAXSTEPS);

	  fragP->tc_frag_data.slot_subtypes[slot]
	    = (int) RELAX_IMMED + num_steps;

	  num_literal_bytes = get_num_stack_literal_bytes (&istack);
	  literal_diff
	    = num_literal_bytes - fragP->tc_frag_data.literal_expansion[slot];

	  num_text_bytes = get_num_stack_text_bytes (&istack) + old_size;
	}
    }

  total_text_diff = num_text_bytes - old_size;
  this_text_diff = total_text_diff - fragP->tc_frag_data.text_expansion[slot];

  /* It MUST get larger.  If not, we could get an infinite loop.  */
  gas_assert (num_text_bytes >= 0);
  gas_assert (literal_diff >= 0);
  gas_assert (total_text_diff >= 0);

  fragP->tc_frag_data.text_expansion[slot] = total_text_diff;
  fragP->tc_frag_data.literal_expansion[slot] = num_literal_bytes;
  gas_assert (fragP->tc_frag_data.text_expansion[slot] >= 0);
  gas_assert (fragP->tc_frag_data.literal_expansion[slot] >= 0);

  /* Find the associated expandable literal for this.  */
  if (literal_diff != 0)
    {
      fragS *lit_fragP = fragP->tc_frag_data.literal_frags[slot];
      if (lit_fragP)
	{
	  gas_assert (literal_diff == 4);
	  lit_fragP->tc_frag_data.unreported_expansion += literal_diff;

	  /* We expect that the literal section state has NOT been
	     modified yet.  */
	  gas_assert (lit_fragP->fr_type == rs_machine_dependent
		  && lit_fragP->fr_subtype == RELAX_LITERAL);
	  lit_fragP->fr_subtype = RELAX_LITERAL_NR;

	  /* We need to mark this section for another iteration
	     of relaxation.  */
	  (*stretched_p)++;
	}
    }

  if (negatable_branch && istack.ninsn > 1)
    update_next_frag_state (fragP);

  /* If last insn is a jump, and it cannot reach its target, try to find a trampoline.  */
  if (istack.ninsn > 2 &&
      istack.insn[istack.ninsn - 1].insn_type == ITYPE_LABEL &&
      istack.insn[istack.ninsn - 2].insn_type == ITYPE_INSN &&
      istack.insn[istack.ninsn - 2].opcode == xtensa_j_opcode)
    {
      TInsn *jinsn = &istack.insn[istack.ninsn - 2];

      if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff))
	{
	  struct trampoline_frag *tf = get_best_trampoline (jinsn, fragP);

	  if (tf)
	    {
	      this_text_diff += init_trampoline_frag (tf);
	      this_text_diff += add_jump_to_trampoline (tf, fragP);
	    }
	  else
	    {
	      /* If target symbol is undefined, assume it will reach once linked.  */
	      expressionS *exp = &istack.insn[istack.ninsn - 2].tok[0];

	      if (exp->X_op == O_symbol && S_IS_DEFINED (exp->X_add_symbol))
		{
		  as_bad_where (fragP->fr_file, fragP->fr_line,
		    _("jump target out of range; no usable trampoline found"));
		}
	    }
	}
    }

  return this_text_diff;
}


/* md_convert_frag Hook and Helper Functions.  */

static void convert_frag_align_next_opcode (fragS *);
static void convert_frag_narrow (segT, fragS *, xtensa_format, int);
static void convert_frag_fill_nop (fragS *);
static void convert_frag_immed (segT, fragS *, int, xtensa_format, int);

void
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragp)
{
  static xtensa_insnbuf vbuf = NULL;
  xtensa_isa isa = xtensa_default_isa;
  int slot;
  int num_slots;
  xtensa_format fmt;
  const char *file_name;
  unsigned line;

  file_name = as_where (&line);
  new_logical_line (fragp->fr_file, fragp->fr_line);

  switch (fragp->fr_subtype)
    {
    case RELAX_ALIGN_NEXT_OPCODE:
      /* Always convert.  */
      convert_frag_align_next_opcode (fragp);
      break;

    case RELAX_DESIRE_ALIGN:
      /* Do nothing.  If not aligned already, too bad.  */
      break;

    case RELAX_LITERAL:
    case RELAX_LITERAL_FINAL:
      break;

    case RELAX_SLOTS:
      if (vbuf == NULL)
	vbuf = xtensa_insnbuf_alloc (isa);

      xtensa_insnbuf_from_chars
	(isa, vbuf, (unsigned char *) fragp->fr_opcode, 0);
      fmt = xtensa_format_decode (isa, vbuf);
      num_slots = xtensa_format_num_slots (isa, fmt);

      for (slot = 0; slot < num_slots; slot++)
	{
	  switch (fragp->tc_frag_data.slot_subtypes[slot])
	    {
	    case RELAX_NARROW:
	      convert_frag_narrow (sec, fragp, fmt, slot);
	      break;

	    case RELAX_IMMED:
	    case RELAX_IMMED_STEP1:
	    case RELAX_IMMED_STEP2:
	    case RELAX_IMMED_STEP3:
	      /* Place the immediate.  */
	      convert_frag_immed
		(sec, fragp,
		 fragp->tc_frag_data.slot_subtypes[slot] - RELAX_IMMED,
		 fmt, slot);
	      break;

	    default:
	      /* This is OK because some slots could have
		 relaxations and others have none.  */
	      break;
	    }
	}
      break;

    case RELAX_UNREACHABLE:
      memset (&fragp->fr_literal[fragp->fr_fix], 0, fragp->fr_var);
      fragp->fr_fix += fragp->tc_frag_data.text_expansion[0];
      fragp->fr_var -= fragp->tc_frag_data.text_expansion[0];
      frag_wane (fragp);
      break;

    case RELAX_MAYBE_UNREACHABLE:
    case RELAX_MAYBE_DESIRE_ALIGN:
      frag_wane (fragp);
      break;

    case RELAX_FILL_NOP:
      convert_frag_fill_nop (fragp);
      break;

    case RELAX_LITERAL_NR:
      if (use_literal_section)
	{
	  /* This should have been handled during relaxation.  When
	     relaxing a code segment, literals sometimes need to be
	     added to the corresponding literal segment.  If that
	     literal segment has already been relaxed, then we end up
	     in this situation.  Marking the literal segments as data
	     would make this happen less often (since GAS always relaxes
	     code before data), but we could still get into trouble if
	     there are instructions in a segment that is not marked as
	     containing code.  Until we can implement a better solution,
	     cheat and adjust the addresses of all the following frags.
	     This could break subsequent alignments, but the linker's
	     literal coalescing will do that anyway.  */

	  fragS *f;
	  fragp->fr_subtype = RELAX_LITERAL_FINAL;
	  gas_assert (fragp->tc_frag_data.unreported_expansion == 4);
	  memset (&fragp->fr_literal[fragp->fr_fix], 0, 4);
	  fragp->fr_var -= 4;
	  fragp->fr_fix += 4;
	  for (f = fragp->fr_next; f; f = f->fr_next)
	    f->fr_address += 4;
	}
      else
	as_bad (_("invalid relaxation fragment result"));
      break;

    case RELAX_TRAMPOLINE:
      break;
    }

  fragp->fr_var = 0;
  new_logical_line (file_name, line);
}


static void
convert_frag_align_next_opcode (fragS *fragp)
{
  char *nop_buf;		/* Location for Writing.  */
  bfd_boolean use_no_density = fragp->tc_frag_data.is_no_density;
  addressT aligned_address;
  offsetT fill_size;
  int nop, nop_count;

  aligned_address = get_noop_aligned_address (fragp, fragp->fr_address +
					      fragp->fr_fix);
  fill_size = aligned_address - (fragp->fr_address + fragp->fr_fix);
  nop_count = get_text_align_nop_count (fill_size, use_no_density);
  nop_buf = fragp->fr_literal + fragp->fr_fix;

  for (nop = 0; nop < nop_count; nop++)
    {
      int nop_size;
      nop_size = get_text_align_nth_nop_size (fill_size, nop, use_no_density);

      assemble_nop (nop_size, nop_buf);
      nop_buf += nop_size;
    }

  fragp->fr_fix += fill_size;
  fragp->fr_var -= fill_size;
}


static void
convert_frag_narrow (segT segP, fragS *fragP, xtensa_format fmt, int slot)
{
  TInsn tinsn, single_target;
  int size, old_size, diff;
  offsetT frag_offset;

  gas_assert (slot == 0);
  tinsn_from_chars (&tinsn, fragP->fr_opcode, 0);

  if (fragP->tc_frag_data.is_aligning_branch == 1)
    {
      gas_assert (fragP->tc_frag_data.text_expansion[0] == 1
	      || fragP->tc_frag_data.text_expansion[0] == 0);
      convert_frag_immed (segP, fragP, fragP->tc_frag_data.text_expansion[0],
			  fmt, slot);
      return;
    }

  if (fragP->tc_frag_data.text_expansion[0] == 0)
    {
      /* No conversion.  */
      fragP->fr_var = 0;
      return;
    }

  gas_assert (fragP->fr_opcode != NULL);

  /* Frags in this relaxation state should only contain
     single instruction bundles.  */
  tinsn_immed_from_frag (&tinsn, fragP, 0);

  /* Just convert it to a wide form....  */
  size = 0;
  old_size = xg_get_single_size (tinsn.opcode);

  tinsn_init (&single_target);
  frag_offset = fragP->fr_opcode - fragP->fr_literal;

  if (! xg_is_single_relaxable_insn (&tinsn, &single_target, FALSE))
    {
      as_bad (_("unable to widen instruction"));
      return;
    }

  size = xg_get_single_size (single_target.opcode);
  xg_emit_insn_to_buf (&single_target, fragP->fr_opcode, fragP,
		       frag_offset, TRUE);

  diff = size - old_size;
  gas_assert (diff >= 0);
  gas_assert (diff <= fragP->fr_var);
  fragP->fr_var -= diff;
  fragP->fr_fix += diff;

  /* clean it up */
  fragP->fr_var = 0;
}


static void
convert_frag_fill_nop (fragS *fragP)
{
  char *loc = &fragP->fr_literal[fragP->fr_fix];
  int size = fragP->tc_frag_data.text_expansion[0];
  gas_assert ((unsigned) size == (fragP->fr_next->fr_address
			      - fragP->fr_address - fragP->fr_fix));
  if (size == 0)
    {
      /* No conversion.  */
      fragP->fr_var = 0;
      return;
    }
  assemble_nop (size, loc);
  fragP->tc_frag_data.is_insn = TRUE;
  fragP->fr_var -= size;
  fragP->fr_fix += size;
  frag_wane (fragP);
}


static fixS *fix_new_exp_in_seg
  (segT, subsegT, fragS *, int, int, expressionS *, int,
   bfd_reloc_code_real_type);
static void convert_frag_immed_finish_loop (segT, fragS *, TInsn *);

static void
convert_frag_immed (segT segP,
		    fragS *fragP,
		    int min_steps,
		    xtensa_format fmt,
		    int slot)
{
  char *immed_instr = fragP->fr_opcode;
  TInsn orig_tinsn;
  bfd_boolean expanded = FALSE;
  bfd_boolean branch_jmp_to_next = FALSE;
  char *fr_opcode = fragP->fr_opcode;
  xtensa_isa isa = xtensa_default_isa;
  bfd_boolean from_wide_insn = FALSE;
  int bytes;
  bfd_boolean is_loop;

  gas_assert (fr_opcode != NULL);

  xg_clear_vinsn (&cur_vinsn);

  vinsn_from_chars (&cur_vinsn, fr_opcode);
  if (cur_vinsn.num_slots > 1)
    from_wide_insn = TRUE;

  orig_tinsn = cur_vinsn.slots[slot];
  tinsn_immed_from_frag (&orig_tinsn, fragP, slot);

  is_loop = xtensa_opcode_is_loop (xtensa_default_isa, orig_tinsn.opcode) == 1;

  if (workaround_b_j_loop_end && ! fragP->tc_frag_data.is_no_transform)
    branch_jmp_to_next = is_branch_jmp_to_next (&orig_tinsn, fragP);

  if (branch_jmp_to_next && !next_frag_is_loop_target (fragP))
    {
      /* Conversion just inserts a NOP and marks the fix as completed.  */
      bytes = xtensa_format_length (isa, fmt);
      if (bytes >= 4)
	{
	  cur_vinsn.slots[slot].opcode =
	    xtensa_format_slot_nop_opcode (isa, cur_vinsn.format, slot);
	  cur_vinsn.slots[slot].ntok = 0;
	}
      else
	{
	  bytes += fragP->tc_frag_data.text_expansion[0];
	  gas_assert (bytes == 2 || bytes == 3);
	  build_nop (&cur_vinsn.slots[0], bytes);
	  fragP->fr_fix += fragP->tc_frag_data.text_expansion[0];
	}
      vinsn_to_insnbuf (&cur_vinsn, fr_opcode, frag_now, TRUE);
      xtensa_insnbuf_to_chars
	(isa, cur_vinsn.insnbuf, (unsigned char *) fr_opcode, 0);
      fragP->fr_var = 0;
    }
  else
    {
      /* Here is the fun stuff:  Get the immediate field from this
	 instruction.  If it fits, we're done.  If not, find the next
	 instruction sequence that fits.  */

      IStack istack;
      int i;
      symbolS *lit_sym = NULL;
      int total_size = 0;
      int target_offset = 0;
      int old_size;
      int diff;
      symbolS *gen_label = NULL;
      offsetT frag_offset;
      bfd_boolean first = TRUE;

      /* It does not fit.  Find something that does and
         convert immediately.  */
      frag_offset = fr_opcode - fragP->fr_literal;
      istack_init (&istack);
      xg_assembly_relax (&istack, &orig_tinsn,
			 segP, fragP, frag_offset, min_steps, 0);

      old_size = xtensa_format_length (isa, fmt);

      /* Assemble this right inline.  */

      /* First, create the mapping from a label name to the REAL label.  */
      target_offset = 0;
      for (i = 0; i < istack.ninsn; i++)
	{
	  TInsn *tinsn = &istack.insn[i];
	  fragS *lit_frag;

	  switch (tinsn->insn_type)
	    {
	    case ITYPE_LITERAL:
	      if (lit_sym != NULL)
		as_bad (_("multiple literals in expansion"));
	      /* First find the appropriate space in the literal pool.  */
	      lit_frag = fragP->tc_frag_data.literal_frags[slot];
	      if (lit_frag == NULL)
		as_bad (_("no registered fragment for literal"));
	      if (tinsn->ntok != 1)
		as_bad (_("number of literal tokens != 1"));

	      /* Set the literal symbol and add a fixup.  */
	      lit_sym = lit_frag->fr_symbol;
	      break;

	    case ITYPE_LABEL:
	      if (align_targets && !is_loop)
		{
		  fragS *unreach = fragP->fr_next;
		  while (!(unreach->fr_type == rs_machine_dependent
			   && (unreach->fr_subtype == RELAX_MAYBE_UNREACHABLE
			       || unreach->fr_subtype == RELAX_UNREACHABLE)))
		    {
		      unreach = unreach->fr_next;
		    }

		  gas_assert (unreach->fr_type == rs_machine_dependent
			  && (unreach->fr_subtype == RELAX_MAYBE_UNREACHABLE
			      || unreach->fr_subtype == RELAX_UNREACHABLE));

		  target_offset += unreach->tc_frag_data.text_expansion[0];
		}
	      gas_assert (gen_label == NULL);
	      gen_label = symbol_new (FAKE_LABEL_NAME, now_seg,
				      fr_opcode - fragP->fr_literal
				      + target_offset, fragP);
	      break;

	    case ITYPE_INSN:
	      if (first && from_wide_insn)
		{
		  target_offset += xtensa_format_length (isa, fmt);
		  first = FALSE;
		  if (!opcode_fits_format_slot (tinsn->opcode, fmt, slot))
		    target_offset += xg_get_single_size (tinsn->opcode);
		}
	      else
		target_offset += xg_get_single_size (tinsn->opcode);
	      break;
	    }
	}

      total_size = 0;
      first = TRUE;
      for (i = 0; i < istack.ninsn; i++)
	{
	  TInsn *tinsn = &istack.insn[i];
	  fragS *lit_frag;
	  int size;
	  segT target_seg;
	  bfd_reloc_code_real_type reloc_type;

	  switch (tinsn->insn_type)
	    {
	    case ITYPE_LITERAL:
	      lit_frag = fragP->tc_frag_data.literal_frags[slot];
	      /* Already checked.  */
	      gas_assert (lit_frag != NULL);
	      gas_assert (lit_sym != NULL);
	      gas_assert (tinsn->ntok == 1);
	      /* Add a fixup.  */
	      target_seg = S_GET_SEGMENT (lit_sym);
	      gas_assert (target_seg);
	      reloc_type = map_operator_to_reloc (tinsn->tok[0].X_op, TRUE);
	      fix_new_exp_in_seg (target_seg, 0, lit_frag, 0, 4,
				  &tinsn->tok[0], FALSE, reloc_type);
	      break;

	    case ITYPE_LABEL:
	      break;

	    case ITYPE_INSN:
	      xg_resolve_labels (tinsn, gen_label);
	      xg_resolve_literals (tinsn, lit_sym);
	      if (from_wide_insn && first)
		{
		  first = FALSE;
		  if (opcode_fits_format_slot (tinsn->opcode, fmt, slot))
		    {
		      cur_vinsn.slots[slot] = *tinsn;
		    }
		  else
		    {
		      cur_vinsn.slots[slot].opcode =
			xtensa_format_slot_nop_opcode (isa, fmt, slot);
		      cur_vinsn.slots[slot].ntok = 0;
		    }
		  vinsn_to_insnbuf (&cur_vinsn, immed_instr, fragP, TRUE);
		  xtensa_insnbuf_to_chars (isa, cur_vinsn.insnbuf,
					   (unsigned char *) immed_instr, 0);
		  fragP->tc_frag_data.is_insn = TRUE;
		  size = xtensa_format_length (isa, fmt);
		  if (!opcode_fits_format_slot (tinsn->opcode, fmt, slot))
		    {
		      xg_emit_insn_to_buf
			(tinsn, immed_instr + size, fragP,
			 immed_instr - fragP->fr_literal + size, TRUE);
		      size += xg_get_single_size (tinsn->opcode);
		    }
		}
	      else
		{
		  size = xg_get_single_size (tinsn->opcode);
		  xg_emit_insn_to_buf (tinsn, immed_instr, fragP,
				       immed_instr - fragP->fr_literal, TRUE);
		}
	      immed_instr += size;
	      total_size += size;
	      break;
	    }
	}

      diff = total_size - old_size;
      gas_assert (diff >= 0);
      if (diff != 0)
	expanded = TRUE;
      gas_assert (diff <= fragP->fr_var);
      fragP->fr_var -= diff;
      fragP->fr_fix += diff;
    }

  /* Check for undefined immediates in LOOP instructions.  */
  if (is_loop)
    {
      symbolS *sym;
      sym = orig_tinsn.tok[1].X_add_symbol;
      if (sym != NULL && !S_IS_DEFINED (sym))
	{
	  as_bad (_("unresolved loop target symbol: %s"), S_GET_NAME (sym));
	  return;
	}
      sym = orig_tinsn.tok[1].X_op_symbol;
      if (sym != NULL && !S_IS_DEFINED (sym))
	{
	  as_bad (_("unresolved loop target symbol: %s"), S_GET_NAME (sym));
	  return;
	}
    }

  if (expanded && xtensa_opcode_is_loop (isa, orig_tinsn.opcode) == 1)
    convert_frag_immed_finish_loop (segP, fragP, &orig_tinsn);

  if (expanded && is_direct_call_opcode (orig_tinsn.opcode))
    {
      /* Add an expansion note on the expanded instruction.  */
      fix_new_exp_in_seg (now_seg, 0, fragP, fr_opcode - fragP->fr_literal, 4,
			  &orig_tinsn.tok[0], TRUE,
			  BFD_RELOC_XTENSA_ASM_EXPAND);
    }
}


/* Add a new fix expression into the desired segment.  We have to
   switch to that segment to do this.  */

static fixS *
fix_new_exp_in_seg (segT new_seg,
		    subsegT new_subseg,
		    fragS *frag,
		    int where,
		    int size,
		    expressionS *exp,
		    int pcrel,
		    bfd_reloc_code_real_type r_type)
{
  fixS *new_fix;
  segT seg = now_seg;
  subsegT subseg = now_subseg;

  gas_assert (new_seg != 0);
  subseg_set (new_seg, new_subseg);

  new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
  subseg_set (seg, subseg);
  return new_fix;
}


/* Relax a loop instruction so that it can span loop >256 bytes.

                  loop    as, .L1
          .L0:
                  rsr     as, LEND
                  wsr     as, LBEG
                  addi    as, as, lo8 (label-.L1)
                  addmi   as, as, mid8 (label-.L1)
                  wsr     as, LEND
                  isync
                  rsr     as, LCOUNT
                  addi    as, as, 1
          .L1:
                  <<body>>
          label:
*/

static void
convert_frag_immed_finish_loop (segT segP, fragS *fragP, TInsn *tinsn)
{
  TInsn loop_insn;
  TInsn addi_insn;
  TInsn addmi_insn;
  unsigned long target;
  static xtensa_insnbuf insnbuf = NULL;
  unsigned int loop_length, loop_length_hi, loop_length_lo;
  xtensa_isa isa = xtensa_default_isa;
  addressT loop_offset;
  addressT addi_offset = 9;
  addressT addmi_offset = 12;
  fragS *next_fragP;
  int target_count;

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (isa);

  /* Get the loop offset.  */
  loop_offset = get_expanded_loop_offset (tinsn->opcode);

  /* Validate that there really is a LOOP at the loop_offset.  Because
     loops are not bundleable, we can assume that the instruction will be
     in slot 0.  */
  tinsn_from_chars (&loop_insn, fragP->fr_opcode + loop_offset, 0);
  tinsn_immed_from_frag (&loop_insn, fragP, 0);

  gas_assert (xtensa_opcode_is_loop (isa, loop_insn.opcode) == 1);
  addi_offset += loop_offset;
  addmi_offset += loop_offset;

  gas_assert (tinsn->ntok == 2);
  if (tinsn->tok[1].X_op == O_constant)
    target = tinsn->tok[1].X_add_number;
  else if (tinsn->tok[1].X_op == O_symbol)
    {
      /* Find the fragment.  */
      symbolS *sym = tinsn->tok[1].X_add_symbol;
      gas_assert (S_GET_SEGMENT (sym) == segP
	      || S_GET_SEGMENT (sym) == absolute_section);
      target = (S_GET_VALUE (sym) + tinsn->tok[1].X_add_number);
    }
  else
    {
      as_bad (_("invalid expression evaluation type %d"), tinsn->tok[1].X_op);
      target = 0;
    }

  loop_length = target - (fragP->fr_address + fragP->fr_fix);
  loop_length_hi = loop_length & ~0x0ff;
  loop_length_lo = loop_length & 0x0ff;
  if (loop_length_lo >= 128)
    {
      loop_length_lo -= 256;
      loop_length_hi += 256;
    }

  /* Because addmi sign-extends the immediate, 'loop_length_hi' can be at most
     32512.  If the loop is larger than that, then we just fail.  */
  if (loop_length_hi > 32512)
    as_bad_where (fragP->fr_file, fragP->fr_line,
		  _("loop too long for LOOP instruction"));

  tinsn_from_chars (&addi_insn, fragP->fr_opcode + addi_offset, 0);
  gas_assert (addi_insn.opcode == xtensa_addi_opcode);

  tinsn_from_chars (&addmi_insn, fragP->fr_opcode + addmi_offset, 0);
  gas_assert (addmi_insn.opcode == xtensa_addmi_opcode);

  set_expr_const (&addi_insn.tok[2], loop_length_lo);
  tinsn_to_insnbuf (&addi_insn, insnbuf);

  fragP->tc_frag_data.is_insn = TRUE;
  xtensa_insnbuf_to_chars
    (isa, insnbuf, (unsigned char *) fragP->fr_opcode + addi_offset, 0);

  set_expr_const (&addmi_insn.tok[2], loop_length_hi);
  tinsn_to_insnbuf (&addmi_insn, insnbuf);
  xtensa_insnbuf_to_chars
    (isa, insnbuf, (unsigned char *) fragP->fr_opcode + addmi_offset, 0);

  /* Walk through all of the frags from here to the loop end
     and mark them as no_transform to keep them from being modified
     by the linker.  If we ever have a relocation for the
     addi/addmi of the difference of two symbols we can remove this.  */

  target_count = 0;
  for (next_fragP = fragP; next_fragP != NULL;
       next_fragP = next_fragP->fr_next)
    {
      next_fragP->tc_frag_data.is_no_transform = TRUE;
      if (next_fragP->tc_frag_data.is_loop_target)
	target_count++;
      if (target_count == 2)
	break;
    }
}


/* A map that keeps information on a per-subsegment basis.  This is
   maintained during initial assembly, but is invalid once the
   subsegments are smashed together.  I.E., it cannot be used during
   the relaxation.  */

typedef struct subseg_map_struct
{
  /* the key */
  segT seg;
  subsegT subseg;

  /* the data */
  unsigned flags;
  float total_freq;	/* fall-through + branch target frequency */
  float target_freq;	/* branch target frequency alone */

  struct subseg_map_struct *next;
} subseg_map;


static subseg_map *sseg_map = NULL;

static subseg_map *
get_subseg_info (segT seg, subsegT subseg)
{
  subseg_map *subseg_e;

  for (subseg_e = sseg_map; subseg_e; subseg_e = subseg_e->next)
    {
      if (seg == subseg_e->seg && subseg == subseg_e->subseg)
	break;
    }
  return subseg_e;
}


static subseg_map *
add_subseg_info (segT seg, subsegT subseg)
{
  subseg_map *subseg_e = XNEW (subseg_map);
  memset (subseg_e, 0, sizeof (subseg_map));
  subseg_e->seg = seg;
  subseg_e->subseg = subseg;
  subseg_e->flags = 0;
  /* Start off considering every branch target very important.  */
  subseg_e->target_freq = 1.0;
  subseg_e->total_freq = 1.0;
  subseg_e->next = sseg_map;
  sseg_map = subseg_e;
  return subseg_e;
}


static unsigned
get_last_insn_flags (segT seg, subsegT subseg)
{
  subseg_map *subseg_e = get_subseg_info (seg, subseg);
  if (subseg_e)
    return subseg_e->flags;
  return 0;
}


static void
set_last_insn_flags (segT seg,
		     subsegT subseg,
		     unsigned fl,
		     bfd_boolean val)
{
  subseg_map *subseg_e = get_subseg_info (seg, subseg);
  if (! subseg_e)
    subseg_e = add_subseg_info (seg, subseg);
  if (val)
    subseg_e->flags |= fl;
  else
    subseg_e->flags &= ~fl;
}


static float
get_subseg_total_freq (segT seg, subsegT subseg)
{
  subseg_map *subseg_e = get_subseg_info (seg, subseg);
  if (subseg_e)
    return subseg_e->total_freq;
  return 1.0;
}


static float
get_subseg_target_freq (segT seg, subsegT subseg)
{
  subseg_map *subseg_e = get_subseg_info (seg, subseg);
  if (subseg_e)
    return subseg_e->target_freq;
  return 1.0;
}


static void
set_subseg_freq (segT seg, subsegT subseg, float total_f, float target_f)
{
  subseg_map *subseg_e = get_subseg_info (seg, subseg);
  if (! subseg_e)
    subseg_e = add_subseg_info (seg, subseg);
  subseg_e->total_freq = total_f;
  subseg_e->target_freq = target_f;
}


/* Segment Lists and emit_state Stuff.  */

static void
xtensa_move_seg_list_to_beginning (seg_list *head)
{
  head = head->next;
  while (head)
    {
      segT literal_section = head->seg;

      /* Move the literal section to the front of the section list.  */
      gas_assert (literal_section);
      if (literal_section != stdoutput->sections)
	{
	  bfd_section_list_remove (stdoutput, literal_section);
	  bfd_section_list_prepend (stdoutput, literal_section);
	}
      head = head->next;
    }
}


static void mark_literal_frags (seg_list *);

static void
xtensa_move_literals (void)
{
  seg_list *segment;
  frchainS *frchain_from, *frchain_to;
  fragS *search_frag, *next_frag, *literal_pool, *insert_after;
  fragS **frag_splice;
  emit_state state;
  segT dest_seg;
  fixS *fix, *next_fix, **fix_splice;
  sym_list *lit;
  struct litpool_seg *lps;
  const char *init_name = INIT_SECTION_NAME;
  const char *fini_name = FINI_SECTION_NAME;
  int init_name_len = strlen(init_name);
  int fini_name_len = strlen(fini_name);

  mark_literal_frags (literal_head->next);

  if (use_literal_section)
    return;

  /* Assign addresses (rough estimates) to the potential literal pool locations
     and create new ones if the gaps are too large.  */

  for (lps = litpool_seg_list.next; lps; lps = lps->next)
    {
      frchainS *frchP = seg_info (lps->seg)->frchainP;
      struct litpool_frag *lpf = lps->frag_list.next;
      addressT addr = 0;

      for ( ; frchP; frchP = frchP->frch_next)
	{
	  fragS *fragP;
	  for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
	    {
	      if (lpf && fragP == lpf->fragP)
		{
		  gas_assert(fragP->fr_type == rs_machine_dependent &&
			     (fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN ||
			      fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN));
		  /* Found a litpool location.  */
		  lpf->addr = addr;
		  lpf = lpf->next;
		}
	      if (fragP->fr_type == rs_machine_dependent &&
		  fragP->fr_subtype == RELAX_SLOTS)
		{
		  int slot;
		  for (slot = 0; slot < MAX_SLOTS; slot++)
		    {
		      if (fragP->tc_frag_data.literal_frags[slot])
			{
			  /* L32R; point its literal to the nearest litpool
			     preferring non-"candidate" positions to avoid
			     the jump-around.  */
			  fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];
			  struct litpool_frag *lp = lpf->prev;
			  if (!lp->fragP)
			    {
			      break;
			    }
			  while (lp->fragP->fr_subtype ==
				 RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
			    {
			      lp = lp->prev;
			      if (lp->fragP == NULL)
				{
				  /* End of list; have to bite the bullet.
				     Take the nearest.  */
				  lp = lpf->prev;
				  break;
				}
			      /* Does it (conservatively) reach?  */
			      if (addr - lp->addr <= 128 * 1024)
				{
				  if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
				    {
				      /* Found a good one.  */
				      break;
				    }
				  else if (lp->prev->fragP &&
					   addr - lp->prev->addr > 128 * 1024)
				    {
				      /* This is still a "candidate" but the next one
				         will be too far away, so revert to the nearest
					 one, convert it and add the jump around.  */
				      fragS *poolbeg;
				      fragS *poolend;
				      symbolS *lsym;
				      char label[10 + 2 * sizeof (fragS *)];
				      lp = lpf->prev;
				      poolbeg = lp->fragP;
				      lp->priority = 1;
				      poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN;
				      poolend = poolbeg->fr_next;
				      gas_assert (poolend->fr_type == rs_machine_dependent &&
						  poolend->fr_subtype == RELAX_LITERAL_POOL_END);
				      /* Create a local symbol pointing to the
				         end of the pool.  */
				      sprintf (label, ".L0_LT_%p", poolbeg);
				      lsym = (symbolS *)local_symbol_make (label, lps->seg,
									   0, poolend);
				      poolbeg->fr_symbol = lsym;
				      /* Rest is done in xtensa_relax_frag.  */
				    }
				}
			    }
			  if (! litfrag->tc_frag_data.literal_frag)
			    {
			      /* Take earliest use of this literal to avoid
				 forward refs.  */
			      litfrag->tc_frag_data.literal_frag = lp->fragP;
			    }
			}
		    }
		}
	      addr += fragP->fr_fix;
	      if (fragP->fr_type == rs_fill)
		addr += fragP->fr_offset;
	    }
	}
    }

  for (segment = literal_head->next; segment; segment = segment->next)
    {
      const char *seg_name = segment_name (segment->seg);

      /* Keep the literals for .init and .fini in separate sections.  */
      if ((!memcmp (seg_name, init_name, init_name_len) &&
	   !strcmp (seg_name + init_name_len, ".literal")) ||
	  (!memcmp (seg_name, fini_name, fini_name_len) &&
	   !strcmp (seg_name + fini_name_len, ".literal")))
	continue;

      frchain_from = seg_info (segment->seg)->frchainP;
      search_frag = frchain_from->frch_root;
      literal_pool = NULL;
      frchain_to = NULL;
      frag_splice = &(frchain_from->frch_root);

      while (search_frag && !search_frag->tc_frag_data.literal_frag)
	{
	  gas_assert (search_frag->fr_fix == 0
		  || search_frag->fr_type == rs_align);
	  search_frag = search_frag->fr_next;
	}

      if (!search_frag)
	{
	  search_frag = frchain_from->frch_root;
	  as_bad_where (search_frag->fr_file, search_frag->fr_line,
			_("literal pool location required for text-section-literals; specify with .literal_position"));
	  continue;
	}

      gas_assert (search_frag->tc_frag_data.literal_frag->fr_subtype
	      == RELAX_LITERAL_POOL_BEGIN);
      xtensa_switch_section_emit_state (&state, segment->seg, 0);

      /* Make sure that all the frags in this series are closed, and
	 that there is at least one left over of zero-size.  This
	 prevents us from making a segment with an frchain without any
	 frags in it.  */
      frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
      xtensa_set_frag_assembly_state (frag_now);
      frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
      xtensa_set_frag_assembly_state (frag_now);

      while (search_frag != frag_now)
	{
	  next_frag = search_frag->fr_next;
	  if (search_frag->tc_frag_data.literal_frag)
	    {
	      literal_pool = search_frag->tc_frag_data.literal_frag;
	      gas_assert (literal_pool->fr_subtype == RELAX_LITERAL_POOL_BEGIN);
	      frchain_to = literal_pool->tc_frag_data.lit_frchain;
	      gas_assert (frchain_to);
	    }

	  if (search_frag->fr_type == rs_fill && search_frag->fr_fix == 0)
	    {
	      /* Skip empty fill frags.  */
	      *frag_splice = next_frag;
	      search_frag = next_frag;
	      continue;
	    }

	  if (search_frag->fr_type == rs_align)
	    {
	      /* Skip alignment frags, because the pool as a whole will be
	         aligned if used, and we don't want to force alignment if the
		 pool is unused.  */
	      *frag_splice = next_frag;
	      search_frag = next_frag;
	      continue;
	    }

	  /* First, move the frag out of the literal section and
	     to the appropriate place.  */

	  /* Insert an aligmnent frag at start of pool.  */
	  if (literal_pool->fr_next->fr_type == rs_machine_dependent &&
	      literal_pool->fr_next->fr_subtype == RELAX_LITERAL_POOL_END)
	    {
	      segT pool_seg = literal_pool->fr_next->tc_frag_data.lit_seg;
	      emit_state prev_state;
	      fragS *prev_frag;
	      fragS *align_frag;
	      xtensa_switch_section_emit_state (&prev_state, pool_seg, 0);
	      prev_frag = frag_now;
	      frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
	      align_frag = frag_now;
	      frag_align (2, 0, 0);
	      /* Splice it into the right place.  */
	      prev_frag->fr_next = align_frag->fr_next;
	      align_frag->fr_next = literal_pool->fr_next;
	      literal_pool->fr_next = align_frag;
	      /* Insert after this one.  */
	      literal_pool->tc_frag_data.literal_frag = align_frag;
	      xtensa_restore_emit_state (&prev_state);
	    }
	  insert_after = literal_pool->tc_frag_data.literal_frag;
	  dest_seg = insert_after->fr_next->tc_frag_data.lit_seg;
	  /* Skip align frag.  */
	  if (insert_after->fr_next->fr_type == rs_align)
	    {
	      insert_after = insert_after->fr_next;
	    }

	  *frag_splice = next_frag;
	  search_frag->fr_next = insert_after->fr_next;
	  insert_after->fr_next = search_frag;
	  search_frag->tc_frag_data.lit_seg = dest_seg;
	  literal_pool->tc_frag_data.literal_frag = search_frag;

	  /* Now move any fixups associated with this frag to the
	     right section.  */
	  fix = frchain_from->fix_root;
	  fix_splice = &(frchain_from->fix_root);
	  while (fix)
	    {
	      next_fix = fix->fx_next;
	      if (fix->fx_frag == search_frag)
		{
		  *fix_splice = next_fix;
		  fix->fx_next = frchain_to->fix_root;
		  frchain_to->fix_root = fix;
		  if (frchain_to->fix_tail == NULL)
		    frchain_to->fix_tail = fix;
		}
	      else
		fix_splice = &(fix->fx_next);
	      fix = next_fix;
	    }
	  search_frag = next_frag;
	}

      if (frchain_from->fix_root != NULL)
	{
	  frchain_from = seg_info (segment->seg)->frchainP;
	  as_warn (_("fixes not all moved from %s"), segment->seg->name);

	  gas_assert (frchain_from->fix_root == NULL);
	}
      frchain_from->fix_tail = NULL;
      xtensa_restore_emit_state (&state);
    }

  /* Now fix up the SEGMENT value for all the literal symbols.  */
  for (lit = literal_syms; lit; lit = lit->next)
    {
      symbolS *lit_sym = lit->sym;
      segT dseg = symbol_get_frag (lit_sym)->tc_frag_data.lit_seg;
      if (dseg)
	S_SET_SEGMENT (lit_sym, dseg);
    }
}


/* Walk over all the frags for segments in a list and mark them as
   containing literals.  As clunky as this is, we can't rely on frag_var
   and frag_variant to get called in all situations.  */

static void
mark_literal_frags (seg_list *segment)
{
  frchainS *frchain_from;
  fragS *search_frag;

  while (segment)
    {
      frchain_from = seg_info (segment->seg)->frchainP;
      search_frag = frchain_from->frch_root;
      while (search_frag)
	{
	  search_frag->tc_frag_data.is_literal = TRUE;
	  search_frag = search_frag->fr_next;
	}
      segment = segment->next;
    }
}


static void
xtensa_reorder_seg_list (seg_list *head, segT after)
{
  /* Move all of the sections in the section list to come
     after "after" in the gnu segment list.  */

  head = head->next;
  while (head)
    {
      segT literal_section = head->seg;

      /* Move the literal section after "after".  */
      gas_assert (literal_section);
      if (literal_section != after)
	{
	  bfd_section_list_remove (stdoutput, literal_section);
	  bfd_section_list_insert_after (stdoutput, after, literal_section);
	}

      head = head->next;
    }
}


/* Push all the literal segments to the end of the gnu list.  */

static void
xtensa_reorder_segments (void)
{
  segT sec;
  segT last_sec = 0;
  int old_count = 0;
  int new_count = 0;

  for (sec = stdoutput->sections; sec != NULL; sec = sec->next)
    {
      last_sec = sec;
      old_count++;
    }

  /* Now that we have the last section, push all the literal
     sections to the end.  */
  xtensa_reorder_seg_list (literal_head, last_sec);

  /* Now perform the final error check.  */
  for (sec = stdoutput->sections; sec != NULL; sec = sec->next)
    new_count++;
  gas_assert (new_count == old_count);
}


/* Change the emit state (seg, subseg, and frag related stuff) to the
   correct location.  Return a emit_state which can be passed to
   xtensa_restore_emit_state to return to current fragment.  */

static void
xtensa_switch_to_literal_fragment (emit_state *result)
{
  if (directive_state[directive_absolute_literals])
    {
      segT lit4_seg = cache_literal_section (TRUE);
      xtensa_switch_section_emit_state (result, lit4_seg, 0);
    }
  else
    xtensa_switch_to_non_abs_literal_fragment (result);

  /* Do a 4-byte align here.  */
  frag_align (2, 0, 0);
  record_alignment (now_seg, 2);
}


static void
xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
{
  static bfd_boolean recursive = FALSE;
  fragS *pool_location = get_literal_pool_location (now_seg);
  segT lit_seg;
  bfd_boolean is_init =
    (now_seg && !strcmp (segment_name (now_seg), INIT_SECTION_NAME));
  bfd_boolean is_fini =
    (now_seg && !strcmp (segment_name (now_seg), FINI_SECTION_NAME));

  if (pool_location == NULL
      && !use_literal_section
      && !recursive
      && !is_init && ! is_fini)
    {
      if (!auto_litpools)
	{
	  as_bad (_("literal pool location required for text-section-literals; specify with .literal_position"));
	}

      /* When we mark a literal pool location, we want to put a frag in
	 the literal pool that points to it.  But to do that, we want to
	 switch_to_literal_fragment.  But literal sections don't have
	 literal pools, so their location is always null, so we would
	 recurse forever.  This is kind of hacky, but it works.  */

      recursive = TRUE;
      xtensa_mark_literal_pool_location ();
      recursive = FALSE;
    }

  lit_seg = cache_literal_section (FALSE);
  xtensa_switch_section_emit_state (result, lit_seg, 0);

  if (!use_literal_section
      && !is_init && !is_fini
      && get_literal_pool_location (now_seg) != pool_location)
    {
      /* Close whatever frag is there.  */
      frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
      xtensa_set_frag_assembly_state (frag_now);
      frag_now->tc_frag_data.literal_frag = pool_location;
      frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
      xtensa_set_frag_assembly_state (frag_now);
    }
}


/* Call this function before emitting data into the literal section.
   This is a helper function for xtensa_switch_to_literal_fragment.
   This is similar to a .section new_now_seg subseg. */

static void
xtensa_switch_section_emit_state (emit_state *state,
				  segT new_now_seg,
				  subsegT new_now_subseg)
{
  state->name = now_seg->name;
  state->now_seg = now_seg;
  state->now_subseg = now_subseg;
  state->generating_literals = generating_literals;
  generating_literals++;
  subseg_set (new_now_seg, new_now_subseg);
}


/* Use to restore the emitting into the normal place.  */

static void
xtensa_restore_emit_state (emit_state *state)
{
  generating_literals = state->generating_literals;
  subseg_set (state->now_seg, state->now_subseg);
}


/* Predicate function used to look up a section in a particular group.  */

static bfd_boolean
match_section_group (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
{
  const char *gname = inf;
  const char *group_name = elf_group_name (sec);

  return (group_name == gname
	  || (group_name != NULL
	      && gname != NULL
	      && strcmp (group_name, gname) == 0));
}


/* Get the literal section to be used for the current text section.
   The result may be cached in the default_lit_sections structure.  */

static segT
cache_literal_section (bfd_boolean use_abs_literals)
{
  const char *text_name, *group_name = 0;
  const char *base_name, *suffix;
  char *name;
  segT *pcached;
  segT seg, current_section;
  int current_subsec;
  bfd_boolean linkonce = FALSE;

  /* Save the current section/subsection.  */
  current_section = now_seg;
  current_subsec = now_subseg;

  /* Clear the cached values if they are no longer valid.  */
  if (now_seg != default_lit_sections.current_text_seg)
    {
      default_lit_sections.current_text_seg = now_seg;
      default_lit_sections.lit_seg = NULL;
      default_lit_sections.lit4_seg = NULL;
    }

  /* Check if the literal section is already cached.  */
  if (use_abs_literals)
    pcached = &default_lit_sections.lit4_seg;
  else
    pcached = &default_lit_sections.lit_seg;

  if (*pcached)
    return *pcached;

  text_name = default_lit_sections.lit_prefix;
  if (! text_name || ! *text_name)
    {
      text_name = segment_name (current_section);
      group_name = elf_group_name (current_section);
      linkonce = (current_section->flags & SEC_LINK_ONCE) != 0;
    }

  base_name = use_abs_literals ? ".lit4" : ".literal";
  if (group_name)
    {
      name = concat (base_name, ".", group_name, (char *) NULL);
    }
  else if (strncmp (text_name, ".gnu.linkonce.", linkonce_len) == 0)
    {
      suffix = strchr (text_name + linkonce_len, '.');

      name = concat (".gnu.linkonce", base_name, suffix ? suffix : "",
		     (char *) NULL);
      linkonce = TRUE;
    }
  else
    {
      /* If the section name begins or ends with ".text", then replace
	 that portion instead of appending an additional suffix.  */
      size_t len = strlen (text_name);
      if (len >= 5
	  && (strcmp (text_name + len - 5, ".text") == 0
	      || strncmp (text_name, ".text", 5) == 0))
	len -= 5;

      name = XNEWVEC (char, len + strlen (base_name) + 1);
      if (strncmp (text_name, ".text", 5) == 0)
	{
	  strcpy (name, base_name);
	  strcat (name, text_name + 5);
	}
      else
	{
	  strcpy (name, text_name);
	  strcpy (name + len, base_name);
	}
    }

  /* Canonicalize section names to allow renaming literal sections.
     The group name, if any, came from the current text section and
     has already been canonicalized.  */
  name = tc_canonicalize_symbol_name (name);

  seg = bfd_get_section_by_name_if (stdoutput, name, match_section_group,
				    (void *) group_name);
  if (! seg)
    {
      flagword flags;

      seg = subseg_force_new (name, 0);

      if (! use_abs_literals)
	{
	  /* Add the newly created literal segment to the list.  */
	  seg_list *n = XNEW (seg_list);
	  n->seg = seg;
	  n->next = literal_head->next;
	  literal_head->next = n;
	}

      flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC | SEC_LOAD
	       | (linkonce ? (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD) : 0)
	       | (use_abs_literals ? SEC_DATA : SEC_CODE));

      elf_group_name (seg) = group_name;

      bfd_set_section_flags (stdoutput, seg, flags);
      bfd_set_section_alignment (stdoutput, seg, 2);
    }

  *pcached = seg;
  subseg_set (current_section, current_subsec);
  return seg;
}


/* Property Tables Stuff.  */

#define XTENSA_INSN_SEC_NAME ".xt.insn"
#define XTENSA_LIT_SEC_NAME ".xt.lit"
#define XTENSA_PROP_SEC_NAME ".xt.prop"

typedef bfd_boolean (*frag_predicate) (const fragS *);
typedef void (*frag_flags_fn) (const fragS *, frag_flags *);

static bfd_boolean get_frag_is_literal (const fragS *);
static void xtensa_create_property_segments
  (frag_predicate, frag_predicate, const char *, xt_section_type);
static void xtensa_create_xproperty_segments
  (frag_flags_fn, const char *, xt_section_type);
static bfd_boolean exclude_section_from_property_tables (segT);
static bfd_boolean section_has_property (segT, frag_predicate);
static bfd_boolean section_has_xproperty (segT, frag_flags_fn);
static void add_xt_block_frags
  (segT, xtensa_block_info **, frag_predicate, frag_predicate);
static bfd_boolean xtensa_frag_flags_is_empty (const frag_flags *);
static void xtensa_frag_flags_init (frag_flags *);
static void get_frag_property_flags (const fragS *, frag_flags *);
static flagword frag_flags_to_number (const frag_flags *);
static void add_xt_prop_frags (segT, xtensa_block_info **, frag_flags_fn);

/* Set up property tables after relaxation.  */

void
xtensa_post_relax_hook (void)
{
  xtensa_move_seg_list_to_beginning (literal_head);

  xtensa_find_unmarked_state_frags ();
  xtensa_mark_frags_for_org ();
  xtensa_mark_difference_of_two_symbols ();

  xtensa_create_property_segments (get_frag_is_literal,
				   NULL,
				   XTENSA_LIT_SEC_NAME,
				   xt_literal_sec);
  xtensa_create_xproperty_segments (get_frag_property_flags,
				    XTENSA_PROP_SEC_NAME,
				    xt_prop_sec);

  if (warn_unaligned_branch_targets)
    bfd_map_over_sections (stdoutput, xtensa_find_unaligned_branch_targets, 0);
  bfd_map_over_sections (stdoutput, xtensa_find_unaligned_loops, 0);
}


/* This function is only meaningful after xtensa_move_literals.  */

static bfd_boolean
get_frag_is_literal (const fragS *fragP)
{
  gas_assert (fragP != NULL);
  return fragP->tc_frag_data.is_literal;
}


static void
xtensa_create_property_segments (frag_predicate property_function,
				 frag_predicate end_property_function,
				 const char *section_name_base,
				 xt_section_type sec_type)
{
  segT *seclist;

  /* Walk over all of the current segments.
     Walk over each fragment
     For each non-empty fragment,
     Build a property record (append where possible).  */

  for (seclist = &stdoutput->sections;
       seclist && *seclist;
       seclist = &(*seclist)->next)
    {
      segT sec = *seclist;

      if (exclude_section_from_property_tables (sec))
	continue;

      if (section_has_property (sec, property_function))
	{
	  segment_info_type *xt_seg_info;
	  xtensa_block_info **xt_blocks;
	  segT prop_sec = xtensa_make_property_section (sec, section_name_base);

	  prop_sec->output_section = prop_sec;
	  subseg_set (prop_sec, 0);
	  xt_seg_info = seg_info (prop_sec);
	  xt_blocks = &xt_seg_info->tc_segment_info_data.blocks[sec_type];

	  /* Walk over all of the frchains here and add new sections.  */
	  add_xt_block_frags (sec, xt_blocks, property_function,
			      end_property_function);
	}
    }

  /* Now we fill them out....  */

  for (seclist = &stdoutput->sections;
       seclist && *seclist;
       seclist = &(*seclist)->next)
    {
      segment_info_type *seginfo;
      xtensa_block_info *block;
      segT sec = *seclist;

      seginfo = seg_info (sec);
      block = seginfo->tc_segment_info_data.blocks[sec_type];

      if (block)
	{
	  xtensa_block_info *cur_block;
	  int num_recs = 0;
	  bfd_size_type rec_size;

	  for (cur_block = block; cur_block; cur_block = cur_block->next)
	    num_recs++;

	  rec_size = num_recs * 8;
	  bfd_set_section_size (stdoutput, sec, rec_size);

	  if (num_recs)
	    {
	      char *frag_data;
	      int i;

	      subseg_set (sec, 0);
	      frag_data = frag_more (rec_size);
	      cur_block = block;
	      for (i = 0; i < num_recs; i++)
		{
		  fixS *fix;

		  /* Write the fixup.  */
		  gas_assert (cur_block);
		  fix = fix_new (frag_now, i * 8, 4,
				 section_symbol (cur_block->sec),
				 cur_block->offset,
				 FALSE, BFD_RELOC_32);
		  fix->fx_file = "<internal>";
		  fix->fx_line = 0;

		  /* Write the length.  */
		  md_number_to_chars (&frag_data[4 + i * 8],
				      cur_block->size, 4);
		  cur_block = cur_block->next;
		}
	      frag_wane (frag_now);
	      frag_new (0);
	      frag_wane (frag_now);
	    }
	}
    }
}


static void
xtensa_create_xproperty_segments (frag_flags_fn flag_fn,
				  const char *section_name_base,
				  xt_section_type sec_type)
{
  segT *seclist;

  /* Walk over all of the current segments.
     Walk over each fragment.
     For each fragment that has instructions,
     build an instruction record (append where possible).  */

  for (seclist = &stdoutput->sections;
       seclist && *seclist;
       seclist = &(*seclist)->next)
    {
      segT sec = *seclist;

      if (exclude_section_from_property_tables (sec))
	continue;

      if (section_has_xproperty (sec, flag_fn))
	{
	  segment_info_type *xt_seg_info;
	  xtensa_block_info **xt_blocks;
	  segT prop_sec = xtensa_make_property_section (sec, section_name_base);

	  prop_sec->output_section = prop_sec;
	  subseg_set (prop_sec, 0);
	  xt_seg_info = seg_info (prop_sec);
	  xt_blocks = &xt_seg_info->tc_segment_info_data.blocks[sec_type];

	  /* Walk over all of the frchains here and add new sections.  */
	  add_xt_prop_frags (sec, xt_blocks, flag_fn);
	}
    }

  /* Now we fill them out....  */

  for (seclist = &stdoutput->sections;
       seclist && *seclist;
       seclist = &(*seclist)->next)
    {
      segment_info_type *seginfo;
      xtensa_block_info *block;
      segT sec = *seclist;

      seginfo = seg_info (sec);
      block = seginfo->tc_segment_info_data.blocks[sec_type];

      if (block)
	{
	  xtensa_block_info *cur_block;
	  int num_recs = 0;
	  bfd_size_type rec_size;

	  for (cur_block = block; cur_block; cur_block = cur_block->next)
	    num_recs++;

	  rec_size = num_recs * (8 + 4);
	  bfd_set_section_size (stdoutput, sec, rec_size);
	  /* elf_section_data (sec)->this_hdr.sh_entsize = 12; */

	  if (num_recs)
	    {
	      char *frag_data;
	      int i;

	      subseg_set (sec, 0);
	      frag_data = frag_more (rec_size);
	      cur_block = block;
	      for (i = 0; i < num_recs; i++)
		{
		  fixS *fix;

		  /* Write the fixup.  */
		  gas_assert (cur_block);
		  fix = fix_new (frag_now, i * 12, 4,
				 section_symbol (cur_block->sec),
				 cur_block->offset,
				 FALSE, BFD_RELOC_32);
		  fix->fx_file = "<internal>";
		  fix->fx_line = 0;

		  /* Write the length.  */
		  md_number_to_chars (&frag_data[4 + i * 12],
				      cur_block->size, 4);
		  md_number_to_chars (&frag_data[8 + i * 12],
				      frag_flags_to_number (&cur_block->flags),
				      sizeof (flagword));
		  cur_block = cur_block->next;
		}
	      frag_wane (frag_now);
	      frag_new (0);
	      frag_wane (frag_now);
	    }
	}
    }
}


static bfd_boolean
exclude_section_from_property_tables (segT sec)
{
  flagword flags = bfd_get_section_flags (stdoutput, sec);

  /* Sections that don't contribute to the memory footprint are excluded.  */
  if ((flags & SEC_DEBUGGING)
      || !(flags & SEC_ALLOC)
      || (flags & SEC_MERGE))
    return TRUE;

  /* Linker cie and fde optimizations mess up property entries for
     eh_frame sections, but there is nothing inside them relevant to
     property tables anyway.  */
  if (strcmp (sec->name, ".eh_frame") == 0)
    return TRUE;

  return FALSE;
}


static bfd_boolean
section_has_property (segT sec, frag_predicate property_function)
{
  segment_info_type *seginfo = seg_info (sec);
  fragS *fragP;

  if (seginfo && seginfo->frchainP)
    {
      for (fragP = seginfo->frchainP->frch_root; fragP; fragP = fragP->fr_next)
	{
	  if (property_function (fragP)
	      && (fragP->fr_type != rs_fill || fragP->fr_fix != 0))
	    return TRUE;
	}
    }
  return FALSE;
}


static bfd_boolean
section_has_xproperty (segT sec, frag_flags_fn property_function)
{
  segment_info_type *seginfo = seg_info (sec);
  fragS *fragP;

  if (seginfo && seginfo->frchainP)
    {
      for (fragP = seginfo->frchainP->frch_root; fragP; fragP = fragP->fr_next)
	{
	  frag_flags prop_flags;
	  property_function (fragP, &prop_flags);
	  if (!xtensa_frag_flags_is_empty (&prop_flags))
	    return TRUE;
	}
    }
  return FALSE;
}


/* Two types of block sections exist right now: literal and insns.  */

static void
add_xt_block_frags (segT sec,
		    xtensa_block_info **xt_block,
		    frag_predicate property_function,
		    frag_predicate end_property_function)
{
  fragS *fragP;

  /* Build it if needed.  */
  while (*xt_block != NULL)
    xt_block = &(*xt_block)->next;
  /* We are either at NULL at the beginning or at the end.  */

  /* Walk through the frags.  */
  if (seg_info (sec)->frchainP)
    {
      for (fragP = seg_info (sec)->frchainP->frch_root;
	   fragP;
	   fragP = fragP->fr_next)
	{
	  if (property_function (fragP)
	      && (fragP->fr_type != rs_fill || fragP->fr_fix != 0))
	    {
	      if (*xt_block != NULL)
		{
		  if ((*xt_block)->offset + (*xt_block)->size
		      == fragP->fr_address)
		    (*xt_block)->size += fragP->fr_fix;
		  else
		    xt_block = &((*xt_block)->next);
		}
	      if (*xt_block == NULL)
		{
		  xtensa_block_info *new_block = XNEW (xtensa_block_info);
		  new_block->sec = sec;
		  new_block->offset = fragP->fr_address;
		  new_block->size = fragP->fr_fix;
		  new_block->next = NULL;
		  xtensa_frag_flags_init (&new_block->flags);
		  *xt_block = new_block;
		}
	      if (end_property_function
		  && end_property_function (fragP))
		{
		  xt_block = &((*xt_block)->next);
		}
	    }
	}
    }
}


/* Break the encapsulation of add_xt_prop_frags here.  */

static bfd_boolean
xtensa_frag_flags_is_empty (const frag_flags *prop_flags)
{
  if (prop_flags->is_literal
      || prop_flags->is_insn
      || prop_flags->is_data
      || prop_flags->is_unreachable)
    return FALSE;
  return TRUE;
}


static void
xtensa_frag_flags_init (frag_flags *prop_flags)
{
  memset (prop_flags, 0, sizeof (frag_flags));
}


static void
get_frag_property_flags (const fragS *fragP, frag_flags *prop_flags)
{
  xtensa_frag_flags_init (prop_flags);
  if (fragP->tc_frag_data.is_literal)
    prop_flags->is_literal = TRUE;
  if (fragP->tc_frag_data.is_specific_opcode
      || fragP->tc_frag_data.is_no_transform)
    {
      prop_flags->is_no_transform = TRUE;
      if (xtensa_frag_flags_is_empty (prop_flags))
	prop_flags->is_data = TRUE;
    }
  if (fragP->tc_frag_data.is_unreachable)
    prop_flags->is_unreachable = TRUE;
  else if (fragP->tc_frag_data.is_insn)
    {
      prop_flags->is_insn = TRUE;
      if (fragP->tc_frag_data.is_loop_target)
	prop_flags->insn.is_loop_target = TRUE;
      if (fragP->tc_frag_data.is_branch_target)
	prop_flags->insn.is_branch_target = TRUE;
      if (fragP->tc_frag_data.is_no_density)
	prop_flags->insn.is_no_density = TRUE;
      if (fragP->tc_frag_data.use_absolute_literals)
	prop_flags->insn.is_abslit = TRUE;
    }
  if (fragP->tc_frag_data.is_align)
    {
      prop_flags->is_align = TRUE;
      prop_flags->alignment = fragP->tc_frag_data.alignment;
      if (xtensa_frag_flags_is_empty (prop_flags))
	prop_flags->is_data = TRUE;
    }
}


static flagword
frag_flags_to_number (const frag_flags *prop_flags)
{
  flagword num = 0;
  if (prop_flags->is_literal)
    num |= XTENSA_PROP_LITERAL;
  if (prop_flags->is_insn)
    num |= XTENSA_PROP_INSN;
  if (prop_flags->is_data)
    num |= XTENSA_PROP_DATA;
  if (prop_flags->is_unreachable)
    num |= XTENSA_PROP_UNREACHABLE;
  if (prop_flags->insn.is_loop_target)
    num |= XTENSA_PROP_INSN_LOOP_TARGET;
  if (prop_flags->insn.is_branch_target)
    {
      num |= XTENSA_PROP_INSN_BRANCH_TARGET;
      num = SET_XTENSA_PROP_BT_ALIGN (num, prop_flags->insn.bt_align_priority);
    }

  if (prop_flags->insn.is_no_density)
    num |= XTENSA_PROP_INSN_NO_DENSITY;
  if (prop_flags->is_no_transform)
    num |= XTENSA_PROP_NO_TRANSFORM;
  if (prop_flags->insn.is_no_reorder)
    num |= XTENSA_PROP_INSN_NO_REORDER;
  if (prop_flags->insn.is_abslit)
    num |= XTENSA_PROP_INSN_ABSLIT;

  if (prop_flags->is_align)
    {
      num |= XTENSA_PROP_ALIGN;
      num = SET_XTENSA_PROP_ALIGNMENT (num, prop_flags->alignment);
    }

  return num;
}


static bfd_boolean
xtensa_frag_flags_combinable (const frag_flags *prop_flags_1,
			      const frag_flags *prop_flags_2)
{
  /* Cannot combine with an end marker.  */

  if (prop_flags_1->is_literal != prop_flags_2->is_literal)
    return FALSE;
  if (prop_flags_1->is_insn != prop_flags_2->is_insn)
    return FALSE;
  if (prop_flags_1->is_data != prop_flags_2->is_data)
    return FALSE;

  if (prop_flags_1->is_insn)
    {
      /* Properties of the beginning of the frag.  */
      if (prop_flags_2->insn.is_loop_target)
	return FALSE;
      if (prop_flags_2->insn.is_branch_target)
	return FALSE;
      if (prop_flags_1->insn.is_no_density !=
	  prop_flags_2->insn.is_no_density)
	return FALSE;
      if (prop_flags_1->is_no_transform !=
	  prop_flags_2->is_no_transform)
	return FALSE;
      if (prop_flags_1->insn.is_no_reorder !=
	  prop_flags_2->insn.is_no_reorder)
	return FALSE;
      if (prop_flags_1->insn.is_abslit !=
	  prop_flags_2->insn.is_abslit)
	return FALSE;
    }

  if (prop_flags_1->is_align)
    return FALSE;

  return TRUE;
}


static bfd_vma
xt_block_aligned_size (const xtensa_block_info *xt_block)
{
  bfd_vma end_addr;
  unsigned align_bits;

  if (!xt_block->flags.is_align)
    return xt_block->size;

  end_addr = xt_block->offset + xt_block->size;
  align_bits = xt_block->flags.alignment;
  end_addr = ((end_addr + ((1 << align_bits) -1)) >> align_bits) << align_bits;
  return end_addr - xt_block->offset;
}


static bfd_boolean
xtensa_xt_block_combine (xtensa_block_info *xt_block,
			 const xtensa_block_info *xt_block_2)
{
  if (xt_block->sec != xt_block_2->sec)
    return FALSE;
  if (xt_block->offset + xt_block_aligned_size (xt_block)
      != xt_block_2->offset)
    return FALSE;

  if (xt_block_2->size == 0
      && (!xt_block_2->flags.is_unreachable
	  || xt_block->flags.is_unreachable))
    {
      if (xt_block_2->flags.is_align
	  && xt_block->flags.is_align)
	{
	  /* Nothing needed.  */
	  if (xt_block->flags.alignment >= xt_block_2->flags.alignment)
	    return TRUE;
	}
      else
	{
	  if (xt_block_2->flags.is_align)
	    {
	      /* Push alignment to previous entry.  */
	      xt_block->flags.is_align = xt_block_2->flags.is_align;
	      xt_block->flags.alignment = xt_block_2->flags.alignment;
	    }
	  return TRUE;
	}
    }
  if (!xtensa_frag_flags_combinable (&xt_block->flags,
				     &xt_block_2->flags))
    return FALSE;

  xt_block->size += xt_block_2->size;

  if (xt_block_2->flags.is_align)
    {
      xt_block->flags.is_align = TRUE;
      xt_block->flags.alignment = xt_block_2->flags.alignment;
    }

  return TRUE;
}


static void
add_xt_prop_frags (segT sec,
		   xtensa_block_info **xt_block,
		   frag_flags_fn property_function)
{
  fragS *fragP;

  /* Build it if needed.  */
  while (*xt_block != NULL)
    {
      xt_block = &(*xt_block)->next;
    }
  /* We are either at NULL at the beginning or at the end.  */

  /* Walk through the frags.  */
  if (seg_info (sec)->frchainP)
    {
      for (fragP = seg_info (sec)->frchainP->frch_root; fragP;
	   fragP = fragP->fr_next)
	{
	  xtensa_block_info tmp_block;
	  tmp_block.sec = sec;
	  tmp_block.offset = fragP->fr_address;
	  tmp_block.size = fragP->fr_fix;
	  tmp_block.next = NULL;
	  property_function (fragP, &tmp_block.flags);

	  if (!xtensa_frag_flags_is_empty (&tmp_block.flags))
	    /* && fragP->fr_fix != 0) */
	    {
	      if ((*xt_block) == NULL
		  || !xtensa_xt_block_combine (*xt_block, &tmp_block))
		{
		  xtensa_block_info *new_block;
		  if ((*xt_block) != NULL)
		    xt_block = &(*xt_block)->next;
		  new_block = XNEW (xtensa_block_info);
		  *new_block = tmp_block;
		  *xt_block = new_block;
		}
	    }
	}
    }
}


/* op_placement_info_table */

/* op_placement_info makes it easier to determine which
   ops can go in which slots.  */

static void
init_op_placement_info_table (void)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_insnbuf ibuf = xtensa_insnbuf_alloc (isa);
  xtensa_opcode opcode;
  xtensa_format fmt;
  int slot;
  int num_opcodes = xtensa_isa_num_opcodes (isa);

  op_placement_table = XNEWVEC (op_placement_info, num_opcodes);
  gas_assert (xtensa_isa_num_formats (isa) < MAX_FORMATS);

  for (opcode = 0; opcode < num_opcodes; opcode++)
    {
      op_placement_info *opi = &op_placement_table[opcode];
      /* FIXME: Make tinsn allocation dynamic.  */
      if (xtensa_opcode_num_operands (isa, opcode) > MAX_INSN_ARGS)
	as_fatal (_("too many operands in instruction"));
      opi->narrowest = XTENSA_UNDEFINED;
      opi->narrowest_size = 0x7F;
      opi->narrowest_slot = 0;
      opi->formats = 0;
      opi->num_formats = 0;
      opi->issuef = 0;
      for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++)
	{
	  opi->slots[fmt] = 0;
	  for (slot = 0; slot < xtensa_format_num_slots (isa, fmt); slot++)
	    {
	      if (xtensa_opcode_encode (isa, fmt, slot, ibuf, opcode) == 0)
		{
		  int fmt_length = xtensa_format_length (isa, fmt);
		  opi->issuef++;
		  set_bit (fmt, opi->formats);
		  set_bit (slot, opi->slots[fmt]);
		  if (fmt_length < opi->narrowest_size
		      || (fmt_length == opi->narrowest_size
			  && (xtensa_format_num_slots (isa, fmt)
			      < xtensa_format_num_slots (isa,
							 opi->narrowest))))
		    {
		      opi->narrowest = fmt;
		      opi->narrowest_size = fmt_length;
		      opi->narrowest_slot = slot;
		    }
		}
	    }
	  if (opi->formats)
	    opi->num_formats++;
	}
    }
  xtensa_insnbuf_free (isa, ibuf);
}


bfd_boolean
opcode_fits_format_slot (xtensa_opcode opcode, xtensa_format fmt, int slot)
{
  return bit_is_set (slot, op_placement_table[opcode].slots[fmt]);
}


/* If the opcode is available in a single slot format, return its size.  */

static int
xg_get_single_size (xtensa_opcode opcode)
{
  return op_placement_table[opcode].narrowest_size;
}


static xtensa_format
xg_get_single_format (xtensa_opcode opcode)
{
  return op_placement_table[opcode].narrowest;
}


static int
xg_get_single_slot (xtensa_opcode opcode)
{
  return op_placement_table[opcode].narrowest_slot;
}


/* Instruction Stack Functions (from "xtensa-istack.h").  */

void
istack_init (IStack *stack)
{
  stack->ninsn = 0;
}


bfd_boolean
istack_empty (IStack *stack)
{
  return (stack->ninsn == 0);
}


bfd_boolean
istack_full (IStack *stack)
{
  return (stack->ninsn == MAX_ISTACK);
}


/* Return a pointer to the top IStack entry.
   It is an error to call this if istack_empty () is TRUE. */

TInsn *
istack_top (IStack *stack)
{
  int rec = stack->ninsn - 1;
  gas_assert (!istack_empty (stack));
  return &stack->insn[rec];
}


/* Add a new TInsn to an IStack.
   It is an error to call this if istack_full () is TRUE.  */

void
istack_push (IStack *stack, TInsn *insn)
{
  int rec = stack->ninsn;
  gas_assert (!istack_full (stack));
  stack->insn[rec] = *insn;
  stack->ninsn++;
}


/* Clear space for the next TInsn on the IStack and return a pointer
   to it.  It is an error to call this if istack_full () is TRUE.  */

TInsn *
istack_push_space (IStack *stack)
{
  int rec = stack->ninsn;
  TInsn *insn;
  gas_assert (!istack_full (stack));
  insn = &stack->insn[rec];
  tinsn_init (insn);
  stack->ninsn++;
  return insn;
}


/* Remove the last pushed instruction.  It is an error to call this if
   istack_empty () returns TRUE.  */

void
istack_pop (IStack *stack)
{
  int rec = stack->ninsn - 1;
  gas_assert (!istack_empty (stack));
  stack->ninsn--;
  tinsn_init (&stack->insn[rec]);
}


/* TInsn functions.  */

void
tinsn_init (TInsn *dst)
{
  memset (dst, 0, sizeof (TInsn));
}


/* Return TRUE if ANY of the operands in the insn are symbolic.  */

static bfd_boolean
tinsn_has_symbolic_operands (const TInsn *insn)
{
  int i;
  int n = insn->ntok;

  gas_assert (insn->insn_type == ITYPE_INSN);

  for (i = 0; i < n; ++i)
    {
      switch (insn->tok[i].X_op)
	{
	case O_register:
	case O_constant:
	  break;
	default:
	  return TRUE;
	}
    }
  return FALSE;
}


bfd_boolean
tinsn_has_invalid_symbolic_operands (const TInsn *insn)
{
  xtensa_isa isa = xtensa_default_isa;
  int i;
  int n = insn->ntok;

  gas_assert (insn->insn_type == ITYPE_INSN);

  for (i = 0; i < n; ++i)
    {
      switch (insn->tok[i].X_op)
	{
	case O_register:
	case O_constant:
	  break;
	case O_big:
	case O_illegal:
	case O_absent:
	  /* Errors for these types are caught later.  */
	  break;
	case O_hi16:
	case O_lo16:
	default:
	  /* Symbolic immediates are only allowed on the last immediate
	     operand.  At this time, CONST16 is the only opcode where we
	     support non-PC-relative relocations.  */
	  if (i != get_relaxable_immed (insn->opcode)
	      || (xtensa_operand_is_PCrelative (isa, insn->opcode, i) != 1
		  && insn->opcode != xtensa_const16_opcode))
	    {
	      as_bad (_("invalid symbolic operand"));
	      return TRUE;
	    }
	}
    }
  return FALSE;
}


/* For assembly code with complex expressions (e.g. subtraction),
   we have to build them in the literal pool so that
   their results are calculated correctly after relaxation.
   The relaxation only handles expressions that
   boil down to SYMBOL + OFFSET.  */

static bfd_boolean
tinsn_has_complex_operands (const TInsn *insn)
{
  int i;
  int n = insn->ntok;
  gas_assert (insn->insn_type == ITYPE_INSN);
  for (i = 0; i < n; ++i)
    {
      switch (insn->tok[i].X_op)
	{
	case O_register:
	case O_constant:
	case O_symbol:
	case O_lo16:
	case O_hi16:
	  break;
	default:
	  return TRUE;
	}
    }
  return FALSE;
}


/* Encode a TInsn opcode and its constant operands into slotbuf.
   Return TRUE if there is a symbol in the immediate field.  This
   function assumes that:
   1) The number of operands are correct.
   2) The insn_type is ITYPE_INSN.
   3) The opcode can be encoded in the specified format and slot.
   4) Operands are either O_constant or O_symbol, and all constants fit.  */

static bfd_boolean
tinsn_to_slotbuf (xtensa_format fmt,
		  int slot,
		  TInsn *tinsn,
		  xtensa_insnbuf slotbuf)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_opcode opcode = tinsn->opcode;
  bfd_boolean has_fixup = FALSE;
  int noperands = xtensa_opcode_num_operands (isa, opcode);
  int i;

  gas_assert (tinsn->insn_type == ITYPE_INSN);
  if (noperands != tinsn->ntok)
    as_fatal (_("operand number mismatch"));

  if (xtensa_opcode_encode (isa, fmt, slot, slotbuf, opcode))
    {
      as_bad (_("cannot encode opcode \"%s\" in the given format \"%s\""),
	      xtensa_opcode_name (isa, opcode), xtensa_format_name (isa, fmt));
      return FALSE;
    }

  for (i = 0; i < noperands; i++)
    {
      expressionS *exp = &tinsn->tok[i];
      int rc;
      unsigned line;
      const char *file_name;
      uint32 opnd_value;

      switch (exp->X_op)
	{
	case O_register:
	  if (xtensa_operand_is_visible (isa, opcode, i) == 0)
	    break;
	  /* The register number has already been checked in
	     expression_maybe_register, so we don't need to check here.  */
	  opnd_value = exp->X_add_number;
	  (void) xtensa_operand_encode (isa, opcode, i, &opnd_value);
	  rc = xtensa_operand_set_field (isa, opcode, i, fmt, slot, slotbuf,
					 opnd_value);
	  if (rc != 0)
	    as_warn (_("xtensa-isa failure: %s"), xtensa_isa_error_msg (isa));
	  break;

	case O_constant:
	  if (xtensa_operand_is_visible (isa, opcode, i) == 0)
	    break;
	  file_name = as_where (&line);
	  /* It is a constant and we called this function
	     then we have to try to fit it.  */
	  xtensa_insnbuf_set_operand (slotbuf, fmt, slot, opcode, i,
				      exp->X_add_number, file_name, line);
	  break;

	default:
	  has_fixup = TRUE;
	  break;
	}
    }

  return has_fixup;
}


/* Encode a single TInsn into an insnbuf.  If the opcode can only be encoded
   into a multi-slot instruction, fill the other slots with NOPs.
   Return TRUE if there is a symbol in the immediate field.  See also the
   assumptions listed for tinsn_to_slotbuf.  */

static bfd_boolean
tinsn_to_insnbuf (TInsn *tinsn, xtensa_insnbuf insnbuf)
{
  static xtensa_insnbuf slotbuf = 0;
  static vliw_insn vinsn;
  xtensa_isa isa = xtensa_default_isa;
  bfd_boolean has_fixup = FALSE;
  int i;

  if (!slotbuf)
    {
      slotbuf = xtensa_insnbuf_alloc (isa);
      xg_init_vinsn (&vinsn);
    }

  xg_clear_vinsn (&vinsn);

  bundle_tinsn (tinsn, &vinsn);

  xtensa_format_encode (isa, vinsn.format, insnbuf);

  for (i = 0; i < vinsn.num_slots; i++)
    {
      /* Only one slot may have a fix-up because the rest contains NOPs.  */
      has_fixup |=
	tinsn_to_slotbuf (vinsn.format, i, &vinsn.slots[i], vinsn.slotbuf[i]);
      xtensa_format_set_slot (isa, vinsn.format, i, insnbuf, vinsn.slotbuf[i]);
    }

  return has_fixup;
}


/* Check the instruction arguments.  Return TRUE on failure.  */

static bfd_boolean
tinsn_check_arguments (const TInsn *insn)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_opcode opcode = insn->opcode;
  xtensa_regfile t1_regfile, t2_regfile;
  int t1_reg, t2_reg;
  int t1_base_reg, t1_last_reg;
  int t2_base_reg, t2_last_reg;
  char t1_inout, t2_inout;
  int i, j;

  if (opcode == XTENSA_UNDEFINED)
    {
      as_bad (_("invalid opcode"));
      return TRUE;
    }

  if (xtensa_opcode_num_operands (isa, opcode) > insn->ntok)
    {
      as_bad (_("too few operands"));
      return TRUE;
    }

  if (xtensa_opcode_num_operands (isa, opcode) < insn->ntok)
    {
      as_bad (_("too many operands"));
      return TRUE;
    }

  /* Check registers.  */
  for (j = 0; j < insn->ntok; j++)
    {
      if (xtensa_operand_is_register (isa, insn->opcode, j) != 1)
	continue;

      t2_regfile = xtensa_operand_regfile (isa, insn->opcode, j);
      t2_base_reg = insn->tok[j].X_add_number;
      t2_last_reg
	= t2_base_reg + xtensa_operand_num_regs (isa, insn->opcode, j);

      for (i = 0; i < insn->ntok; i++)
	{
	  if (i == j)
	    continue;

	  if (xtensa_operand_is_register (isa, insn->opcode, i) != 1)
	    continue;

	  t1_regfile = xtensa_operand_regfile (isa, insn->opcode, i);

	  if (t1_regfile != t2_regfile)
	    continue;

	  t1_inout = xtensa_operand_inout (isa, insn->opcode, i);
	  t2_inout = xtensa_operand_inout (isa, insn->opcode, j);

	  t1_base_reg = insn->tok[i].X_add_number;
	  t1_last_reg = (t1_base_reg
			 + xtensa_operand_num_regs (isa, insn->opcode, i));

	  for (t1_reg = t1_base_reg; t1_reg < t1_last_reg; t1_reg++)
	    {
	      for (t2_reg = t2_base_reg; t2_reg < t2_last_reg; t2_reg++)
		{
		  if (t1_reg != t2_reg)
		    continue;

		  if (t1_inout != 'i' && t2_inout != 'i')
		    {
		      as_bad (_("multiple writes to the same register"));
		      return TRUE;
		    }
		}
	    }
	}
    }
  return FALSE;
}


/* Load an instruction from its encoded form.  */

static void
tinsn_from_chars (TInsn *tinsn, char *f, int slot)
{
  vliw_insn vinsn;

  xg_init_vinsn (&vinsn);
  vinsn_from_chars (&vinsn, f);

  *tinsn = vinsn.slots[slot];
  xg_free_vinsn (&vinsn);
}


static void
tinsn_from_insnbuf (TInsn *tinsn,
		    xtensa_insnbuf slotbuf,
		    xtensa_format fmt,
		    int slot)
{
  int i;
  xtensa_isa isa = xtensa_default_isa;

  /* Find the immed.  */
  tinsn_init (tinsn);
  tinsn->insn_type = ITYPE_INSN;
  tinsn->is_specific_opcode = FALSE;	/* must not be specific */
  tinsn->opcode = xtensa_opcode_decode (isa, fmt, slot, slotbuf);
  tinsn->ntok = xtensa_opcode_num_operands (isa, tinsn->opcode);
  for (i = 0; i < tinsn->ntok; i++)
    {
      set_expr_const (&tinsn->tok[i],
		      xtensa_insnbuf_get_operand (slotbuf, fmt, slot,
						  tinsn->opcode, i));
    }
}


/* Read the value of the relaxable immed from the fr_symbol and fr_offset.  */

static void
tinsn_immed_from_frag (TInsn *tinsn, fragS *fragP, int slot)
{
  xtensa_opcode opcode = tinsn->opcode;
  int opnum;

  if (fragP->tc_frag_data.slot_symbols[slot])
    {
      opnum = get_relaxable_immed (opcode);
      gas_assert (opnum >= 0);
      set_expr_symbol_offset (&tinsn->tok[opnum],
			      fragP->tc_frag_data.slot_symbols[slot],
			      fragP->tc_frag_data.slot_offsets[slot]);
    }
  tinsn->extra_arg = fragP->tc_frag_data.free_reg[slot];
}


static int
get_num_stack_text_bytes (IStack *istack)
{
  int i;
  int text_bytes = 0;

  for (i = 0; i < istack->ninsn; i++)
    {
      TInsn *tinsn = &istack->insn[i];
      if (tinsn->insn_type == ITYPE_INSN)
	text_bytes += xg_get_single_size (tinsn->opcode);
    }
  return text_bytes;
}


static int
get_num_stack_literal_bytes (IStack *istack)
{
  int i;
  int lit_bytes = 0;

  for (i = 0; i < istack->ninsn; i++)
    {
      TInsn *tinsn = &istack->insn[i];
      if (tinsn->insn_type == ITYPE_LITERAL && tinsn->ntok == 1)
	lit_bytes += 4;
    }
  return lit_bytes;
}


/* vliw_insn functions.  */

static void
xg_init_vinsn (vliw_insn *v)
{
  int i;
  xtensa_isa isa = xtensa_default_isa;

  xg_clear_vinsn (v);

  v->insnbuf = xtensa_insnbuf_alloc (isa);
  if (v->insnbuf == NULL)
    as_fatal (_("out of memory"));

  for (i = 0; i < config_max_slots; i++)
    {
      v->slotbuf[i] = xtensa_insnbuf_alloc (isa);
      if (v->slotbuf[i] == NULL)
	as_fatal (_("out of memory"));
    }
}


static void
xg_clear_vinsn (vliw_insn *v)
{
  int i;

  memset (v, 0, offsetof (vliw_insn, slots)
                + sizeof(TInsn) * config_max_slots);

  v->format = XTENSA_UNDEFINED;
  v->num_slots = 0;
  v->inside_bundle = FALSE;

  if (xt_saved_debug_type != DEBUG_NONE)
    debug_type = xt_saved_debug_type;

  for (i = 0; i < config_max_slots; i++)
    v->slots[i].opcode = XTENSA_UNDEFINED;
}


static void
xg_copy_vinsn (vliw_insn *dst, vliw_insn *src)
{
  memcpy (dst, src,
	  offsetof(vliw_insn, slots) + src->num_slots * sizeof(TInsn));
  dst->insnbuf = src->insnbuf;
  memcpy (dst->slotbuf, src->slotbuf, src->num_slots * sizeof(xtensa_insnbuf));
}


static bfd_boolean
vinsn_has_specific_opcodes (vliw_insn *v)
{
  int i;

  for (i = 0; i < v->num_slots; i++)
    {
      if (v->slots[i].is_specific_opcode)
	return TRUE;
    }
  return FALSE;
}


static void
xg_free_vinsn (vliw_insn *v)
{
  int i;
  xtensa_insnbuf_free (xtensa_default_isa, v->insnbuf);
  for (i = 0; i < config_max_slots; i++)
    xtensa_insnbuf_free (xtensa_default_isa, v->slotbuf[i]);
}


/* Encode a vliw_insn into an insnbuf.  Return TRUE if there are any symbolic
   operands.  See also the assumptions listed for tinsn_to_slotbuf.  */

static bfd_boolean
vinsn_to_insnbuf (vliw_insn *vinsn,
		  char *frag_offset,
		  fragS *fragP,
		  bfd_boolean record_fixup)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt = vinsn->format;
  xtensa_insnbuf insnbuf = vinsn->insnbuf;
  int slot;
  bfd_boolean has_fixup = FALSE;

  xtensa_format_encode (isa, fmt, insnbuf);

  for (slot = 0; slot < vinsn->num_slots; slot++)
    {
      TInsn *tinsn = &vinsn->slots[slot];
      expressionS *extra_arg = &tinsn->extra_arg;
      bfd_boolean tinsn_has_fixup =
	tinsn_to_slotbuf (vinsn->format, slot, tinsn,
			  vinsn->slotbuf[slot]);

      xtensa_format_set_slot (isa, fmt, slot,
			      insnbuf, vinsn->slotbuf[slot]);
      if (extra_arg->X_op != O_illegal && extra_arg->X_op != O_register)
	{
	  if (vinsn->num_slots != 1)
	    as_bad (_("TLS relocation not allowed in FLIX bundle"));
	  else if (record_fixup)
	    /* Instructions that generate TLS relocations should always be
	       relaxed in the front-end.  If "record_fixup" is set, then this
	       function is being called during back-end relaxation, so flag
	       the unexpected behavior as an error.  */
	    as_bad (_("unexpected TLS relocation"));
	  else
	    fix_new (fragP, frag_offset - fragP->fr_literal,
		     xtensa_format_length (isa, fmt),
		     extra_arg->X_add_symbol, extra_arg->X_add_number,
		     FALSE, map_operator_to_reloc (extra_arg->X_op, FALSE));
	}
      if (tinsn_has_fixup)
	{
	  int i;
	  xtensa_opcode opcode = tinsn->opcode;
	  int noperands = xtensa_opcode_num_operands (isa, opcode);
	  has_fixup = TRUE;

	  for (i = 0; i < noperands; i++)
	    {
	      expressionS* exp = &tinsn->tok[i];
	      switch (exp->X_op)
		{
		case O_symbol:
		case O_lo16:
		case O_hi16:
		  if (get_relaxable_immed (opcode) == i)
		    {
		      /* Add a fix record for the instruction, except if this
			 function is being called prior to relaxation, i.e.,
			 if record_fixup is false, and the instruction might
			 be relaxed later.  */
		      if (record_fixup
			  || tinsn->is_specific_opcode
			  || !xg_is_relaxable_insn (tinsn, 0))
			{
			  xg_add_opcode_fix (tinsn, i, fmt, slot, exp, fragP,
					     frag_offset - fragP->fr_literal);
			}
		      else
			{
			  if (exp->X_op != O_symbol)
			    as_bad (_("invalid operand"));
			  tinsn->symbol = exp->X_add_symbol;
			  tinsn->offset = exp->X_add_number;
			}
		    }
		  else
		    as_bad (_("symbolic operand not allowed"));
		  break;

		case O_constant:
		case O_register:
		  break;

		default:
		  as_bad (_("expression too complex"));
		  break;
		}
	    }
	}
    }

  return has_fixup;
}


static void
vinsn_from_chars (vliw_insn *vinsn, char *f)
{
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  int i;
  xtensa_format fmt;
  xtensa_isa isa = xtensa_default_isa;

  if (!insnbuf)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  xtensa_insnbuf_from_chars (isa, insnbuf, (unsigned char *) f, 0);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED)
    as_fatal (_("cannot decode instruction format"));
  vinsn->format = fmt;
  vinsn->num_slots = xtensa_format_num_slots (isa, fmt);

  for (i = 0; i < vinsn->num_slots; i++)
    {
      TInsn *tinsn = &vinsn->slots[i];
      xtensa_format_get_slot (isa, fmt, i, insnbuf, slotbuf);
      tinsn_from_insnbuf (tinsn, slotbuf, fmt, i);
    }
}


/* Expression utilities.  */

/* Return TRUE if the expression is an integer constant.  */

bfd_boolean
expr_is_const (const expressionS *s)
{
  return (s->X_op == O_constant);
}


/* Get the expression constant.
   Calling this is illegal if expr_is_const () returns TRUE.  */

offsetT
get_expr_const (const expressionS *s)
{
  gas_assert (expr_is_const (s));
  return s->X_add_number;
}


/* Set the expression to a constant value.  */

void
set_expr_const (expressionS *s, offsetT val)
{
  s->X_op = O_constant;
  s->X_add_number = val;
  s->X_add_symbol = NULL;
  s->X_op_symbol = NULL;
}


bfd_boolean
expr_is_register (const expressionS *s)
{
  return (s->X_op == O_register);
}


/* Get the expression constant.
   Calling this is illegal if expr_is_const () returns TRUE.  */

offsetT
get_expr_register (const expressionS *s)
{
  gas_assert (expr_is_register (s));
  return s->X_add_number;
}


/* Set the expression to a symbol + constant offset.  */

void
set_expr_symbol_offset (expressionS *s, symbolS *sym, offsetT offset)
{
  s->X_op = O_symbol;
  s->X_add_symbol = sym;
  s->X_op_symbol = NULL;	/* unused */
  s->X_add_number = offset;
}


/* Return TRUE if the two expressions are equal.  */

bfd_boolean
expr_is_equal (expressionS *s1, expressionS *s2)
{
  if (s1->X_op != s2->X_op)
    return FALSE;
  if (s1->X_add_symbol != s2->X_add_symbol)
    return FALSE;
  if (s1->X_op_symbol != s2->X_op_symbol)
    return FALSE;
  if (s1->X_add_number != s2->X_add_number)
    return FALSE;
  return TRUE;
}


static void
copy_expr (expressionS *dst, const expressionS *src)
{
  memcpy (dst, src, sizeof (expressionS));
}


/* Support for the "--rename-section" option.  */

struct rename_section_struct
{
  const char *old_name;
  char *new_name;
  struct rename_section_struct *next;
};

static struct rename_section_struct *section_rename;


/* Parse the string "oldname=new_name(:oldname2=new_name2)*" and add
   entries to the section_rename list.  Note: Specifying multiple
   renamings separated by colons is not documented and is retained only
   for backward compatibility.  */

static void
build_section_rename (const char *arg)
{
  struct rename_section_struct *r;
  char *this_arg = NULL;
  char *next_arg = NULL;

  for (this_arg = xstrdup (arg); this_arg != NULL; this_arg = next_arg)
    {
      char *old_name, *new_name;

      if (this_arg)
	{
	  next_arg = strchr (this_arg, ':');
	  if (next_arg)
	    {
	      *next_arg = '\0';
	      next_arg++;
	    }
	}

      old_name = this_arg;
      new_name = strchr (this_arg, '=');

      if (*old_name == '\0')
	{
	  as_warn (_("ignoring extra '-rename-section' delimiter ':'"));
	  continue;
	}
      if (!new_name || new_name[1] == '\0')
	{
	  as_warn (_("ignoring invalid '-rename-section' specification: '%s'"),
		   old_name);
	  continue;
	}
      *new_name = '\0';
      new_name++;

      /* Check for invalid section renaming.  */
      for (r = section_rename; r != NULL; r = r->next)
	{
	  if (strcmp (r->old_name, old_name) == 0)
	    as_bad (_("section %s renamed multiple times"), old_name);
	  if (strcmp (r->new_name, new_name) == 0)
	    as_bad (_("multiple sections remapped to output section %s"),
		    new_name);
	}

      /* Now add it.  */
      r = XNEW (struct rename_section_struct);
      r->old_name = xstrdup (old_name);
      r->new_name = xstrdup (new_name);
      r->next = section_rename;
      section_rename = r;
    }
}


char *
xtensa_section_rename (const char *name)
{
  struct rename_section_struct *r = section_rename;

  for (r = section_rename; r != NULL; r = r->next)
    {
      if (strcmp (r->old_name, name) == 0)
	return r->new_name;
    }

  return (char *) name;
}
