/* tc-xtensa.c -- Assemble Xtensa instructions.
   Copyright (C) 2003-2014 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"

/* 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 GET_XTENSA_PROP_BT_ALIGN(flag) \
  (((unsigned) ((flag) & (XTENSA_PROP_BT_ALIGN_MASK))) >> 9)
#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 GET_XTENSA_PROP_ALIGNMENT(flag) \
  (((unsigned) ((flag) & (XTENSA_PROP_ALIGNMENT_MASK))) >> 12)
#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
{
  char *suffix;
  int length;
  bfd_reloc_code_real_type reloc;
  unsigned char 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),
  { (char *) 0, 0,	BFD_RELOC_UNUSED,		0 }
};


/* 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
};


/* 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 *);

/* 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);

/* Import from elf32-xtensa.c in BFD library.  */

extern asection *xtensa_make_property_section (asection *, const char *);

/* 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,
};

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 },

  { NULL, no_argument, NULL, 0 }
};

size_t md_longopts_size = sizeof md_longopts;


int
md_parse_option (int c, 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;
	if (*arg == 0 || *arg == '-')
	  as_fatal (_("invalid target hardware version"));

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

	if (*arg == 0)
	  latest = earliest;
	else if (*arg == '-')
	  {
	    if (*++arg == 0)
	      as_fatal (_("invalid target hardware version"));
	    latest = strtol (arg, &arg, 0);
	  }
	if (*arg != 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;

    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", 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 = (sym_list *) xmalloc (sizeof (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)
{
  char *file;
  unsigned int line;
  state_stackS *stack = (state_stackS *) xmalloc (sizeof (state_stackS));

  as_where (&file, &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;
  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 = (emit_state *) xmalloc (sizeof (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 = xmalloc (sizeof (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_end ();
  /* Just after name is now '\0'.  */
  p = input_line_pointer;
  *p = c;
  SKIP_WHITESPACE ();

  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 = xmalloc (len + 1);
  gas_assert (name);
  strncpy (name, input_line_pointer, len);
  name[len] = 0;

  /* 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;
  struct suffix_reloc_map *ptr;

  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 (ptr = &suffix_relocs[0]; ptr->length > 0; ptr++)
    if (ch == ptr->suffix[0]
	&& len == ptr->length
	&& memcmp (ident, ptr->suffix, ptr->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 ptr->reloc;
      }

  return BFD_RELOC_UNUSED;
}


/* Find the matching operator type.  */
static unsigned char
map_suffix_reloc_to_operator (bfd_reloc_code_real_type reloc)
{
  struct suffix_reloc_map *sfx;
  unsigned char operator = (unsigned char) -1;
  
  for (sfx = &suffix_relocs[0]; sfx->suffix; sfx++)
    {
      if (sfx->reloc == reloc)
	{
	  operator = sfx->operator;
	  break;
	}
    }
  gas_assert (operator != (unsigned char) -1);
  return operator;
}


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

  for (sfx = &suffix_relocs[0]; sfx->suffix; sfx++)
    {
      if (sfx->operator == operator)
	{
	  reloc = sfx->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 = (char *) xmalloc ((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 = (char *) xmalloc (strlen (cnt_arg) + 6);
  sprintf (new_arg, "31-(%s)", cnt_arg);

  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, char *newop)
{
  free (*popname);
  *popname = (char *) xmalloc (strlen (newop) + 1);
  strcpy (*popname, 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 = (char *) xmalloc (strlen (sr_name) + 6);
  sprintf (new_opname, "%s.%s", *popname, sr_name);
  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 = (char *) xmalloc (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 (char *old_op,
			     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] = (char *) xmalloc (strlen (arg_strings[1]) + 1);
	  strcpy (arg_strings[2], 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] = (char *) xmalloc (3);
	  arg_strings[1] = (char *) xmalloc (3);
	  arg_strings[2] = (char *) xmalloc (3);
	  strcpy (arg_strings[0], "a1");
	  strcpy (arg_strings[1], "a1");
	  strcpy (arg_strings[2], "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 = (sym_list *) xmalloc (sizeof (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;
  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)
{
  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 = xmalloc (opnamelen + 1);
  memcpy (opname, str, opnamelen);
  opname[opnamelen] = '\0';

  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 = 1;
	      break;
	    case BFD_RELOC_16:
	      fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16;
	      fixP->fx_signed = 1;
	      break;
	    case BFD_RELOC_32:
	      fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32;
	      fixP->fx_signed = 1;
	      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));
    }
}


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 = (arelent *) xmalloc (sizeof (arelent));
  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (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 = (resource_table *) xmalloc (sizeof (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 = (unsigned char **) xcalloc (cycles, sizeof (unsigned char *));
  for (i = 0; i < cycles; i++)
    rt->units[i] = (unsigned char *) xcalloc (nu, sizeof (unsigned char));

  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 = xrealloc (rt->units,
			rt->allocated_cycles * sizeof (unsigned char *));
  for (i = 0; i < old_cycles; i++)
    rt->units[i] = xrealloc (rt->units[i],
			     rt->num_units * sizeof (unsigned char));
  for (i = old_cycles; i < cycles; i++)
    rt->units[i] = xcalloc (rt->num_units, sizeof (unsigned char));
}


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;
  char *file_name;
  unsigned line;

  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_where (&file_name, &line);
      as_bad_where (file_name, line,
		    _("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_where (&file_name, &line);
      as_bad_where (file_name, line, _("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_where (&file_name, &line);
      as_bad_where (file_name, line, _("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 = xmalloc (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->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 ();
	}
      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;
    }
}

static xtensa_insnbuf trampoline_buf = NULL;
static xtensa_insnbuf trampoline_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 = (struct trampoline_seg *)xcalloc(sizeof (struct trampoline_seg), 1);
      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 = (struct trampoline_frag *)xmalloc(sizeof (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
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)
{
  char *file_name;
  unsigned line;
  frchainS *frchP;
  asection *s;

  as_where (&file_name, &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 = xmalloc (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);


/* 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;
  char *file_name;
  unsigned line;
  int lit_size;
  static xtensa_insnbuf vbuf = NULL;
  int slot, num_slots;
  xtensa_format fmt;

  as_where (&file_name, &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:
    case RELAX_LITERAL_POOL_END:
    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)
        {
          segment_info_type *seginfo = seg_info (now_seg);
          fragS *fP; /* The out-of-range jump.  */
          fixS *fixP;

          /* Scan for jumps that will not reach.  */
          for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next)
            {
              symbolS *s = fixP->fx_addsy;
	      xtensa_opcode opcode;
              int target;
              int addr;
              int delta;

              if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP ||
                  fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP)
                continue;
	      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)
		continue;
              target = S_GET_VALUE (s);
              addr = fixP->fx_frag->fr_address;
              delta = target - addr + stretch;
              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)
		    {
		      int trampaddr = fragP->fr_address + fragP->fr_fix;

		      if (abs (addr - trampaddr) < J_RANGE)
			{ /* The trampoline is in range of original; fix it!  */
			  fixS *newfixP;
			  int offset;
			  TInsn insn;
			  symbolS *lsym;

			  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;
			  /* 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;
			  /* 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;
			      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;
  char *file_name;
  unsigned line;

  as_where (&file_name, &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 = (subseg_map *) xmalloc (sizeof (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;

  mark_literal_frags (literal_head->next);

  if (use_literal_section)
    return;

  for (segment = literal_head->next; segment; segment = segment->next)
    {
      /* Keep the literals for .init and .fini in separate sections.  */
      if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME)
	  || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME))
	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->tc_frag_data.literal_frag)
	{
	  gas_assert (search_frag->fr_fix == 0
		  || search_frag->fr_type == rs_align);
	  search_frag = search_frag->fr_next;
	}

      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;

	  /* First, move the frag out of the literal section and
	     to the appropriate place.  */
	  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);
	    }
	  insert_after = literal_pool->tc_frag_data.literal_frag;
	  dest_seg = insert_after->fr_next->tc_frag_data.lit_seg;

	  *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)
    {
      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;
  char *base_name, *name, *suffix;
  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 = xmalloc (strlen (base_name) + strlen (group_name) + 2);
      sprintf (name, "%s.%s", base_name, group_name);
    }
  else if (strncmp (text_name, ".gnu.linkonce.", linkonce_len) == 0)
    {
      suffix = strchr (text_name + linkonce_len, '.');

      name = xmalloc (linkonce_len + strlen (base_name) + 1
		      + (suffix ? strlen (suffix) : 0));
      strcpy (name, ".gnu.linkonce");
      strcat (name, base_name);
      if (suffix)
	strcat (name, suffix);
      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 = xmalloc (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 = (seg_list *) xmalloc (sizeof (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 = (xtensa_block_info *)
		    xmalloc (sizeof (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 = (xtensa_block_info *)
		    xmalloc (sizeof (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 = (op_placement_info_table)
    xmalloc (sizeof (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;
      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;
	  as_where (&file_name, &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
{
  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 = (struct rename_section_struct *)
	xmalloc (sizeof (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 (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 name;
}
