/* TI C6X assembler.
   Copyright (C) 2010-2020 Free Software Foundation, Inc.
   Contributed by Joseph Myers <joseph@codesourcery.com>
   		  Bernd Schmidt  <bernds@codesourcery.com>

   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 "dwarf2dbg.h"
#include "dw2gencfi.h"
#include "safe-ctype.h"
#include "subsegs.h"
#include "opcode/tic6x.h"
#include "elf/tic6x.h"
#include "elf32-tic6x.h"

/* Truncate and sign-extend at 32 bits, so that building on a 64-bit
   host gives identical results to a 32-bit host.  */
#define TRUNC(X)	((valueT) (X) & 0xffffffffU)
#define SEXT(X)		((TRUNC (X) ^ 0x80000000U) - 0x80000000U)

#define streq(a, b)           (strcmp (a, b) == 0)

/* Stuff for .scomm symbols.  */
static segT sbss_section;
static asection scom_section;
static asymbol scom_symbol;

const char comment_chars[] = ";";
const char line_comment_chars[] = "#*;";
const char line_separator_chars[] = "@";

const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "dDfF";

const char *md_shortopts = "";

enum
  {
    OPTION_MARCH = OPTION_MD_BASE,
    OPTION_MBIG_ENDIAN,
    OPTION_MLITTLE_ENDIAN,
    OPTION_MDSBT,
    OPTION_MNO_DSBT,
    OPTION_MPID,
    OPTION_MPIC,
    OPTION_MNO_PIC,
    OPTION_MGENERATE_REL
  };

struct option md_longopts[] =
  {
    { "march", required_argument, NULL, OPTION_MARCH },
    { "mbig-endian", no_argument, NULL, OPTION_MBIG_ENDIAN },
    { "mlittle-endian", no_argument, NULL, OPTION_MLITTLE_ENDIAN },
    { "mdsbt", no_argument, NULL, OPTION_MDSBT },
    { "mno-dsbt", no_argument, NULL, OPTION_MNO_DSBT },
    { "mpid", required_argument, NULL, OPTION_MPID },
    { "mpic", no_argument, NULL, OPTION_MPIC },
    { "mno-pic", no_argument, NULL, OPTION_MNO_PIC },
    { "mgenerate-rel", no_argument, NULL, OPTION_MGENERATE_REL },
    { NULL, no_argument, NULL, 0 }
  };
size_t md_longopts_size = sizeof (md_longopts);

/* The instructions enabled based only on the selected architecture
   (all instructions, if no architecture specified).  */
static unsigned short tic6x_arch_enable = (TIC6X_INSN_C62X
					   | TIC6X_INSN_C64X
					   | TIC6X_INSN_C64XP
					   | TIC6X_INSN_C67X
					   | TIC6X_INSN_C67XP
					   | TIC6X_INSN_C674X);

/* The instructions enabled based on the current set of features
   (architecture, as modified by other options).  */
static unsigned short tic6x_features;

/* The architecture attribute value, or C6XABI_Tag_ISA_none if
   not yet set.  */
static int tic6x_arch_attribute = C6XABI_Tag_ISA_none;

/* Whether any instructions at all have been seen.  Once any
   instructions have been seen, architecture attributes merge into the
   previous attribute value rather than replacing it.  */
static bfd_boolean tic6x_seen_insns = FALSE;

/* The number of registers in each register file supported by the
   current architecture.  */
static unsigned int tic6x_num_registers;

/* Whether predication on A0 is possible.  */
static bfd_boolean tic6x_predicate_a0;

/* Whether execute packets can cross fetch packet boundaries.  */
static bfd_boolean tic6x_can_cross_fp_boundary;

/* Whether there are constraints on simultaneous reads and writes of
   40-bit data.  */
static bfd_boolean tic6x_long_data_constraints;

/* Whether compact instructions are available.  */
static bfd_boolean tic6x_compact_insns;

/* Whether to generate RELA relocations.  */
static bfd_boolean tic6x_generate_rela = TRUE;

/* Whether the code uses DSBT addressing.  */
static bfd_boolean tic6x_dsbt;

/* Types of position-independent data (attribute values for
   Tag_ABI_PID).  */
typedef enum
  {
    tic6x_pid_no = 0,
    tic6x_pid_near = 1,
    tic6x_pid_far = 2
  } tic6x_pid_type;

/* The type of data addressing used in this code.  */
static tic6x_pid_type tic6x_pid;

/* Whether the code uses position-independent code.  */
static bfd_boolean tic6x_pic;

/* Table of supported architecture variants.  */
typedef struct
{
  const char *arch;
  int attr;
  unsigned short features;
} tic6x_arch_table;
static const tic6x_arch_table tic6x_arches[] =
  {
    { "c62x", C6XABI_Tag_ISA_C62X, TIC6X_INSN_C62X },
    { "c64x", C6XABI_Tag_ISA_C64X, TIC6X_INSN_C62X | TIC6X_INSN_C64X },
    { "c64x+", C6XABI_Tag_ISA_C64XP, (TIC6X_INSN_C62X
				      | TIC6X_INSN_C64X
				      | TIC6X_INSN_C64XP) },
    { "c67x", C6XABI_Tag_ISA_C67X, TIC6X_INSN_C62X | TIC6X_INSN_C67X },
    { "c67x+", C6XABI_Tag_ISA_C67XP, (TIC6X_INSN_C62X
				      | TIC6X_INSN_C67X
				      | TIC6X_INSN_C67XP) },
    { "c674x", C6XABI_Tag_ISA_C674X, (TIC6X_INSN_C62X
				      | TIC6X_INSN_C64X
				      | TIC6X_INSN_C64XP
				      | TIC6X_INSN_C67X
				      | TIC6X_INSN_C67XP
				      | TIC6X_INSN_C674X) }
  };

/* Caller saved register encodings.  The standard frame layout uses this
   order, starting from the highest address.  There must be
   TIC6X_NUM_UNWIND_REGS values.  */
enum
{
  UNWIND_A15,
  UNWIND_B15,
  UNWIND_B14,
  UNWIND_B13,
  UNWIND_B12,
  UNWIND_B11,
  UNWIND_B10,
  UNWIND_B3,
  UNWIND_A14,
  UNWIND_A13,
  UNWIND_A12,
  UNWIND_A11,
  UNWIND_A10
};

static void tic6x_output_unwinding (bfd_boolean need_extab);

/* Return the frame unwind state for the current function, allocating
   as necessary.  */

static tic6x_unwind_info *tic6x_get_unwind (void)
{
  tic6x_unwind_info *unwind;

  unwind = seg_info (now_seg)->tc_segment_info_data.unwind;
  if (unwind)
    return unwind;

  unwind = seg_info (now_seg)->tc_segment_info_data.text_unwind;
  if (unwind)
    return unwind;

  unwind =XNEW (tic6x_unwind_info);
  seg_info (now_seg)->tc_segment_info_data.unwind = unwind;
  memset (unwind, 0, sizeof (*unwind));
  return unwind;
}

/* Update the selected architecture based on ARCH, giving an error if
   ARCH is an invalid value.  Does not call tic6x_update_features; the
   caller must do that if necessary.  */

static void
tic6x_use_arch (const char *arch)
{
  unsigned int i;

  for (i = 0; i < ARRAY_SIZE (tic6x_arches); i++)
    if (strcmp (arch, tic6x_arches[i].arch) == 0)
      {
	tic6x_arch_enable = tic6x_arches[i].features;
	if (tic6x_seen_insns)
	  tic6x_arch_attribute
	    = elf32_tic6x_merge_arch_attributes (tic6x_arch_attribute,
						 tic6x_arches[i].attr);
	else
	  tic6x_arch_attribute = tic6x_arches[i].attr;
	return;
      }

  as_bad (_("unknown architecture '%s'"), arch);
}

/* Table of supported -mpid arguments.  */
typedef struct
{
  const char *arg;
  tic6x_pid_type attr;
} tic6x_pid_type_table;
static const tic6x_pid_type_table tic6x_pid_types[] =
  {
    { "no", tic6x_pid_no },
    { "near", tic6x_pid_near },
    { "far", tic6x_pid_far }
  };

/* Handle -mpid=ARG.  */

static void
tic6x_use_pid (const char *arg)
{
  unsigned int i;

  for (i = 0; i < ARRAY_SIZE (tic6x_pid_types); i++)
    if (strcmp (arg, tic6x_pid_types[i].arg) == 0)
      {
	tic6x_pid = tic6x_pid_types[i].attr;
	return;
      }

  as_bad (_("unknown -mpid= argument '%s'"), arg);
}

/* Parse a target-specific option.  */

int
md_parse_option (int c, const char *arg)
{
  switch (c)
    {
    case OPTION_MARCH:
      tic6x_use_arch (arg);
      break;

    case OPTION_MBIG_ENDIAN:
      target_big_endian = 1;
      break;

    case OPTION_MLITTLE_ENDIAN:
      target_big_endian = 0;
      break;

    case OPTION_MDSBT:
      tic6x_dsbt = 1;
      break;

    case OPTION_MNO_DSBT:
      tic6x_dsbt = 0;
      break;

    case OPTION_MPID:
      tic6x_use_pid (arg);
      break;

    case OPTION_MPIC:
      tic6x_pic = 1;
      break;

    case OPTION_MNO_PIC:
      tic6x_pic = 0;
      break;

    case OPTION_MGENERATE_REL:
      tic6x_generate_rela = FALSE;
      break;

    default:
      return 0;
    }
  return 1;
}

void
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
{
  unsigned int i;

  fputc ('\n', stream);
  fprintf (stream, _("TMS320C6000 options:\n"));
  fprintf (stream, _("  -march=ARCH             enable instructions from architecture ARCH\n"));
  fprintf (stream, _("  -mbig-endian            generate big-endian code\n"));
  fprintf (stream, _("  -mlittle-endian         generate little-endian code\n"));
  fprintf (stream, _("  -mdsbt                  code uses DSBT addressing\n"));
  fprintf (stream, _("  -mno-dsbt               code does not use DSBT addressing\n"));
  fprintf (stream, _("  -mpid=no                code uses position-dependent data addressing\n"));
  fprintf (stream, _("  -mpid=near              code uses position-independent data addressing,\n"
		     "                            GOT accesses use near DP addressing\n"));
  fprintf (stream, _("  -mpid=far               code uses position-independent data addressing,\n"
		     "                            GOT accesses use far DP addressing\n"));
  fprintf (stream, _("  -mpic                   code addressing is position-independent\n"));
  fprintf (stream, _("  -mno-pic                code addressing is position-dependent\n"));
  /* -mgenerate-rel is only for testsuite use and is deliberately
      undocumented.  */

  fputc ('\n', stream);
  fprintf (stream, _("Supported ARCH values are:"));
  for (i = 0; i < ARRAY_SIZE (tic6x_arches); i++)
    fprintf (stream, " %s", tic6x_arches[i].arch);
  fputc ('\n', stream);
}

/* Update enabled features based on the current architecture and
   related settings.  */
static void
tic6x_update_features (void)
{
  tic6x_features = tic6x_arch_enable;

  tic6x_num_registers
    = (tic6x_arch_enable & (TIC6X_INSN_C64X | TIC6X_INSN_C67XP)) ? 32 : 16;

  tic6x_predicate_a0 = (tic6x_arch_enable & TIC6X_INSN_C64X) ? TRUE : FALSE;

  tic6x_can_cross_fp_boundary
    = (tic6x_arch_enable
       & (TIC6X_INSN_C64X | TIC6X_INSN_C67XP)) ? TRUE : FALSE;

  tic6x_long_data_constraints
    = (tic6x_arch_enable & TIC6X_INSN_C64X) ? FALSE : TRUE;

  tic6x_compact_insns = (tic6x_arch_enable & TIC6X_INSN_C64XP) ? TRUE : FALSE;
}

/* Do configuration after all options have been parsed.  */

void
tic6x_after_parse_args (void)
{
  tic6x_update_features ();
}

/* Parse a .cantunwind directive.  */
static void
s_tic6x_cantunwind (int ignored ATTRIBUTE_UNUSED)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();

  /* GCC sometimes spits out superfluous .cantunwind directives, so ignore
     them.  */
  if (unwind->data_bytes == 0)
    return;

  if (unwind->data_bytes != -1)
    {
      as_bad (_("unexpected .cantunwind directive"));
      return;
    }

  demand_empty_rest_of_line ();

  if (unwind->personality_routine || unwind->personality_index != -1)
    as_bad (_("personality routine specified for cantunwind frame"));

  unwind->personality_index = -2;
}

/* Parse a .handlerdata directive.  */
static void
s_tic6x_handlerdata (int ignored ATTRIBUTE_UNUSED)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();

  if (!unwind->saved_seg)
    {
      as_bad (_("unexpected .handlerdata directive"));
      return;
    }

  if (unwind->table_entry || unwind->personality_index == -2)
    {
      as_bad (_("duplicate .handlerdata directive"));
      return;
    }

  if (unwind->personality_index == -1 && unwind->personality_routine == NULL)
    {
      as_bad (_("personality routine required before .handlerdata directive"));
      return;
    }

  tic6x_output_unwinding (TRUE);
}

/* Parse a .endp directive.  */
static void
s_tic6x_endp (int ignored ATTRIBUTE_UNUSED)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();

  if (unwind->data_bytes != 0)
    {
      /* Output a .exidx entry if we have not already done so.
	 Then switch back to the text section.  */
      if (!unwind->table_entry)
	tic6x_output_unwinding (FALSE);

      subseg_set (unwind->saved_seg, unwind->saved_subseg);
    }

  unwind->saved_seg = NULL;
  unwind->table_entry = NULL;
  unwind->data_bytes = 0;
}

/* Parse a .personalityindex directive.  */
static void
s_tic6x_personalityindex (int ignored ATTRIBUTE_UNUSED)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
  expressionS exp;

  if (unwind->personality_routine || unwind->personality_index != -1)
    as_bad (_("duplicate .personalityindex directive"));

  expression (&exp);

  if (exp.X_op != O_constant
      || exp.X_add_number < 0 || exp.X_add_number > 15)
    {
      as_bad (_("bad personality routine number"));
      ignore_rest_of_line ();
      return;
    }

  unwind->personality_index = exp.X_add_number;

  demand_empty_rest_of_line ();
}

static void
s_tic6x_personality (int ignored ATTRIBUTE_UNUSED)
{
  char *name, c;
  tic6x_unwind_info *unwind = tic6x_get_unwind ();

  if (unwind->personality_routine || unwind->personality_index != -1)
    as_bad (_("duplicate .personality directive"));

  c = get_symbol_name (&name);
  unwind->personality_routine = symbol_find_or_make (name);
  (void) restore_line_pointer (c);
  demand_empty_rest_of_line ();
}

/* Parse a .arch directive.  */
static void
s_tic6x_arch (int ignored ATTRIBUTE_UNUSED)
{
  char c;
  char *arch;

  arch = input_line_pointer;
  while (*input_line_pointer && !ISSPACE (*input_line_pointer))
    input_line_pointer++;
  c = *input_line_pointer;
  *input_line_pointer = 0;

  tic6x_use_arch (arch);
  tic6x_update_features ();
  *input_line_pointer = c;
  demand_empty_rest_of_line ();
}

/* Parse a .ehtype directive.  */

static void
s_tic6x_ehtype (int ignored ATTRIBUTE_UNUSED)
{
  expressionS exp;
  char *p;

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

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

#ifdef md_cons_align
  md_cons_align (4);
#endif


  expression (&exp);

  if (exp.X_op != O_symbol)
    {
      as_bad (_("expected symbol"));
      return;
    }

  p = frag_more (4);
  memset (p, 0, 4);
  fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
	       &exp, 0, BFD_RELOC_C6000_EHTYPE);

  demand_empty_rest_of_line ();
}

/* Parse a .nocmp directive.  */

static void
s_tic6x_nocmp (int ignored ATTRIBUTE_UNUSED)
{
  seg_info (now_seg)->tc_segment_info_data.nocmp = TRUE;
  demand_empty_rest_of_line ();
}

/* .scomm pseudo-op handler.

   This is a new pseudo-op to handle putting objects in .scommon.
   By doing this the linker won't need to do any work,
   and more importantly it removes the implicit -G arg necessary to
   correctly link the object file.  */

static void
s_tic6x_scomm (int ignore ATTRIBUTE_UNUSED)
{
  char *name;
  char c;
  char *p;
  offsetT size;
  symbolS *symbolP;
  offsetT align;
  int align2;

  c = get_symbol_name (&name);

  /* Just after name is now '\0'.  */
  p = input_line_pointer;
  (void) restore_line_pointer (c);
  SKIP_WHITESPACE ();
  if (*input_line_pointer != ',')
    {
      as_bad (_("expected comma after symbol name"));
      ignore_rest_of_line ();
      return;
    }

  /* Skip ','.  */
  input_line_pointer++;
  if ((size = get_absolute_expression ()) < 0)
    {
      /* xgettext:c-format  */
      as_warn (_("invalid length for .scomm directive"));
      ignore_rest_of_line ();
      return;
    }

  /* The third argument to .scomm is the alignment.  */
  if (*input_line_pointer != ',')
    align = 8;
  else
    {
      ++input_line_pointer;
      align = get_absolute_expression ();
      if (align <= 0)
	{
	  as_warn (_("alignment is not a positive number"));
	  align = 8;
	}
    }

  /* Convert to a power of 2 alignment.  */
  if (align)
    {
      for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2)
	continue;
      if (align != 1)
	{
	  as_bad (_("alignment is not a power of 2"));
	  ignore_rest_of_line ();
	  return;
	}
    }
  else
    align2 = 0;

  *p = 0;
  symbolP = symbol_find_or_make (name);
  *p = c;

  if (S_IS_DEFINED (symbolP))
    {
      /* xgettext:c-format  */
      as_bad (_("attempt to re-define symbol `%s'"),
	      S_GET_NAME (symbolP));
      ignore_rest_of_line ();
      return;
    }

  if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
    {
      /* xgettext:c-format  */
      as_bad (_("attempt to redefine `%s' with a different length"),
	      S_GET_NAME (symbolP));

      ignore_rest_of_line ();
      return;
    }

  if (symbol_get_obj (symbolP)->local)
    {
      segT old_sec = now_seg;
      int old_subsec = now_subseg;
      char *pfrag;

      record_alignment (sbss_section, align2);
      subseg_set (sbss_section, 0);

      if (align2)
	frag_align (align2, 0, 0);

      if (S_GET_SEGMENT (symbolP) == sbss_section)
	symbol_get_frag (symbolP)->fr_symbol = 0;

      symbol_set_frag (symbolP, frag_now);

      pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
			(char *) 0);
      *pfrag = 0;
      S_SET_SIZE (symbolP, size);
      S_SET_SEGMENT (symbolP, sbss_section);
      S_CLEAR_EXTERNAL (symbolP);
      subseg_set (old_sec, old_subsec);
    }
  else
    {
      S_SET_VALUE (symbolP, (valueT) size);
      S_SET_ALIGN (symbolP, 1 << align2);
      S_SET_EXTERNAL (symbolP);
      S_SET_SEGMENT (symbolP, &scom_section);
    }

  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;

  demand_empty_rest_of_line ();
}

/* Track for each attribute whether it has been set explicitly (and so
   should not have a default value set by the assembler).  */
static bfd_boolean tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];

/* Parse a .c6xabi_attribute directive.  */

static void
s_tic6x_c6xabi_attribute (int ignored ATTRIBUTE_UNUSED)
{
  int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);

  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
    tic6x_attributes_set_explicitly[tag] = TRUE;
}

typedef struct
{
  const char *name;
  int tag;
} tic6x_attribute_table;

static const tic6x_attribute_table tic6x_attributes[] =
  {
#define TAG(tag, value) { #tag, tag },
#include "elf/tic6x-attrs.h"
#undef TAG
  };

/* Convert an attribute name to a number.  */

int
tic6x_convert_symbolic_attribute (const char *name)
{
  unsigned int i;

  for (i = 0; i < ARRAY_SIZE (tic6x_attributes); i++)
    if (strcmp (name, tic6x_attributes[i].name) == 0)
      return tic6x_attributes[i].tag;

  return -1;
}

const pseudo_typeS md_pseudo_table[] =
  {
    { "arch", s_tic6x_arch, 0 },
    { "c6xabi_attribute", s_tic6x_c6xabi_attribute, 0 },
    { "nocmp", s_tic6x_nocmp, 0 },
    { "scomm",	s_tic6x_scomm, 0 },
    { "word", cons, 4 },
    { "ehtype", s_tic6x_ehtype, 0 },
    { "endp", s_tic6x_endp, 0 },
    { "handlerdata", s_tic6x_handlerdata, 0 },
    { "personalityindex", s_tic6x_personalityindex, 0 },
    { "personality", s_tic6x_personality, 0 },
    { "cantunwind", s_tic6x_cantunwind, 0 },
    { 0, 0, 0 }
  };

/* Hash table of opcodes.  For each opcode name, this stores a pointer
   to a tic6x_opcode_list listing (in an arbitrary order) all opcode
   table entries with that name.  */
static htab_t opcode_hash;

/* Initialize the assembler (called once at assembler startup).  */

void
md_begin (void)
{
  tic6x_opcode_id id;
  flagword applicable;
  segT seg;
  subsegT subseg;

  bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);

  /* Insert opcodes into the hash table.  */
  opcode_hash = str_htab_create ();
  for (id = 0; id < tic6x_opcode_max; id++)
    {
      tic6x_opcode_list *opc = XNEW (tic6x_opcode_list);

      opc->id = id;
      opc->next = str_hash_find (opcode_hash, tic6x_opcode_table[id].name);
      str_hash_insert (opcode_hash, tic6x_opcode_table[id].name, opc, 1);
    }

  /* Save the current subseg so we can restore it [it's the default one and
     we don't want the initial section to be .sbss].  */
  seg = now_seg;
  subseg = now_subseg;

  /* The sbss section is for local .scomm symbols.  */
  sbss_section = subseg_new (".bss", 0);
  seg_info (sbss_section)->bss = 1;

  /* This is copied from perform_an_assembly_pass.  */
  applicable = bfd_applicable_section_flags (stdoutput);
  bfd_set_section_flags (sbss_section, applicable & SEC_ALLOC);

  subseg_set (seg, subseg);

  /* We must construct a fake section similar to bfd_com_section
     but with the name .scommon.  */
  scom_section                = *bfd_com_section_ptr;
  scom_section.name           = ".scommon";
  scom_section.output_section = & scom_section;
  scom_section.symbol         = & scom_symbol;
  scom_section.symbol_ptr_ptr = & scom_section.symbol;
  scom_symbol                 = * bfd_com_section_ptr->symbol;
  scom_symbol.name            = ".scommon";
  scom_symbol.section         = & scom_section;
}

/* Whether the current line being parsed had the "||" parallel bars.  */
static bfd_boolean tic6x_line_parallel;

/* Whether the current line being parsed started "||^" to indicate an
   SPMASKed parallel instruction.  */
static bfd_boolean tic6x_line_spmask;

/* If the current line being parsed had an instruction predicate, the
   creg value for that predicate (which must be nonzero); otherwise
   0.  */
static unsigned int tic6x_line_creg;

/* If the current line being parsed had an instruction predicate, the
   z value for that predicate; otherwise 0.  */
static unsigned int tic6x_line_z;

/* Return 1 (updating input_line_pointer as appropriate) if the line
   starting with C (immediately before input_line_pointer) starts with
   pre-opcode text appropriate for this target, 0 otherwise.  */

int
tic6x_unrecognized_line (int c)
{
  char *p, *endp;
  unsigned int z;
  bfd_boolean areg;
  bfd_boolean bad_predicate;

  switch (c)
    {
    case '|':
      if (input_line_pointer[0] == '|')
	{
	  if (input_line_pointer[1] == '^')
	    {
	      tic6x_line_spmask = TRUE;
	      input_line_pointer += 2;
	    }
	  else
	    input_line_pointer += 1;
	  if (tic6x_line_parallel)
	    as_bad (_("multiple '||' on same line"));
	  tic6x_line_parallel = TRUE;
	  if (tic6x_line_creg)
	    as_bad (_("'||' after predicate"));
	  return 1;
	}
      return 0;

    case '[':
      /* If it doesn't look like a predicate at all, just return 0.
	 If it looks like one but not a valid one, give a better
	 error.  */
      p = input_line_pointer;
      while (*p != ']' && !is_end_of_line[(unsigned char) *p])
	p++;
      if (*p != ']')
	return 0;
      endp = p + 1;
      p = input_line_pointer;
      z = 0;
      bad_predicate = FALSE;
      if (*p == '!')
	{
	  z = 1;
	  p++;
	}
      if (*p == 'A' || *p == 'a')
	areg = TRUE;
      else if (*p == 'B' || *p == 'b')
	areg = FALSE;
      else
	{
	  areg = TRUE; /* Avoid uninitialized warning.  */
	  bad_predicate = TRUE;
	}
      if (!bad_predicate)
	{
	  p++;
	  if (*p != '0' && *p != '1' && *p != '2')
	    bad_predicate = TRUE;
	  else if (p[1] != ']')
	    bad_predicate = TRUE;
	  else
	    input_line_pointer = p + 2;
	}

      if (tic6x_line_creg)
	as_bad (_("multiple predicates on same line"));

      if (bad_predicate)
	{
	  char ctmp = *endp;
	  *endp = 0;
	  as_bad (_("bad predicate '%s'"), input_line_pointer - 1);
	  *endp = ctmp;
	  input_line_pointer = endp;
	  return 1;
	}

      switch (*p)
	{
	case '0':
	  tic6x_line_creg = (areg ? 6 : 1);
	  if (areg && !tic6x_predicate_a0)
	    as_bad (_("predication on A0 not supported on this architecture"));
	  break;

	case '1':
	  tic6x_line_creg = (areg ? 4 : 2);
	  break;

	case '2':
	  tic6x_line_creg = (areg ? 5 : 3);
	  break;

	default:
	  abort ();
	}

      tic6x_line_z = z;
      return 1;

    default:
      return 0;
    }
}

/* Do any target-specific handling of a label required.  */

void
tic6x_frob_label (symbolS *sym)
{
  segment_info_type *si;
  tic6x_label_list *list;

  if (tic6x_line_parallel)
    {
      as_bad (_("label after '||'"));
      tic6x_line_parallel = FALSE;
      tic6x_line_spmask = FALSE;
    }
  if (tic6x_line_creg)
    {
      as_bad (_("label after predicate"));
      tic6x_line_creg = 0;
      tic6x_line_z = 0;
    }

  si = seg_info (now_seg);
  list = si->tc_segment_info_data.label_list;
  si->tc_segment_info_data.label_list = XNEW (tic6x_label_list);
  si->tc_segment_info_data.label_list->next = list;
  si->tc_segment_info_data.label_list->label = sym;

  /* Defining tc_frob_label overrides the ELF definition of
     obj_frob_label, so we need to apply its effects here.  */
  dwarf2_emit_label (sym);
}

/* At end-of-line, give errors for start-of-line decorations that
   needed an instruction but were not followed by one.  */

static void
tic6x_end_of_line (void)
{
  if (tic6x_line_parallel)
    {
      as_bad (_("'||' not followed by instruction"));
      tic6x_line_parallel = FALSE;
      tic6x_line_spmask = FALSE;
    }
  if (tic6x_line_creg)
    {
      as_bad (_("predicate not followed by instruction"));
      tic6x_line_creg = 0;
      tic6x_line_z = 0;
    }
}

/* Do any target-specific handling of the start of a logical line.  */

void
tic6x_start_line_hook (void)
{
  tic6x_end_of_line ();
}

/* Do target-specific handling immediately after an input file from
   the command line, and any other inputs it includes, have been
   read.  */

void
tic6x_cleanup (void)
{
  tic6x_end_of_line ();
}

/* Do target-specific initialization after arguments have been
   processed and the output file created.  */

void
tic6x_init_after_args (void)
{
  elf32_tic6x_set_use_rela_p (stdoutput, tic6x_generate_rela);
}

/* Free LIST of labels (possibly NULL).  */

static void
tic6x_free_label_list (tic6x_label_list *list)
{
  while (list)
    {
      tic6x_label_list *old = list;

      list = list->next;
      free (old);
    }
}

/* Handle a data alignment of N bytes.  */

void
tic6x_cons_align (int n ATTRIBUTE_UNUSED)
{
  segment_info_type *seginfo = seg_info (now_seg);

  /* Data means there is no current execute packet, and that any label
     applies to that data rather than a subsequent instruction.  */
  tic6x_free_label_list (seginfo->tc_segment_info_data.label_list);
  seginfo->tc_segment_info_data.label_list = NULL;
  seginfo->tc_segment_info_data.execute_packet_frag = NULL;
  seginfo->tc_segment_info_data.last_insn_lsb = NULL;
  seginfo->tc_segment_info_data.spmask_addr = NULL;
  seginfo->tc_segment_info_data.func_units_used = 0;
}

/* Handle an alignment directive.  Return TRUE if the
   machine-independent frag generation should be skipped.  */

bfd_boolean
tic6x_do_align (int n, char *fill, int len ATTRIBUTE_UNUSED, int max)
{
  /* Given code alignments of 4, 8, 16 or 32 bytes, we try to handle
     them in the md_end pass by inserting NOPs in parallel with
     previous instructions.  We only do this in sections containing
     nothing but instructions.  Code alignments of 1 or 2 bytes have
     no effect in such sections (but we record them with
     machine-dependent frags anyway so they can be skipped or
     converted to machine-independent), while those of more than 64
     bytes cannot reliably be handled in this way.  */
  if (n > 0
      && max >= 0
      && max < (1 << n)
      && !need_pass_2
      && fill == NULL
      && subseg_text_p (now_seg))
    {
      fragS *align_frag;
      char *p;

      if (n > 5)
	return FALSE;

      /* Machine-independent code would generate a frag here, but we
	 wish to handle it in a machine-dependent way.  */
      if (frag_now_fix () != 0)
	{
	  if (frag_now->fr_type != rs_machine_dependent)
	    frag_wane (frag_now);

	  frag_new (0);
	}
      frag_grow (32);
      align_frag = frag_now;
      p = frag_var (rs_machine_dependent, 32, 32, max, NULL, n, NULL);
      /* This must be the same as the frag to which a pointer was just
	 saved.  */
      if (p != align_frag->fr_literal)
	abort ();
      align_frag->tc_frag_data.is_insns = FALSE;
      return TRUE;
    }
  else
    return FALSE;
}

/* Types of operand for parsing purposes.  These are used as bit-masks
   to tell tic6x_parse_operand what forms of operand are
   permitted.  */
#define TIC6X_OP_EXP		0x0001u
#define TIC6X_OP_REG		0x0002u
#define TIC6X_OP_REGPAIR	0x0004u
#define TIC6X_OP_IRP		0x0008u
#define TIC6X_OP_NRP		0x0010u
/* With TIC6X_OP_MEM_NOUNREG, the contents of a () offset are always
   interpreted as an expression, which may be a symbol with the same
   name as a register that ends up being implicitly DP-relative.  With
   TIC6X_OP_MEM_UNREG, the contents of a () offset are interpreted as
   a register if they match one, and failing that as an expression,
   which must be constant.  */
#define TIC6X_OP_MEM_NOUNREG	0x0020u
#define TIC6X_OP_MEM_UNREG	0x0040u
#define TIC6X_OP_CTRL		0x0080u
#define TIC6X_OP_FUNC_UNIT	0x0100u

/* A register or register pair read by the assembler.  */
typedef struct
{
  /* The side the register is on (1 or 2).  */
  unsigned int side;
  /* The register number (0 to 31).  */
  unsigned int num;
} tic6x_register;

/* Types of modification of a base address.  */
typedef enum
  {
    tic6x_mem_mod_none,
    tic6x_mem_mod_plus,
    tic6x_mem_mod_minus,
    tic6x_mem_mod_preinc,
    tic6x_mem_mod_predec,
    tic6x_mem_mod_postinc,
    tic6x_mem_mod_postdec
  } tic6x_mem_mod;

/* Scaled [] or unscaled () nature of an offset.  */
typedef enum
  {
    tic6x_offset_none,
    tic6x_offset_scaled,
    tic6x_offset_unscaled
  } tic6x_mem_scaling;

/* A memory operand read by the assembler.  */
typedef struct
{
  /* The base register.  */
  tic6x_register base_reg;
  /* How the base register is modified.  */
  tic6x_mem_mod mod;
  /* Whether there is an offset (required with plain "+" and "-"), and
     whether it is scaled or unscaled if so.  */
  tic6x_mem_scaling scaled;
  /* Whether the offset is a register (TRUE) or an expression
     (FALSE).  */
  bfd_boolean offset_is_reg;
  /* The offset.  */
  union
  {
    expressionS exp;
    tic6x_register reg;
  } offset;
} tic6x_mem_ref;

/* A functional unit in SPMASK operands read by the assembler.  */
typedef struct
{
  /* The basic unit.  */
  tic6x_func_unit_base base;
  /* The side (1 or 2).  */
  unsigned int side;
} tic6x_func_unit_operand;

/* An operand read by the assembler.  */
typedef struct
{
  /* The syntactic form of the operand, as one of the bit-masks
     above.  */
  unsigned int form;
  /* The operand value.  */
  union
  {
    /* An expression: TIC6X_OP_EXP.  */
    expressionS exp;
    /* A register: TIC6X_OP_REG, TIC6X_OP_REGPAIR.  */
    tic6x_register reg;
    /* A memory reference: TIC6X_OP_MEM_NOUNREG,
       TIC6X_OP_MEM_UNREG.  */
    tic6x_mem_ref mem;
    /* A control register: TIC6X_OP_CTRL.  */
    tic6x_ctrl_id ctrl;
    /* A functional unit: TIC6X_OP_FUNC_UNIT.  */
    tic6x_func_unit_operand func_unit;
  } value;
} tic6x_operand;

#define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)

/* Parse a register operand, or part of an operand, starting at *P.
   If syntactically OK (including that the number is in the range 0 to
   31, but not necessarily in range for this architecture), return
   TRUE, putting the register side and number in *REG and update *P to
   point immediately after the register number; otherwise return FALSE
   without changing *P (but possibly changing *REG).  Do not print any
   diagnostics.  */

static bfd_boolean
tic6x_parse_register (char **p, tic6x_register *reg)
{
  char *r = *p;

  switch (*r)
    {
    case 'a':
    case 'A':
      reg->side = 1;
      break;

    case 'b':
    case 'B':
      reg->side = 2;
      break;

    default:
      return FALSE;
    }
  r++;

  if (*r >= '0' && *r <= '9')
    {
      reg->num = *r - '0';
      r++;
    }
  else
    return FALSE;

  if (reg->num > 0 && *r >= '0' && *r <= '9')
    {
      reg->num = reg->num * 10 + (*r - '0');
      r++;
    }

  if (*r >= '0' && *r <= '9')
    return FALSE;

  if (reg->num >= 32)
    return FALSE;
  *p = r;
  return TRUE;
}

/* Parse the initial two characters of a functional unit name starting
   at *P.  If OK, set *BASE and *SIDE and return TRUE; otherwise,
   return FALSE.  */

static bfd_boolean
tic6x_parse_func_unit_base (char *p, tic6x_func_unit_base *base,
			    unsigned int *side)
{
  bfd_boolean good_func_unit = TRUE;
  tic6x_func_unit_base maybe_base = tic6x_func_unit_nfu;
  unsigned int maybe_side = 0;

  switch (p[0])
    {
    case 'd':
    case 'D':
      maybe_base = tic6x_func_unit_d;
      break;

    case 'l':
    case 'L':
      maybe_base = tic6x_func_unit_l;
      break;

    case 'm':
    case 'M':
      maybe_base = tic6x_func_unit_m;
      break;

    case 's':
    case 'S':
      maybe_base = tic6x_func_unit_s;
      break;

    default:
      good_func_unit = FALSE;
      break;
    }

  if (good_func_unit)
    switch (p[1])
      {
      case '1':
	maybe_side = 1;
	break;

      case '2':
	maybe_side = 2;
	break;

      default:
	good_func_unit = FALSE;
	break;
      }

  if (good_func_unit)
    {
      *base = maybe_base;
      *side = maybe_side;
    }

  return good_func_unit;
}

/* Parse an operand starting at *P.  If the operand parses OK, return
   TRUE and store the value in *OP; otherwise return FALSE (possibly
   changing *OP).  In any case, update *P to point to the following
   comma or end of line.  The possible operand forms are given by
   OP_FORMS.  For diagnostics, this is operand OPNO of an opcode
   starting at STR, length OPC_LEN.  */

static bfd_boolean
tic6x_parse_operand (char **p, tic6x_operand *op, unsigned int op_forms,
		     char *str, int opc_len, unsigned int opno)
{
  bfd_boolean operand_parsed = FALSE;
  char *q = *p;

  if ((op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG))
      == (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG))
    abort ();

  /* Check for functional unit names for SPMASK and SPMASKR.  */
  if (!operand_parsed && (op_forms & TIC6X_OP_FUNC_UNIT))
    {
      tic6x_func_unit_base base = tic6x_func_unit_nfu;
      unsigned int side = 0;

      if (tic6x_parse_func_unit_base (q, &base, &side))
	{
	  char *rq = q + 2;

	  skip_whitespace (rq);
	  if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
	    {
	      op->form = TIC6X_OP_FUNC_UNIT;
	      op->value.func_unit.base = base;
	      op->value.func_unit.side = side;
	      operand_parsed = TRUE;
	      q = rq;
	    }
	}
    }

  /* Check for literal "irp".  */
  if (!operand_parsed && (op_forms & TIC6X_OP_IRP))
    {
      if ((q[0] == 'i' || q[0] == 'I')
	  && (q[1] == 'r' || q[1] == 'R')
	  && (q[2] == 'p' || q[2] == 'P'))
	{
	  char *rq = q + 3;

	  skip_whitespace (rq);
	  if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
	    {
	      op->form = TIC6X_OP_IRP;
	      operand_parsed = TRUE;
	      q = rq;
	    }
	}
    }

  /* Check for literal "nrp".  */
  if (!operand_parsed && (op_forms & TIC6X_OP_NRP))
    {
      if ((q[0] == 'n' || q[0] == 'N')
	  && (q[1] == 'r' || q[1] == 'R')
	  && (q[2] == 'p' || q[2] == 'P'))
	{
	  char *rq = q + 3;

	  skip_whitespace (rq);
	  if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
	    {
	      op->form = TIC6X_OP_NRP;
	      operand_parsed = TRUE;
	      q = rq;
	    }
	}
    }

  /* Check for control register names.  */
  if (!operand_parsed && (op_forms & TIC6X_OP_CTRL))
    {
      tic6x_ctrl_id crid;

      for (crid = 0; crid < tic6x_ctrl_max; crid++)
	{
	  size_t len = strlen (tic6x_ctrl_table[crid].name);

	  if (strncasecmp (tic6x_ctrl_table[crid].name, q, len) == 0)
	    {
	      char *rq = q + len;

	      skip_whitespace (rq);
	      if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
		{
		  op->form = TIC6X_OP_CTRL;
		  op->value.ctrl = crid;
		  operand_parsed = TRUE;
		  q = rq;
		  if (!(tic6x_ctrl_table[crid].isa_variants & tic6x_features))
		    as_bad (_("control register '%s' not supported "
			      "on this architecture"),
			    tic6x_ctrl_table[crid].name);
		}
	    }
	}
    }

  /* See if this looks like a memory reference.  */
  if (!operand_parsed
      && (op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG)))
    {
      bfd_boolean mem_ok = TRUE;
      char *mq = q;
      tic6x_mem_mod mem_mod = tic6x_mem_mod_none;
      tic6x_register base_reg;
      bfd_boolean require_offset, permit_offset;
      tic6x_mem_scaling scaled;
      bfd_boolean offset_is_reg;
      expressionS offset_exp;
      tic6x_register offset_reg;

      if (*mq == '*')
	mq++;
      else
	mem_ok = FALSE;

      if (mem_ok)
	{
	  skip_whitespace (mq);
	  switch (*mq)
	    {
	    case '+':
	      if (mq[1] == '+')
		{
		  mem_mod = tic6x_mem_mod_preinc;
		  mq += 2;
		}
	      else
		{
		  mem_mod = tic6x_mem_mod_plus;
		  mq++;
		}
	      break;

	    case '-':
	      if (mq[1] == '-')
		{
		  mem_mod = tic6x_mem_mod_predec;
		  mq += 2;
		}
	      else
		{
		  mem_mod = tic6x_mem_mod_minus;
		  mq++;
		}
	      break;

	    default:
	      break;
	    }
	}

      if (mem_ok)
	{
	  skip_whitespace (mq);
	  mem_ok = tic6x_parse_register (&mq, &base_reg);
	}

      if (mem_ok && mem_mod == tic6x_mem_mod_none)
	{
	  skip_whitespace (mq);
	  if (mq[0] == '+' && mq[1] == '+')
	    {
	      mem_mod = tic6x_mem_mod_postinc;
	      mq += 2;
	    }
	  else if (mq[0] == '-' && mq[1] == '-')
	    {
	      mem_mod = tic6x_mem_mod_postdec;
	      mq += 2;
	    }
	}

      if (mem_mod == tic6x_mem_mod_none)
	permit_offset = FALSE;
      else
	permit_offset = TRUE;
      if (mem_mod == tic6x_mem_mod_plus || mem_mod == tic6x_mem_mod_minus)
	require_offset = TRUE;
      else
	require_offset = FALSE;
      scaled = tic6x_offset_none;
      offset_is_reg = FALSE;

      if (mem_ok && permit_offset)
	{
	  char endc = 0;

	  skip_whitespace (mq);
	  switch (*mq)
	    {
	    case '[':
	      scaled = tic6x_offset_scaled;
	      mq++;
	      endc = ']';
	      break;

	    case '(':
	      scaled = tic6x_offset_unscaled;
	      mq++;
	      endc = ')';
	      break;

	    default:
	      break;
	    }
	  if (scaled != tic6x_offset_none)
	    {
	      skip_whitespace (mq);
	      if (scaled == tic6x_offset_scaled
		  || (op_forms & TIC6X_OP_MEM_UNREG))
		{
		  bfd_boolean reg_ok;
		  char *rq = mq;

		  reg_ok = tic6x_parse_register (&rq, &offset_reg);
		  if (reg_ok)
		    {
		      skip_whitespace (rq);
		      if (*rq == endc)
			{
			  mq = rq;
			  offset_is_reg = TRUE;
			}
		    }
		}
	      if (!offset_is_reg)
		{
		  char *save_input_line_pointer;

		  save_input_line_pointer = input_line_pointer;
		  input_line_pointer = mq;
		  expression (&offset_exp);
		  mq = input_line_pointer;
		  input_line_pointer = save_input_line_pointer;
		}
	      skip_whitespace (mq);
	      if (*mq == endc)
		mq++;
	      else
		mem_ok = FALSE;
	    }
	}

      if (mem_ok && require_offset && scaled == tic6x_offset_none)
	mem_ok = FALSE;

      if (mem_ok)
	{
	  skip_whitespace (mq);
	  if (!is_end_of_line[(unsigned char) *mq] && *mq != ',')
	    mem_ok = FALSE;
	}

      if (mem_ok)
	{
	  op->form = op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG);
	  op->value.mem.base_reg = base_reg;
	  op->value.mem.mod = mem_mod;
	  op->value.mem.scaled = scaled;
	  op->value.mem.offset_is_reg = offset_is_reg;
	  if (offset_is_reg)
	    op->value.mem.offset.reg = offset_reg;
	  else
	    op->value.mem.offset.exp = offset_exp;
	  operand_parsed = TRUE;
	  q = mq;
	  if (base_reg.num >= tic6x_num_registers)
	    as_bad (_("register number %u not supported on this architecture"),
		    base_reg.num);
	  if (offset_is_reg && offset_reg.num >= tic6x_num_registers)
	    as_bad (_("register number %u not supported on this architecture"),
		    offset_reg.num);
	}
    }

  /* See if this looks like a register or register pair.  */
  if (!operand_parsed && (op_forms & (TIC6X_OP_REG | TIC6X_OP_REGPAIR)))
    {
      tic6x_register first_reg, second_reg;
      bfd_boolean reg_ok;
      char *rq = q;

      reg_ok = tic6x_parse_register (&rq, &first_reg);

      if (reg_ok)
	{
	  if (*rq == ':' && (op_forms & TIC6X_OP_REGPAIR))
	    {
	      rq++;
	      reg_ok = tic6x_parse_register (&rq, &second_reg);
	      if (reg_ok)
		{
		  skip_whitespace (rq);
		  if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
		    {
		      if ((second_reg.num & 1)
			  || (first_reg.num != second_reg.num + 1)
			  || (first_reg.side != second_reg.side))
			as_bad (_("register pair for operand %u of '%.*s'"
				  " not a valid even/odd pair"), opno,
				opc_len, str);
		      op->form = TIC6X_OP_REGPAIR;
		      op->value.reg = second_reg;
		      operand_parsed = TRUE;
		      q = rq;
		    }
		}
	    }
	  else if (op_forms & TIC6X_OP_REG)
	    {
	      skip_whitespace (rq);
	      if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
		{
		  op->form = TIC6X_OP_REG;
		  op->value.reg = first_reg;
		  operand_parsed = TRUE;
		  q = rq;
		}
	    }
	}
      if (operand_parsed)
	{
	  if (first_reg.num >= tic6x_num_registers)
	    as_bad (_("register number %u not supported on this architecture"),
		    first_reg.num);
	  if (op->form == TIC6X_OP_REGPAIR
	      && second_reg.num >= tic6x_num_registers)
	    as_bad (_("register number %u not supported on this architecture"),
		    second_reg.num);
	}
    }

  /* Otherwise, parse it as an expression.  */
  if (!operand_parsed && (op_forms & TIC6X_OP_EXP))
    {
      char *save_input_line_pointer;

      save_input_line_pointer = input_line_pointer;
      input_line_pointer = q;
      op->form = TIC6X_OP_EXP;
      expression (&op->value.exp);
      q = input_line_pointer;
      input_line_pointer = save_input_line_pointer;
      operand_parsed = TRUE;
    }

  if (operand_parsed)
    {
      /* Now the operand has been parsed, there must be nothing more
	 before the comma or end of line.  */
      skip_whitespace (q);
      if (!is_end_of_line[(unsigned char) *q] && *q != ',')
	{
	  operand_parsed = FALSE;
	  as_bad (_("junk after operand %u of '%.*s'"), opno,
		  opc_len, str);
	  while (!is_end_of_line[(unsigned char) *q] && *q != ',')
	    q++;
	}
    }
  else
    {
      /* This could not be parsed as any acceptable form of
	 operand.  */
      switch (op_forms)
	{
	case TIC6X_OP_REG | TIC6X_OP_REGPAIR:
	  as_bad (_("bad register or register pair for operand %u of '%.*s'"),
		  opno, opc_len, str);
	  break;

	case TIC6X_OP_REG | TIC6X_OP_CTRL:
	case TIC6X_OP_REG:
	  as_bad (_("bad register for operand %u of '%.*s'"),
		  opno, opc_len, str);
	  break;

	case TIC6X_OP_REGPAIR:
	  as_bad (_("bad register pair for operand %u of '%.*s'"),
		  opno, opc_len, str);
	  break;

	case TIC6X_OP_FUNC_UNIT:
	  as_bad (_("bad functional unit for operand %u of '%.*s'"),
		  opno, opc_len, str);
	  break;

	default:
	  as_bad (_("bad operand %u of '%.*s'"),
		  opno, opc_len, str);
	  break;

	}
      while (!is_end_of_line[(unsigned char) *q] && *q != ',')
	q++;
    }
  *p = q;
  return operand_parsed;
}

/* Table of assembler operators and associated O_* values.  */
typedef struct
{
  const char *name;
  operatorT op;
} tic6x_operator_table;
static const tic6x_operator_table tic6x_operators[] = {
#define O_dsbt_index O_md1
  { "dsbt_index", O_dsbt_index },
#define O_got O_md2
  { "got", O_got },
#define O_dpr_got O_md3
  { "dpr_got", O_dpr_got },
#define O_dpr_byte O_md4
  { "dpr_byte", O_dpr_byte },
#define O_dpr_hword O_md5
  { "dpr_hword", O_dpr_hword },
#define O_dpr_word O_md6
  { "dpr_word", O_dpr_word },
#define O_pcr_offset O_md7
  { "pcr_offset", O_pcr_offset }
};

/* Parse a name in some machine-specific way.  Used on C6X to handle
   assembler operators.  */

int
tic6x_parse_name (const char *name, expressionS *exprP,
		  enum expr_mode mode ATTRIBUTE_UNUSED, char *nextchar)
{
  char *p = input_line_pointer;
  char c, *name_start, *name_end;
  const char *inner_name;
  unsigned int i;
  operatorT op = O_illegal;
  symbolS *sym, *op_sym = NULL;

  if (*name != '$')
    return 0;

  for (i = 0; i < ARRAY_SIZE (tic6x_operators); i++)
    if (strcasecmp (name + 1, tic6x_operators[i].name) == 0)
      {
	op = tic6x_operators[i].op;
	break;
      }

  if (op == O_illegal)
    return 0;

  *input_line_pointer = *nextchar;
  skip_whitespace (p);

  if (*p != '(')
    {
      *input_line_pointer = 0;
      return 0;
    }
  p++;
  skip_whitespace (p);

  if (!is_name_beginner (*p))
    {
      *input_line_pointer = 0;
      return 0;
    }

  name_start = p;
  p++;
  while (is_part_of_name (*p))
    p++;
  name_end = p;
  skip_whitespace (p);

  if (op == O_pcr_offset)
    {
      char *op_name_start, *op_name_end;

      if (*p != ',')
	{
	  *input_line_pointer = 0;
	  return 0;
	}
      p++;
      skip_whitespace (p);

      if (!is_name_beginner (*p))
	{
	  *input_line_pointer = 0;
	  return 0;
	}

      op_name_start = p;
      p++;
      while (is_part_of_name (*p))
	p++;
      op_name_end = p;
      skip_whitespace (p);

      c = *op_name_end;
      *op_name_end = 0;
      op_sym = symbol_find_or_make (op_name_start);
      *op_name_end = c;
    }

  if (*p != ')')
    {
      *input_line_pointer = 0;
      return 0;
    }

  input_line_pointer = p + 1;
  *nextchar = *input_line_pointer;
  *input_line_pointer = 0;

  c = *name_end;
  *name_end = 0;
  inner_name = name_start;
  if (op == O_dsbt_index && strcmp (inner_name, "__c6xabi_DSBT_BASE") != 0)
    {
      as_bad (_("$DSBT_INDEX must be used with __c6xabi_DSBT_BASE"));
      inner_name = "__c6xabi_DSBT_BASE";
    }
  sym = symbol_find_or_make (inner_name);
  *name_end = c;

  exprP->X_op = op;
  exprP->X_add_symbol = sym;
  exprP->X_add_number = 0;
  exprP->X_op_symbol = op_sym;
  exprP->X_md = 0;

  return 1;
}

/* Create a fixup for an expression.  Same arguments as fix_new_exp,
   plus FIX_ADDA which is TRUE for ADDA instructions (to indicate that
   fixes resolving to constants should have those constants implicitly
   shifted) and FALSE otherwise, but look for C6X-specific expression
   types and adjust the relocations or give errors accordingly.  */

static void
tic6x_fix_new_exp (fragS *frag, int where, int size, expressionS *exp,
		   int pcrel, bfd_reloc_code_real_type r_type,
		   bfd_boolean fix_adda)
{
  bfd_reloc_code_real_type new_reloc = BFD_RELOC_UNUSED;
  symbolS *subsy = NULL;
  fixS *fix;

  switch (exp->X_op)
    {
    case O_dsbt_index:
      switch (r_type)
	{
	case BFD_RELOC_C6000_SBR_U15_W:
	  new_reloc = BFD_RELOC_C6000_DSBT_INDEX;
	  break;

	default:
	  as_bad (_("$DSBT_INDEX not supported in this context"));
	  return;
	}
      break;

    case O_got:
      switch (r_type)
	{
	case BFD_RELOC_C6000_SBR_U15_W:
	  new_reloc = BFD_RELOC_C6000_SBR_GOT_U15_W;
	  break;

	default:
	  as_bad (_("$GOT not supported in this context"));
	  return;
	}
      break;

    case O_dpr_got:
      switch (r_type)
	{
	case BFD_RELOC_C6000_ABS_L16:
	  new_reloc = BFD_RELOC_C6000_SBR_GOT_L16_W;
	  break;

	case BFD_RELOC_C6000_ABS_H16:
	  new_reloc = BFD_RELOC_C6000_SBR_GOT_H16_W;
	  break;

	default:
	  as_bad (_("$DPR_GOT not supported in this context"));
	  return;
	}
      break;

    case O_dpr_byte:
      switch (r_type)
	{
	case BFD_RELOC_C6000_ABS_S16:
	  new_reloc = BFD_RELOC_C6000_SBR_S16;
	  break;

	case BFD_RELOC_C6000_ABS_L16:
	  new_reloc = BFD_RELOC_C6000_SBR_L16_B;
	  break;

	case BFD_RELOC_C6000_ABS_H16:
	  new_reloc = BFD_RELOC_C6000_SBR_H16_B;
	  break;

	default:
	  as_bad (_("$DPR_BYTE not supported in this context"));
	  return;
	}
      break;

    case O_dpr_hword:
      switch (r_type)
	{
	case BFD_RELOC_C6000_ABS_L16:
	  new_reloc = BFD_RELOC_C6000_SBR_L16_H;
	  break;

	case BFD_RELOC_C6000_ABS_H16:
	  new_reloc = BFD_RELOC_C6000_SBR_H16_H;
	  break;

	default:
	  as_bad (_("$DPR_HWORD not supported in this context"));
	  return;
	}
      break;

    case O_dpr_word:
      switch (r_type)
	{
	case BFD_RELOC_C6000_ABS_L16:
	  new_reloc = BFD_RELOC_C6000_SBR_L16_W;
	  break;

	case BFD_RELOC_C6000_ABS_H16:
	  new_reloc = BFD_RELOC_C6000_SBR_H16_W;
	  break;

	default:
	  as_bad (_("$DPR_WORD not supported in this context"));
	  return;
	}
      break;

    case O_pcr_offset:
      subsy = exp->X_op_symbol;
      switch (r_type)
	{
	case BFD_RELOC_C6000_ABS_S16:
	case BFD_RELOC_C6000_ABS_L16:
	  new_reloc = BFD_RELOC_C6000_PCR_L16;
	  break;

	case BFD_RELOC_C6000_ABS_H16:
	  new_reloc = BFD_RELOC_C6000_PCR_H16;
	  break;

	default:
	  as_bad (_("$PCR_OFFSET not supported in this context"));
	  return;
	}
      break;

    case O_symbol:
      break;

    default:
      if (pcrel)
	{
	  as_bad (_("invalid PC-relative operand"));
	  return;
	}
      break;
    }

  if (new_reloc == BFD_RELOC_UNUSED)
    fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
  else
    fix = fix_new (frag, where, size, exp->X_add_symbol, exp->X_add_number,
		   pcrel, new_reloc);
  fix->tc_fix_data.fix_subsy = subsy;
  fix->tc_fix_data.fix_adda = fix_adda;
}

/* Generate a fix for a constant (.word etc.).  Needed to ensure these
   go through the error checking in tic6x_fix_new_exp.  */

void
tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp,
		    bfd_reloc_code_real_type r_type)
{
  switch (size)
    {
    case 1:
      r_type = BFD_RELOC_8;
      break;

    case 2:
      r_type = BFD_RELOC_16;
      break;

    case 4:
      r_type = BFD_RELOC_32;
      break;

    default:
      as_bad (_("no %d-byte relocations available"), size);
      return;
    }

  tic6x_fix_new_exp (frag, where, size, exp, 0, r_type, FALSE);
}

/* Initialize target-specific fix data.  */

void
tic6x_init_fix_data (fixS *fixP)
{
  fixP->tc_fix_data.fix_adda = FALSE;
  fixP->tc_fix_data.fix_subsy = NULL;
}

/* Return true if the fix can be handled by GAS, false if it must
   be passed through to the linker.  */

bfd_boolean
tic6x_fix_adjustable (fixS *fixP)
{
  switch (fixP->fx_r_type)
    {
      /* Adjust_reloc_syms doesn't know about the GOT.  */
    case BFD_RELOC_C6000_SBR_GOT_U15_W:
    case BFD_RELOC_C6000_SBR_GOT_H16_W:
    case BFD_RELOC_C6000_SBR_GOT_L16_W:
    case BFD_RELOC_C6000_EHTYPE:
      return 0;

    case BFD_RELOC_C6000_PREL31:
      return 0;

    case BFD_RELOC_C6000_PCR_H16:
    case BFD_RELOC_C6000_PCR_L16:
      return 0;

    default:
      return 1;
    }
}

/* Given the fine-grained form of an operand, return the coarse
   (bit-mask) form.  */

static unsigned int
tic6x_coarse_operand_form (tic6x_operand_form form)
{
  switch (form)
    {
    case tic6x_operand_asm_const:
    case tic6x_operand_link_const:
      return TIC6X_OP_EXP;

    case tic6x_operand_reg:
    case tic6x_operand_xreg:
    case tic6x_operand_dreg:
    case tic6x_operand_areg:
    case tic6x_operand_retreg:
      return TIC6X_OP_REG;

    case tic6x_operand_regpair:
    case tic6x_operand_xregpair:
    case tic6x_operand_dregpair:
      return TIC6X_OP_REGPAIR;

    case tic6x_operand_irp:
      return TIC6X_OP_IRP;

    case tic6x_operand_nrp:
      return TIC6X_OP_NRP;

    case tic6x_operand_ctrl:
      return TIC6X_OP_CTRL;

    case tic6x_operand_mem_short:
    case tic6x_operand_mem_long:
    case tic6x_operand_mem_deref:
      return TIC6X_OP_MEM_NOUNREG;

    case tic6x_operand_mem_ndw:
      return TIC6X_OP_MEM_UNREG;

    case tic6x_operand_func_unit:
      return TIC6X_OP_FUNC_UNIT;

    default:
      abort ();
    }
}

/* How an operand may match or not match a desired form.  If different
   instruction alternatives fail in different ways, the first failure
   in this list determines the diagnostic.  */
typedef enum
  {
    /* Matches.  */
    tic6x_match_matches,
    /* Bad coarse form.  */
    tic6x_match_coarse,
    /* Not constant.  */
    tic6x_match_non_const,
    /* Register on wrong side.  */
    tic6x_match_wrong_side,
    /* Not a valid address register.  */
    tic6x_match_bad_address,
    /* Not a valid return address register.  */
    tic6x_match_bad_return,
    /* Control register not readable.  */
    tic6x_match_ctrl_write_only,
    /* Control register not writable.  */
    tic6x_match_ctrl_read_only,
    /* Not a valid memory reference for this instruction.  */
    tic6x_match_bad_mem
  } tic6x_operand_match;

/* Return whether an operand matches the given fine-grained form and
   read/write usage, and, if it does not match, how it fails to match.
   The main functional unit side is SIDE; the cross-path side is CROSS
   (the same as SIDE if a cross path not used); the data side is
   DATA_SIDE.  */
static tic6x_operand_match
tic6x_operand_matches_form (const tic6x_operand *op, tic6x_operand_form form,
			    tic6x_rw rw, unsigned int side, unsigned int cross,
			    unsigned int data_side)
{
  unsigned int coarse = tic6x_coarse_operand_form (form);

  if (coarse != op->form)
    return tic6x_match_coarse;

  switch (form)
    {
    case tic6x_operand_asm_const:
      if (op->value.exp.X_op == O_constant)
	return tic6x_match_matches;
      else
	return tic6x_match_non_const;

    case tic6x_operand_link_const:
    case tic6x_operand_irp:
    case tic6x_operand_nrp:
    case tic6x_operand_func_unit:
      /* All expressions are link-time constants, although there may
	 not be relocations to express them in the output file.  "irp"
	 and "nrp" are unique operand values.  All parsed functional
	 unit names are valid.  */
      return tic6x_match_matches;

    case tic6x_operand_reg:
    case tic6x_operand_regpair:
      if (op->value.reg.side == side)
	return tic6x_match_matches;
      else
	return tic6x_match_wrong_side;

    case tic6x_operand_xreg:
    case tic6x_operand_xregpair:
      if (op->value.reg.side == cross)
	return tic6x_match_matches;
      else
	return tic6x_match_wrong_side;

    case tic6x_operand_dreg:
    case tic6x_operand_dregpair:
      if (op->value.reg.side == data_side)
	return tic6x_match_matches;
      else
	return tic6x_match_wrong_side;

    case tic6x_operand_areg:
      if (op->value.reg.side != cross)
	return tic6x_match_wrong_side;
      else if (op->value.reg.side == 2
	       && (op->value.reg.num == 14 || op->value.reg.num == 15))
	return tic6x_match_matches;
      else
	return tic6x_match_bad_address;

    case tic6x_operand_retreg:
      if (op->value.reg.side != side)
	return tic6x_match_wrong_side;
      else if (op->value.reg.num != 3)
	return tic6x_match_bad_return;
      else
	return tic6x_match_matches;

    case tic6x_operand_ctrl:
      switch (rw)
	{
	case tic6x_rw_read:
	  if (tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read
	      || tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read_write)
	    return tic6x_match_matches;
	  else
	    return tic6x_match_ctrl_write_only;

	case tic6x_rw_write:
	  if (tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_write
	      || tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read_write)
	    return tic6x_match_matches;
	  else
	    return tic6x_match_ctrl_read_only;

	default:
	  abort ();
	}

    case tic6x_operand_mem_deref:
      if (op->value.mem.mod != tic6x_mem_mod_none)
	return tic6x_match_bad_mem;
      else if (op->value.mem.scaled != tic6x_offset_none)
	abort ();
      else if (op->value.mem.base_reg.side != side)
	return tic6x_match_bad_mem;
      else
	return tic6x_match_matches;

    case tic6x_operand_mem_short:
    case tic6x_operand_mem_ndw:
      if (op->value.mem.base_reg.side != side)
	return tic6x_match_bad_mem;
      if (op->value.mem.mod == tic6x_mem_mod_none)
	{
	  if (op->value.mem.scaled != tic6x_offset_none)
	    abort ();
	  return tic6x_match_matches;
	}
      if (op->value.mem.scaled == tic6x_offset_none)
	{
	  if (op->value.mem.mod == tic6x_mem_mod_plus
	      || op->value.mem.mod == tic6x_mem_mod_minus)
	    abort ();
	  return tic6x_match_matches;
	}
      if (op->value.mem.offset_is_reg)
	{
	  if (op->value.mem.scaled == tic6x_offset_unscaled
	      && form != tic6x_operand_mem_ndw)
	    abort ();
	  if (op->value.mem.offset.reg.side == side)
	    return tic6x_match_matches;
	  else
	    return tic6x_match_bad_mem;
	}
      else
	{
	  if (op->value.mem.offset.exp.X_op == O_constant)
	    return tic6x_match_matches;
	  else
	    return tic6x_match_bad_mem;
	}

    case tic6x_operand_mem_long:
      if (op->value.mem.base_reg.side == 2
	  && (op->value.mem.base_reg.num == 14
	      || op->value.mem.base_reg.num == 15))
	{
	  switch (op->value.mem.mod)
	    {
	    case tic6x_mem_mod_none:
	      if (op->value.mem.scaled != tic6x_offset_none)
		abort ();
	      return tic6x_match_matches;

	    case tic6x_mem_mod_plus:
	      if (op->value.mem.scaled == tic6x_offset_none)
		abort ();
	      if (op->value.mem.offset_is_reg)
		return tic6x_match_bad_mem;
	      else if (op->value.mem.scaled == tic6x_offset_scaled
		       && op->value.mem.offset.exp.X_op != O_constant)
		return tic6x_match_bad_mem;
	      else
		return tic6x_match_matches;

	    case tic6x_mem_mod_minus:
	    case tic6x_mem_mod_preinc:
	    case tic6x_mem_mod_predec:
	    case tic6x_mem_mod_postinc:
	    case tic6x_mem_mod_postdec:
	      return tic6x_match_bad_mem;

	    default:
	      abort ();
	    }

	}
      else
	return tic6x_match_bad_mem;

    default:
      abort ();
    }
}

/* Return the number of bits shift used with DP-relative coding method
   CODING.  */

static unsigned int
tic6x_dpr_shift (tic6x_coding_method coding)
{
  switch (coding)
    {
    case tic6x_coding_ulcst_dpr_byte:
      return 0;

    case tic6x_coding_ulcst_dpr_half:
      return 1;

    case tic6x_coding_ulcst_dpr_word:
      return 2;

    default:
      abort ();
    }
}

/* Return the relocation used with DP-relative coding method
   CODING.  */

static bfd_reloc_code_real_type
tic6x_dpr_reloc (tic6x_coding_method coding)
{
  switch (coding)
    {
    case tic6x_coding_ulcst_dpr_byte:
      return BFD_RELOC_C6000_SBR_U15_B;

    case tic6x_coding_ulcst_dpr_half:
      return BFD_RELOC_C6000_SBR_U15_H;

    case tic6x_coding_ulcst_dpr_word:
      return BFD_RELOC_C6000_SBR_U15_W;

    default:
      abort ();
    }
}

/* Given a memory reference *MEM_REF as originally parsed, fill in
   defaults for missing offsets.  */

static void
tic6x_default_mem_ref (tic6x_mem_ref *mem_ref)
{
  switch (mem_ref->mod)
    {
    case tic6x_mem_mod_none:
      if (mem_ref->scaled != tic6x_offset_none)
	abort ();
      mem_ref->mod = tic6x_mem_mod_plus;
      mem_ref->scaled = tic6x_offset_unscaled;
      mem_ref->offset_is_reg = FALSE;
      memset (&mem_ref->offset.exp, 0, sizeof mem_ref->offset.exp);
      mem_ref->offset.exp.X_op = O_constant;
      mem_ref->offset.exp.X_add_number = 0;
      mem_ref->offset.exp.X_unsigned = 0;
      break;

    case tic6x_mem_mod_plus:
    case tic6x_mem_mod_minus:
      if (mem_ref->scaled == tic6x_offset_none)
	abort ();
      break;

    case tic6x_mem_mod_preinc:
    case tic6x_mem_mod_predec:
    case tic6x_mem_mod_postinc:
    case tic6x_mem_mod_postdec:
      if (mem_ref->scaled != tic6x_offset_none)
	break;
      mem_ref->scaled = tic6x_offset_scaled;
      mem_ref->offset_is_reg = FALSE;
      memset (&mem_ref->offset.exp, 0, sizeof mem_ref->offset.exp);
      mem_ref->offset.exp.X_op = O_constant;
      mem_ref->offset.exp.X_add_number = 1;
      mem_ref->offset.exp.X_unsigned = 0;
      break;

    default:
      abort ();
    }
}

/* Return the encoding in the 8-bit field of an SPMASK or SPMASKR
   instruction of the specified UNIT, side SIDE.  */

static unsigned int
tic6x_encode_spmask (tic6x_func_unit_base unit, unsigned int side)
{
  switch (unit)
    {
    case tic6x_func_unit_l:
      return 1 << (side - 1);

    case tic6x_func_unit_s:
      return 1 << (side + 1);

    case tic6x_func_unit_d:
      return 1 << (side + 3);

    case tic6x_func_unit_m:
      return 1 << (side + 5);

    default:
      abort ();
    }
}

/* Try to encode the instruction with opcode number ID and operands
   OPERANDS (number NUM_OPERANDS), creg value THIS_LINE_CREG and z
   value THIS_LINE_Z; FUNC_UNIT_SIDE, FUNC_UNIT_CROSS and
   FUNC_UNIT_DATA_SIDE describe the functional unit specification;
   SPLOOP_II is the ii value from the previous SPLOOP-family
   instruction, or 0 if not in such a loop; the only possible problems
   are operands being out of range (they already match the
   fine-grained form), and inappropriate predication.  If this
   succeeds, return the encoding and set *OK to TRUE; otherwise return
   0 and set *OK to FALSE.  If a fix is needed, set *FIX_NEEDED to
   true and fill in *FIX_EXP, *FIX_PCREL, *FX_R_TYPE and *FIX_ADDA.
   Print error messages for failure if PRINT_ERRORS is TRUE; the
   opcode starts at STR and has length OPC_LEN.  */

static unsigned int
tic6x_try_encode (tic6x_opcode_id id, tic6x_operand *operands,
		  unsigned int num_operands, unsigned int this_line_creg,
		  unsigned int this_line_z, unsigned int func_unit_side,
		  unsigned int func_unit_cross,
		  unsigned int func_unit_data_side, int sploop_ii,
		  expressionS **fix_exp, int *fix_pcrel,
		  bfd_reloc_code_real_type *fx_r_type, bfd_boolean *fix_adda,
		  bfd_boolean *fix_needed, bfd_boolean *ok,
		  bfd_boolean print_errors, char *str, int opc_len)
{
  const tic6x_opcode *opct;
  const tic6x_insn_format *fmt;
  unsigned int opcode_value;
  unsigned int fld;

  opct = &tic6x_opcode_table[id];
  fmt = &tic6x_insn_format_table[opct->format];
  opcode_value = fmt->cst_bits;

  for (fld = 0; fld < opct->num_fixed_fields; fld++)
    {
      if (opct->fixed_fields[fld].min_val == opct->fixed_fields[fld].max_val)
	{
	  const tic6x_insn_field *fldd;
	  fldd = tic6x_field_from_fmt (fmt, opct->fixed_fields[fld].field_id);
	  if (fldd == NULL)
	    abort ();
	  opcode_value |= opct->fixed_fields[fld].min_val << fldd->bitfields[0].low_pos;
	}
    }

  for (fld = 0; fld < opct->num_variable_fields; fld++)
    {
      const tic6x_insn_field *fldd;
      unsigned int value;
      unsigned int opno;
      unsigned int ffld;
      offsetT sign_value;
      unsigned int bits;
      unsigned int fcyc_bits;
      expressionS *expp;
      expressionS ucexp;
      tic6x_mem_ref mem;

      fldd = tic6x_field_from_fmt (fmt, opct->variable_fields[fld].field_id);
      if (fldd == NULL)
	abort ();
      opno = opct->variable_fields[fld].operand_num;
      switch (opct->variable_fields[fld].coding_method)
	{
	case tic6x_coding_ucst:
	  if (operands[opno].form != TIC6X_OP_EXP)
	    abort ();
	  if (operands[opno].value.exp.X_op != O_constant)
	    abort ();
	  ucexp = operands[opno].value.exp;
	unsigned_constant:
	  if (ucexp.X_add_number < 0
	      || ucexp.X_add_number >= (1 << fldd->bitfields[0].width))
	    {
	      if (print_errors)
		as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
			opc_len, str);
	      *ok = FALSE;
	      return 0;
	    }
	  value = ucexp.X_add_number;
	  break;

	case tic6x_coding_scst:
	  if (operands[opno].form != TIC6X_OP_EXP)
	    abort ();
	  if (operands[opno].value.exp.X_op != O_constant)
	    {
	      value = 0;
	      /* Opcode table should not permit non-constants without
		 a known relocation for them.  */
	      if (fldd->bitfields[0].low_pos != 7 || fldd->bitfields[0].width != 16)
		abort ();
	      *fix_needed = TRUE;
	      *fix_exp = &operands[opno].value.exp;
	      *fix_pcrel = 0;
	      *fx_r_type = BFD_RELOC_C6000_ABS_S16;
	      *fix_adda = FALSE;
	      break;
	    }
	  sign_value = SEXT (operands[opno].value.exp.X_add_number);
	signed_constant:
	  if (sign_value < -(1 << (fldd->bitfields[0].width - 1))
	      || (sign_value >= (1 << (fldd->bitfields[0].width - 1))))
	    {
	      if (print_errors)
		as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
			opc_len, str);
	      *ok = FALSE;
	      return 0;
	    }
	  value = sign_value + (1 << (fldd->bitfields[0].width - 1));
	  value ^= (1 << (fldd->bitfields[0].width - 1));
	  break;

	case tic6x_coding_ucst_minus_one:
	  if (operands[opno].form != TIC6X_OP_EXP)
	    abort ();
	  if (operands[opno].value.exp.X_op != O_constant)
	    abort ();
	  if (operands[opno].value.exp.X_add_number <= 0
	      || operands[opno].value.exp.X_add_number > (1 << fldd->bitfields[0].width))
	    {
	      if (print_errors)
		as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
			opc_len, str);
	      *ok = FALSE;
	      return 0;
	    }
	  value = operands[opno].value.exp.X_add_number - 1;
	  break;

	case tic6x_coding_scst_negate:
	  if (operands[opno].form != TIC6X_OP_EXP)
	    abort ();
	  if (operands[opno].value.exp.X_op != O_constant)
	    abort ();
	  sign_value = SEXT (-operands[opno].value.exp.X_add_number);
	  goto signed_constant;

	case tic6x_coding_ulcst_dpr_byte:
	case tic6x_coding_ulcst_dpr_half:
	case tic6x_coding_ulcst_dpr_word:
	  bits = tic6x_dpr_shift (opct->variable_fields[fld].coding_method);
	  switch (operands[opno].form)
	    {
	    case TIC6X_OP_EXP:
	      if (operands[opno].value.exp.X_op == O_constant)
		{
		  ucexp = operands[opno].value.exp;
		  goto unsigned_constant;
		}
	      expp = &operands[opno].value.exp;
	      break;

	    case TIC6X_OP_MEM_NOUNREG:
	      mem = operands[opno].value.mem;
	      tic6x_default_mem_ref (&mem);
	      if (mem.offset_is_reg)
		abort ();
	      if (mem.offset.exp.X_op == O_constant)
		{
		  ucexp = mem.offset.exp;
		  if (mem.scaled == tic6x_offset_unscaled)
		    {
		      if (ucexp.X_add_number & ((1 << bits) - 1))
			{
			  if (print_errors)
			    as_bad (_("offset in operand %u of '%.*s' not "
				      "divisible by %u"), opno + 1, opc_len,
				    str, 1u << bits);
			  *ok = FALSE;
			  return 0;
			}
		      ucexp.X_add_number >>= bits;
		    }
		  goto unsigned_constant;
		}
	      if (mem.scaled != tic6x_offset_unscaled)
		abort ();
	      if (operands[opno].value.mem.mod == tic6x_mem_mod_none
		  || operands[opno].value.mem.scaled != tic6x_offset_unscaled
		  || operands[opno].value.mem.offset_is_reg)
		abort ();
	      expp = &operands[opno].value.mem.offset.exp;
	      break;

	    default:
	      abort ();
	    }
	  value = 0;
	  /* Opcode table should not use this encoding without a known
	     relocation.  */
	  if (fldd->bitfields[0].low_pos != 8 || fldd->bitfields[0].width != 15)
	    abort ();
	  /* We do not check for offset divisibility here; such a
	     check is not needed at this point to encode the value,
	     and if there is eventually a problem it will be detected
	     either in md_apply_fix or at link time.  */
	  *fix_needed = TRUE;
	  *fix_exp = expp;
	  *fix_pcrel = 0;
	  *fx_r_type
	    = tic6x_dpr_reloc (opct->variable_fields[fld].coding_method);
	  if (operands[opno].form == TIC6X_OP_EXP)
	    *fix_adda = TRUE;
	  else
	    *fix_adda = FALSE;
	  break;

	case tic6x_coding_lcst_low16:
	  if (operands[opno].form != TIC6X_OP_EXP)
	    abort ();
	  if (operands[opno].value.exp.X_op == O_constant)
	    value = operands[opno].value.exp.X_add_number & 0xffff;
	  else
	    {
	      value = 0;
	      /* Opcode table should not use this encoding without a
		 known relocation.  */
	      if (fldd->bitfields[0].low_pos != 7 || fldd->bitfields[0].width != 16)
		abort ();
	      *fix_needed = TRUE;
	      *fix_exp = &operands[opno].value.exp;
	      *fix_pcrel = 0;
	      *fx_r_type = BFD_RELOC_C6000_ABS_L16;
	      *fix_adda = FALSE;
	    }
	  break;

	case tic6x_coding_lcst_high16:
	  if (operands[opno].form != TIC6X_OP_EXP)
	    abort ();
	  if (operands[opno].value.exp.X_op == O_constant)
	    value = (operands[opno].value.exp.X_add_number >> 16) & 0xffff;
	  else
	    {
	      value = 0;
	      /* Opcode table should not use this encoding without a
		 known relocation.  */
	      if (fldd->bitfields[0].low_pos != 7 || fldd->bitfields[0].width != 16)
		abort ();
	      *fix_needed = TRUE;
	      *fix_exp = &operands[opno].value.exp;
	      *fix_pcrel = 0;
	      *fx_r_type = BFD_RELOC_C6000_ABS_H16;
	      *fix_adda = FALSE;
	    }
	  break;

	case tic6x_coding_pcrel:
	case tic6x_coding_pcrel_half:
	  if (operands[opno].form != TIC6X_OP_EXP)
	    abort ();
	  value = 0;
	  *fix_needed = TRUE;
	  *fix_exp = &operands[opno].value.exp;
	  *fix_pcrel = 1;
	  if (fldd->bitfields[0].low_pos == 7 && fldd->bitfields[0].width == 21)
	    *fx_r_type = BFD_RELOC_C6000_PCR_S21;
	  else if (fldd->bitfields[0].low_pos == 16 && fldd->bitfields[0].width == 12)
	    *fx_r_type = BFD_RELOC_C6000_PCR_S12;
	  else if (fldd->bitfields[0].low_pos == 13 && fldd->bitfields[0].width == 10)
	    *fx_r_type = BFD_RELOC_C6000_PCR_S10;
	  else if (fldd->bitfields[0].low_pos == 16 && fldd->bitfields[0].width == 7)
	    *fx_r_type = BFD_RELOC_C6000_PCR_S7;
	  else
	    /* Opcode table should not use this encoding without a
	       known relocation.  */
	    abort ();
	  *fix_adda = FALSE;
	  break;

	case tic6x_coding_regpair_lsb:
	  switch (operands[opno].form)
	    {
	    case TIC6X_OP_REGPAIR:
	      value = operands[opno].value.reg.num;
	      break;

	    default:
	      abort ();
	    }
	  break;

	case tic6x_coding_regpair_msb:
	  switch (operands[opno].form)
	    {
	    case TIC6X_OP_REGPAIR:
	      value = operands[opno].value.reg.num + 1;
	      break;

	    default:
	      abort ();
	    }
	  break;

	case tic6x_coding_reg:
	  switch (operands[opno].form)
	    {
	    case TIC6X_OP_REG:
	    case TIC6X_OP_REGPAIR:
	      value = operands[opno].value.reg.num;
	      break;

	    case TIC6X_OP_MEM_NOUNREG:
	    case TIC6X_OP_MEM_UNREG:
	      value = operands[opno].value.mem.base_reg.num;
	      break;

	    default:
	      abort ();
	    }
	  break;

	case tic6x_coding_areg:
	  switch (operands[opno].form)
	    {
	    case TIC6X_OP_REG:
	      value = (operands[opno].value.reg.num == 15 ? 1 : 0);
	      break;

	    case TIC6X_OP_MEM_NOUNREG:
	      value = (operands[opno].value.mem.base_reg.num == 15 ? 1 : 0);
	      break;

	    default:
	      abort ();
	    }
	  break;

	case tic6x_coding_crlo:
	  if (operands[opno].form != TIC6X_OP_CTRL)
	    abort ();
	  value = tic6x_ctrl_table[operands[opno].value.ctrl].crlo;
	  break;

	case tic6x_coding_crhi:
	  if (operands[opno].form != TIC6X_OP_CTRL)
	    abort ();
	  value = 0;
	  break;

	case tic6x_coding_reg_shift:
	  if (operands[opno].form != TIC6X_OP_REGPAIR)
	    abort ();
	  value = operands[opno].value.reg.num >> 1;
	  break;

	case tic6x_coding_mem_offset:
	  if (operands[opno].form != TIC6X_OP_MEM_NOUNREG)
	    abort ();
	  mem = operands[opno].value.mem;
	  tic6x_default_mem_ref (&mem);
	  if (mem.offset_is_reg)
	    {
	      if (mem.scaled != tic6x_offset_scaled)
		abort ();
	      value = mem.offset.reg.num;
	    }
	  else
	    {
	      int scale;

	      if (mem.offset.exp.X_op != O_constant)
		abort ();
	      switch (mem.scaled)
		{
		case tic6x_offset_scaled:
		  scale = 1;
		  break;

		case tic6x_offset_unscaled:
		  scale = opct->operand_info[opno].size;
		  if (scale != 1 && scale != 2 && scale != 4 && scale != 8)
		    abort ();
		  break;

		default:
		  abort ();
		}
	      if (mem.offset.exp.X_add_number < 0
		  || mem.offset.exp.X_add_number >= (1 << fldd->bitfields[0].width) * scale)
		{
		  if (print_errors)
		    as_bad (_("offset in operand %u of '%.*s' out of range"),
			    opno + 1, opc_len, str);
		  *ok = FALSE;
		  return 0;
		}
	      if (mem.offset.exp.X_add_number % scale)
		{
		  if (print_errors)
		    as_bad (_("offset in operand %u of '%.*s' not "
			      "divisible by %u"),
			    opno + 1, opc_len, str, scale);
		  *ok = FALSE;
		  return 0;
		}
	      value = mem.offset.exp.X_add_number / scale;
	    }
	  break;

	case tic6x_coding_mem_offset_noscale:
	  if (operands[opno].form != TIC6X_OP_MEM_UNREG)
	    abort ();
	  mem = operands[opno].value.mem;
	  tic6x_default_mem_ref (&mem);
	  if (mem.offset_is_reg)
	    value = mem.offset.reg.num;
	  else
	    {
	      if (mem.offset.exp.X_op != O_constant)
		abort ();
	      if (mem.offset.exp.X_add_number < 0
		  || mem.offset.exp.X_add_number >= (1 << fldd->bitfields[0].width))
		{
		  if (print_errors)
		    as_bad (_("offset in operand %u of '%.*s' out of range"),
			    opno + 1, opc_len, str);
		  *ok = FALSE;
		  return 0;
		}
	      value = mem.offset.exp.X_add_number;
	    }
	  break;

	case tic6x_coding_mem_mode:
	  if (operands[opno].form != TIC6X_OP_MEM_NOUNREG
	      && operands[opno].form != TIC6X_OP_MEM_UNREG)
	    abort ();
	  mem = operands[opno].value.mem;
	  tic6x_default_mem_ref (&mem);
	  switch (mem.mod)
	    {
	    case tic6x_mem_mod_plus:
	      value = 1;
	      break;

	    case tic6x_mem_mod_minus:
	      value = 0;
	      break;

	    case tic6x_mem_mod_preinc:
	      value = 9;
	      break;

	    case tic6x_mem_mod_predec:
	      value = 8;
	      break;

	    case tic6x_mem_mod_postinc:
	      value = 11;
	      break;

	    case tic6x_mem_mod_postdec:
	      value = 10;
	      break;

	    default:
	      abort ();
	    }
	  value += (mem.offset_is_reg ? 4 : 0);
	  break;

	case tic6x_coding_scaled:
	  if (operands[opno].form != TIC6X_OP_MEM_UNREG)
	    abort ();
	  mem = operands[opno].value.mem;
	  tic6x_default_mem_ref (&mem);
	  switch (mem.scaled)
	    {
	    case tic6x_offset_unscaled:
	      value = 0;
	      break;

	    case tic6x_offset_scaled:
	      value = 1;
	      break;

	    default:
	      abort ();
	    }
	  break;

	case tic6x_coding_spmask:
	  /* The position of such a field is hardcoded in the handling
	     of "||^".  */
	  if (fldd->bitfields[0].low_pos != 18)
	    abort ();
	  value = 0;
	  for (opno = 0; opno < num_operands; opno++)
	    {
	      unsigned int v;

	      v = tic6x_encode_spmask (operands[opno].value.func_unit.base,
				       operands[opno].value.func_unit.side);
	      if (value & v)
		{
		  if (print_errors)
		    as_bad (_("functional unit already masked for operand "
			      "%u of '%.*s'"), opno + 1, opc_len, str);
		  *ok = FALSE;
		  return 0;
		}
	      value |= v;
	    }
	  break;

	case tic6x_coding_reg_unused:
	  /* This is a placeholder; correct handling goes along with
	     resource constraint checks.  */
	  value = 0;
	  break;

	case tic6x_coding_fstg:
	case tic6x_coding_fcyc:
	  if (operands[opno].form != TIC6X_OP_EXP)
	    abort ();
	  if (operands[opno].value.exp.X_op != O_constant)
	    abort ();
	  if (!sploop_ii)
	    {
	      if (print_errors)
		as_bad (_("'%.*s' instruction not in a software "
			  "pipelined loop"),
			opc_len, str);
	      *ok = FALSE;
	      return 0;
	    }

	  if (sploop_ii <= 1)
	    fcyc_bits = 0;
	  else if (sploop_ii <= 2)
	    fcyc_bits = 1;
	  else if (sploop_ii <= 4)
	    fcyc_bits = 2;
	  else if (sploop_ii <= 8)
	    fcyc_bits = 3;
	  else if (sploop_ii <= 14)
	    fcyc_bits = 4;
	  else
	    abort ();
	  if (fcyc_bits > fldd->bitfields[0].width)
	    abort ();

	  if (opct->variable_fields[fld].coding_method == tic6x_coding_fstg)
	    {
	      int i, t;
	      if (operands[opno].value.exp.X_add_number < 0
		  || (operands[opno].value.exp.X_add_number
		      >= (1 << (fldd->bitfields[0].width - fcyc_bits))))
		{
		  if (print_errors)
		    as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
			    opc_len, str);
		  *ok = FALSE;
		  return 0;
		}
	      value = operands[opno].value.exp.X_add_number;
	      for (t = 0, i = fcyc_bits; i < fldd->bitfields[0].width; i++)
		{
		  t = (t << 1) | (value & 1);
		  value >>= 1;
		}
	      value = t << fcyc_bits;
	    }
	  else
	    {
	      if (operands[opno].value.exp.X_add_number < 0
		  || (operands[opno].value.exp.X_add_number >= sploop_ii))
		{
		  if (print_errors)
		    as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
			    opc_len, str);
		  *ok = FALSE;
		  return 0;
		}
	      value = operands[opno].value.exp.X_add_number;
	    }
	  break;

	case tic6x_coding_fu:
	  value = func_unit_side == 2 ? 1 : 0;
	  break;

	case tic6x_coding_data_fu:
	  value = func_unit_data_side == 2 ? 1 : 0;
	  break;

	case tic6x_coding_xpath:
	  value = func_unit_cross;
	  break;

	default:
	  abort ();
	}

      for (ffld = 0; ffld < opct->num_fixed_fields; ffld++)
	if ((opct->fixed_fields[ffld].field_id
	     == opct->variable_fields[fld].field_id)
	    && (value < opct->fixed_fields[ffld].min_val
		|| value > opct->fixed_fields[ffld].max_val))
	  {
	    if (print_errors)
	      as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
		      opc_len, str);
	    *ok = FALSE;
	    return 0;
	  }

      opcode_value |= value << fldd->bitfields[0].low_pos;
    }

  if (this_line_creg)
    {
      const tic6x_insn_field *creg;
      const tic6x_insn_field *z;

      creg = tic6x_field_from_fmt (fmt, tic6x_field_creg);
      if (creg == NULL)
	{
	  if (print_errors)
	    as_bad (_("instruction '%.*s' cannot be predicated"),
		    opc_len, str);
	  *ok = FALSE;
	  return 0;
	}
      z = tic6x_field_from_fmt (fmt, tic6x_field_z);
      /* If there is a creg field, there must be a z field; otherwise
	 there is an error in the format table.  */
      if (z == NULL)
	abort ();

      opcode_value |= this_line_creg << creg->bitfields[0].low_pos;
      opcode_value |= this_line_z << z->bitfields[0].low_pos;
    }

  *ok = TRUE;
  return opcode_value;
}

/* Convert the target integer stored in N bytes in BUF to a host
   integer, returning that value.  */

static valueT
md_chars_to_number (char *buf, int n)
{
  valueT result = 0;
  unsigned char *p = (unsigned char *) buf;

  if (target_big_endian)
    {
      while (n--)
	{
	  result <<= 8;
	  result |= (*p++ & 0xff);
	}
    }
  else
    {
      while (n--)
	{
	  result <<= 8;
	  result |= (p[n] & 0xff);
	}
    }

  return result;
}

/* Assemble the instruction starting at STR (an opcode, with the
   opcode name all-lowercase).  */

void
md_assemble (char *str)
{
  char *p;
  int opc_len;
  bfd_boolean this_line_parallel;
  bfd_boolean this_line_spmask;
  unsigned int this_line_creg;
  unsigned int this_line_z;
  tic6x_label_list *this_insn_label_list;
  segment_info_type *seginfo;
  tic6x_opcode_list *opc_list, *opc;
  tic6x_func_unit_base func_unit_base = tic6x_func_unit_nfu;
  unsigned int func_unit_side = 0;
  unsigned int func_unit_cross = 0;
  unsigned int cross_side = 0;
  unsigned int func_unit_data_side = 0;
  unsigned int max_matching_opcodes, num_matching_opcodes;
  tic6x_opcode_id *opcm = NULL;
  unsigned int opc_rank[TIC6X_NUM_PREFER];
  const tic6x_opcode *opct = NULL;
  int min_rank, try_rank, max_rank;
  bfd_boolean num_operands_permitted[TIC6X_MAX_SOURCE_OPERANDS + 1]
    = { FALSE };
  unsigned int operand_forms[TIC6X_MAX_SOURCE_OPERANDS] = { 0 };
  tic6x_operand operands[TIC6X_MAX_SOURCE_OPERANDS];
  unsigned int max_num_operands;
  unsigned int num_operands_read;
  bfd_boolean ok_this_arch, ok_this_fu, ok_this_arch_fu;
  bfd_boolean bad_operands = FALSE;
  unsigned int opcode_value;
  bfd_boolean encoded_ok;
  bfd_boolean fix_needed = FALSE;
  expressionS *fix_exp = NULL;
  int fix_pcrel = 0;
  bfd_reloc_code_real_type fx_r_type = BFD_RELOC_UNUSED;
  bfd_boolean fix_adda = FALSE;
  fragS *insn_frag;
  char *output;

  p = str;
  while (*p && !is_end_of_line[(unsigned char) *p] && *p != ' ')
    p++;

  /* This function should only have been called when there is actually
     an instruction to assemble.  */
  if (p == str)
    abort ();

  /* Now an instruction has been seen, architecture attributes from
     .arch directives merge with rather than overriding the previous
     value.  */
  tic6x_seen_insns = TRUE;
  /* If no .arch directives or -march options have been seen, we are
     assessing instruction validity based on the C674X default, so set
     the attribute accordingly.  */
  if (tic6x_arch_attribute == C6XABI_Tag_ISA_none)
    tic6x_arch_attribute = C6XABI_Tag_ISA_C674X;

  /* Reset global settings for parallel bars and predicates now to
     avoid extra errors if there are problems with this opcode.  */
  this_line_parallel = tic6x_line_parallel;
  this_line_spmask = tic6x_line_spmask;
  this_line_creg = tic6x_line_creg;
  this_line_z = tic6x_line_z;
  tic6x_line_parallel = FALSE;
  tic6x_line_spmask = FALSE;
  tic6x_line_creg = 0;
  tic6x_line_z = 0;
  seginfo = seg_info (now_seg);
  this_insn_label_list = seginfo->tc_segment_info_data.label_list;
  seginfo->tc_segment_info_data.label_list = NULL;

  opc_list = str_hash_find_n (opcode_hash, str, p - str);
  if (opc_list == NULL)
    {
      char c = *p;
      *p = 0;
      as_bad (_("unknown opcode '%s'"), str);
      *p = c;
      return;
    }

  opc_len = p - str;
  skip_whitespace (p);

  /* See if there is something that looks like a functional unit
     specifier.  */
  if (*p == '.')
    {
      bfd_boolean good_func_unit;
      tic6x_func_unit_base maybe_base = tic6x_func_unit_nfu;
      unsigned int maybe_side = 0;
      unsigned int maybe_cross = 0;
      unsigned int maybe_data_side = 0;

      good_func_unit = tic6x_parse_func_unit_base (p + 1, &maybe_base,
						   &maybe_side);

      if (good_func_unit)
	{
	  if (p[3] == ' ' || is_end_of_line[(unsigned char) p[3]])
	    p += 3;
	  else if ((p[3] == 'x' || p[3] == 'X')
		   && (p[4] == ' ' || is_end_of_line[(unsigned char) p[4]]))
	    {
	      maybe_cross = 1;
	      p += 4;
	    }
	  else if (maybe_base == tic6x_func_unit_d
		   && (p[3] == 't' || p[3] == 'T')
		   && (p[4] == '1' || p[4] == '2')
		   && (p[5] == ' ' || is_end_of_line[(unsigned char) p[5]]))
	    {
	      maybe_data_side = p[4] - '0';
	      p += 5;
	    }
	  else
	    good_func_unit = FALSE;
	}

      if (good_func_unit)
	{
	  func_unit_base = maybe_base;
	  func_unit_side = maybe_side;
	  func_unit_cross = maybe_cross;
	  cross_side = (func_unit_cross ? 3 - func_unit_side : func_unit_side);
	  func_unit_data_side = maybe_data_side;
	}

      skip_whitespace (p);
    }

  /* Determine which entries in the opcode table match, and the
     associated permitted forms of operands.  */
  max_matching_opcodes = 0;
  for (opc = opc_list; opc; opc = opc->next)
    max_matching_opcodes++;
  num_matching_opcodes = 0;
  opcm = XNEWVEC (tic6x_opcode_id, max_matching_opcodes);
  max_num_operands = 0;
  ok_this_arch = FALSE;
  ok_this_fu = FALSE;
  ok_this_arch_fu = FALSE;
  for (opc = opc_list; opc; opc = opc->next)
    {
      unsigned int num_operands;
      unsigned int i;
      bfd_boolean this_opc_arch_ok = TRUE;
      bfd_boolean this_opc_fu_ok = TRUE;

      if (tic6x_insn_format_table[tic6x_opcode_table[opc->id].format].num_bits
	  != 32)
	continue;
      if (!(tic6x_opcode_table[opc->id].isa_variants & tic6x_features))
	this_opc_arch_ok = FALSE;
      if (tic6x_opcode_table[opc->id].func_unit != func_unit_base)
	this_opc_fu_ok = FALSE;
      if (func_unit_side == 1
	  && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SIDE_B_ONLY))
	this_opc_fu_ok = FALSE;
      if (func_unit_cross
	  && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_NO_CROSS))
	this_opc_fu_ok = FALSE;
      if (!func_unit_data_side
	  && (tic6x_opcode_table[opc->id].flags
	      & (TIC6X_FLAG_LOAD | TIC6X_FLAG_STORE)))
	this_opc_fu_ok = FALSE;
      if (func_unit_data_side
	  && !(tic6x_opcode_table[opc->id].flags
	       & (TIC6X_FLAG_LOAD | TIC6X_FLAG_STORE)))
	this_opc_fu_ok = FALSE;
      if (func_unit_data_side == 1
	  && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SIDE_T2_ONLY))
	this_opc_fu_ok = FALSE;
      if (this_opc_arch_ok)
	ok_this_arch = TRUE;
      if (this_opc_fu_ok)
	ok_this_fu = TRUE;
      if (!this_opc_arch_ok || !this_opc_fu_ok)
	continue;
      ok_this_arch_fu = TRUE;
      opcm[num_matching_opcodes] = opc->id;
      num_matching_opcodes++;
      num_operands = tic6x_opcode_table[opc->id].num_operands;

      if (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SPMASK)
	{
	  if (num_operands != 1
	      || (tic6x_opcode_table[opc->id].operand_info[0].form
		  != tic6x_operand_func_unit))
	    abort ();
	  num_operands = 8;
	  for (i = 0; i < num_operands; i++)
	    {
	      operand_forms[i]
		|= tic6x_coarse_operand_form (tic6x_operand_func_unit);
	      num_operands_permitted[i] = TRUE;
	    }
	}
      else
	{
	  for (i = 0; i < num_operands; i++)
	    {
	      tic6x_operand_form f
		= tic6x_opcode_table[opc->id].operand_info[i].form;

	      operand_forms[i] |= tic6x_coarse_operand_form (f);
	    }
	}
      num_operands_permitted[num_operands] = TRUE;
      if (num_operands > max_num_operands)
	max_num_operands = num_operands;
    }

  if (!ok_this_arch)
    {
      as_bad (_("'%.*s' instruction not supported on this architecture"),
	      opc_len, str);
      free (opcm);
      return;
    }

  if (!ok_this_fu)
    {
      as_bad (_("'%.*s' instruction not supported on this functional unit"),
	      opc_len, str);
      free (opcm);
      return;
    }

  if (!ok_this_arch_fu)
    {
      as_bad (_("'%.*s' instruction not supported on this functional unit"
		" for this architecture"),
	      opc_len, str);
      free (opcm);
      return;
    }

  /* If there were no instructions matching the above availability
     checks, we should now have given an error and returned.  */
  if (num_matching_opcodes == 0)
    abort ();

  num_operands_read = 0;
  while (TRUE)
    {
      skip_whitespace (p);
      if (is_end_of_line[(unsigned char) *p])
	{
	  if (num_operands_read > 0)
	    {
	      as_bad (_("missing operand after comma"));
	      bad_operands = TRUE;
	    }
	  break;
	}

      if (max_num_operands == 0)
	{
	  as_bad (_("too many operands to '%.*s'"), opc_len, str);
	  bad_operands = TRUE;
	  break;
	}

      if (!tic6x_parse_operand (&p, &operands[num_operands_read],
				operand_forms[num_operands_read], str, opc_len,
				num_operands_read + 1))
	bad_operands = TRUE;
      num_operands_read++;

      if (is_end_of_line[(unsigned char) *p])
	break;
      else if (*p == ',')
	{
	  p++;
	  if (num_operands_read == max_num_operands)
	    {
	      as_bad (_("too many operands to '%.*s'"), opc_len, str);
	      bad_operands = TRUE;
	      break;
	    }
	  continue;
	}
      else
	/* Operand parsing should consume whole operands.  */
	abort ();
    }

  if (!bad_operands && !num_operands_permitted[num_operands_read])
    {
      as_bad (_("bad number of operands to '%.*s'"), opc_len, str);
      bad_operands = TRUE;
    }

  if (!bad_operands)
    {
      /* Each operand is of the right syntactic form for some opcode
	 choice, and the number of operands is valid.  Check that each
	 operand is OK in detail for some opcode choice with the right
	 number of operands.  */
      unsigned int i;

      for (i = 0; i < num_operands_read; i++)
	{
	  bfd_boolean coarse_ok = FALSE;
	  bfd_boolean fine_ok = FALSE;
	  tic6x_operand_match fine_failure = tic6x_match_matches;
	  unsigned int j;

	  for (j = 0; j < num_matching_opcodes; j++)
	    {
	      tic6x_operand_form f;
	      tic6x_rw rw;
	      unsigned int cf;
	      tic6x_operand_match this_fine_failure;

	      if (tic6x_opcode_table[opcm[j]].flags & TIC6X_FLAG_SPMASK)
		{
		  f = tic6x_operand_func_unit;
		  rw = tic6x_rw_none;
		}
	      else
		{
		  if (tic6x_opcode_table[opcm[j]].num_operands
		      != num_operands_read)
		    continue;

		  f = tic6x_opcode_table[opcm[j]].operand_info[i].form;
		  rw = tic6x_opcode_table[opcm[j]].operand_info[i].rw;
		}
	      cf = tic6x_coarse_operand_form (f);

	      if (operands[i].form != cf)
		continue;

	      coarse_ok = TRUE;
	      this_fine_failure
		= tic6x_operand_matches_form (&operands[i], f, rw,
					      func_unit_side,
					      cross_side,
					      func_unit_data_side);
	      if (this_fine_failure == tic6x_match_matches)
		{
		  fine_ok = TRUE;
		  break;
		}
	      if (fine_failure == tic6x_match_matches
		  || fine_failure > this_fine_failure)
		fine_failure = this_fine_failure;
	    }

	  /* No instructions should have operand syntactic forms only
	     acceptable with certain numbers of operands, so no
	     diagnostic for this case.  */
	  if (!coarse_ok)
	    abort ();

	  if (!fine_ok)
	    {
	      switch (fine_failure)
		{
		case tic6x_match_non_const:
		  as_bad (_("operand %u of '%.*s' not constant"),
			  i + 1, opc_len, str);
		  break;

		case tic6x_match_wrong_side:
		  as_bad (_("operand %u of '%.*s' on wrong side"),
			  i + 1, opc_len, str);
		  break;

		case tic6x_match_bad_return:
		  as_bad (_("operand %u of '%.*s' not a valid return "
			    "address register"),
			  i + 1, opc_len, str);
		  break;

		case tic6x_match_ctrl_write_only:
		  as_bad (_("operand %u of '%.*s' is write-only"),
			  i + 1, opc_len, str);
		  break;

		case tic6x_match_ctrl_read_only:
		  as_bad (_("operand %u of '%.*s' is read-only"),
			  i + 1, opc_len, str);
		  break;

		case tic6x_match_bad_mem:
		  as_bad (_("operand %u of '%.*s' not a valid memory "
			    "reference"),
			  i + 1, opc_len, str);
		  break;

		case tic6x_match_bad_address:
		  as_bad (_("operand %u of '%.*s' not a valid base "
			    "address register"),
			  i + 1, opc_len, str);
		  break;

		default:
		  abort ();
		}
	      bad_operands = TRUE;
	      break;
	    }
	}
    }

  if (!bad_operands)
    {
      /* Each operand is OK for some opcode choice, and the number of
	 operands is valid.  Check whether there is an opcode choice
	 for which all operands are simultaneously valid.  */
      unsigned int i;
      bfd_boolean found_match = FALSE;

      for (i = 0; i < TIC6X_NUM_PREFER; i++)
	opc_rank[i] = (unsigned int) -1;

      min_rank = TIC6X_NUM_PREFER - 1;
      max_rank = 0;

      for (i = 0; i < num_matching_opcodes; i++)
	{
	  unsigned int j;
	  bfd_boolean this_matches = TRUE;

	  if (!(tic6x_opcode_table[opcm[i]].flags & TIC6X_FLAG_SPMASK)
	      && tic6x_opcode_table[opcm[i]].num_operands != num_operands_read)
	    continue;

	  for (j = 0; j < num_operands_read; j++)
	    {
	      tic6x_operand_form f;
	      tic6x_rw rw;

	      if (tic6x_opcode_table[opcm[i]].flags & TIC6X_FLAG_SPMASK)
		{
		  f = tic6x_operand_func_unit;
		  rw = tic6x_rw_none;
		}
	      else
		{
		  f = tic6x_opcode_table[opcm[i]].operand_info[j].form;
		  rw = tic6x_opcode_table[opcm[i]].operand_info[j].rw;
		}
	      if (tic6x_operand_matches_form (&operands[j], f, rw,
					      func_unit_side,
					      cross_side,
					      func_unit_data_side)
		  != tic6x_match_matches)
		{
		  this_matches = FALSE;
		  break;
		}
	    }

	  if (this_matches)
	    {
	      int rank = TIC6X_PREFER_VAL (tic6x_opcode_table[opcm[i]].flags);

	      if (rank < min_rank)
		min_rank = rank;
	      if (rank > max_rank)
		max_rank = rank;

	      if (opc_rank[rank] == (unsigned int) -1)
		opc_rank[rank] = i;
	      else
		/* The opcode table should provide a total ordering
		   for all cases where multiple matches may get
		   here.  */
		abort ();

	      found_match = TRUE;
	    }
	}

      if (!found_match)
	{
	  as_bad (_("bad operand combination for '%.*s'"), opc_len, str);
	  bad_operands = TRUE;
	}
    }

  if (bad_operands)
    {
      free (opcm);
      return;
    }

  opcode_value = 0;
  encoded_ok = FALSE;
  for (try_rank = max_rank; try_rank >= min_rank; try_rank--)
    {
      fix_needed = FALSE;

      if (opc_rank[try_rank] == (unsigned int) -1)
	continue;

      opcode_value = tic6x_try_encode (opcm[opc_rank[try_rank]], operands,
				       num_operands_read, this_line_creg,
				       this_line_z, func_unit_side,
				       func_unit_cross, func_unit_data_side,
				       seginfo->tc_segment_info_data.sploop_ii,
				       &fix_exp, &fix_pcrel, &fx_r_type,
				       &fix_adda, &fix_needed, &encoded_ok,
				       (try_rank == min_rank ? TRUE : FALSE),
				       str, opc_len);
      if (encoded_ok)
	{
	  opct = &tic6x_opcode_table[opcm[opc_rank[try_rank]]];
	  break;
	}
    }

  free (opcm);

  if (!encoded_ok)
    return;

  if (this_line_parallel)
    {
      insn_frag = seginfo->tc_segment_info_data.execute_packet_frag;
      if (insn_frag == NULL)
	{
	  as_bad (_("parallel instruction not following another instruction"));
	  return;
	}

      if (insn_frag->fr_fix >= 32)
	{
	  as_bad (_("too many instructions in execute packet"));
	  return;
	}

      if (this_insn_label_list != NULL)
	as_bad (_("label not at start of execute packet"));

      if (opct->flags & TIC6X_FLAG_FIRST)
	as_bad (_("'%.*s' instruction not at start of execute packet"),
		opc_len, str);

      *seginfo->tc_segment_info_data.last_insn_lsb |= 0x1;
      output = insn_frag->fr_literal + insn_frag->fr_fix;
    }
  else
    {
      tic6x_label_list *l;

      seginfo->tc_segment_info_data.spmask_addr = NULL;
      seginfo->tc_segment_info_data.func_units_used = 0;

      /* Start a new frag for this execute packet.  */
      if (frag_now_fix () != 0)
	{
	  if (frag_now->fr_type != rs_machine_dependent)
	    frag_wane (frag_now);

	  frag_new (0);
	}
      frag_grow (32);
      insn_frag = seginfo->tc_segment_info_data.execute_packet_frag = frag_now;
      for (l = this_insn_label_list; l; l = l->next)
	{
	  symbol_set_frag (l->label, frag_now);
	  S_SET_VALUE (l->label, 0);
	  S_SET_SEGMENT (l->label, now_seg);
	}
      tic6x_free_label_list (this_insn_label_list);
      dwarf2_emit_insn (0);
      output = frag_var (rs_machine_dependent, 32, 32, 0, NULL, 0, NULL);
      /* This must be the same as the frag to which a pointer was just
	 saved.  */
      if (output != insn_frag->fr_literal)
	abort ();
      insn_frag->tc_frag_data.is_insns = TRUE;
      insn_frag->tc_frag_data.can_cross_fp_boundary
	= tic6x_can_cross_fp_boundary;
    }

  if (func_unit_base != tic6x_func_unit_nfu)
    {
      unsigned int func_unit_enc;

      func_unit_enc = tic6x_encode_spmask (func_unit_base, func_unit_side);

      if (seginfo->tc_segment_info_data.func_units_used & func_unit_enc)
	as_bad (_("functional unit already used in this execute packet"));

      seginfo->tc_segment_info_data.func_units_used |= func_unit_enc;
    }

  if (opct->flags & TIC6X_FLAG_SPLOOP)
    {
      if (seginfo->tc_segment_info_data.sploop_ii)
	as_bad (_("nested software pipelined loop"));
      if (num_operands_read != 1
	  || operands[0].form != TIC6X_OP_EXP
	  || operands[0].value.exp.X_op != O_constant)
	abort ();
      seginfo->tc_segment_info_data.sploop_ii
	= operands[0].value.exp.X_add_number;
    }
  else if (opct->flags & TIC6X_FLAG_SPKERNEL)
    {
      if (!seginfo->tc_segment_info_data.sploop_ii)
	as_bad (_("'%.*s' instruction not in a software pipelined loop"),
		opc_len, str);
      seginfo->tc_segment_info_data.sploop_ii = 0;
    }

  if (this_line_spmask)
    {
      if (seginfo->tc_segment_info_data.spmask_addr == NULL)
	as_bad (_("'||^' without previous SPMASK"));
      else if (func_unit_base == tic6x_func_unit_nfu)
	as_bad (_("cannot mask instruction using no functional unit"));
      else
	{
	  unsigned int spmask_opcode;
	  unsigned int mask_bit;

	  spmask_opcode
	    = md_chars_to_number (seginfo->tc_segment_info_data.spmask_addr,
				  4);
	  mask_bit = tic6x_encode_spmask (func_unit_base, func_unit_side);
	  mask_bit <<= 18;
	  if (spmask_opcode & mask_bit)
	    as_bad (_("functional unit already masked"));
	  spmask_opcode |= mask_bit;
	  md_number_to_chars (seginfo->tc_segment_info_data.spmask_addr,
			      spmask_opcode, 4);
	}
    }

  record_alignment (now_seg, 5);
  md_number_to_chars (output, opcode_value, 4);
  if (fix_needed)
    tic6x_fix_new_exp (insn_frag, output - insn_frag->fr_literal, 4, fix_exp,
		       fix_pcrel, fx_r_type, fix_adda);
  insn_frag->fr_fix += 4;
  insn_frag->fr_var -= 4;
  seginfo->tc_segment_info_data.last_insn_lsb
    = (target_big_endian ? output + 3 : output);
  if (opct->flags & TIC6X_FLAG_SPMASK)
    seginfo->tc_segment_info_data.spmask_addr = output;
}

/* Modify NEWVAL (32-bit) by inserting VALUE, shifted right by SHIFT
   and the least significant BITS bits taken, at position POS.  */
#define MODIFY_VALUE(NEWVAL, VALUE, SHIFT, POS, BITS)			\
  do {									\
    (NEWVAL) &= 0xffffffffU & ~(((1U << (BITS)) - 1) << (POS));		\
    (NEWVAL) |= (((VALUE) >> (SHIFT)) & ((1U << (BITS)) - 1)) << (POS);	\
  } while (0)

/* Apply a fixup to the object file.  */

void
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
  valueT value = *valP;
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;

  value = SEXT (value);
  *valP = value;

  fixP->fx_offset = SEXT (fixP->fx_offset);

  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
    fixP->fx_done = 1;

  /* We do our own overflow checks.  */
  fixP->fx_no_overflow = 1;

  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_NONE:
    case BFD_RELOC_C6000_EHTYPE:
      /* Force output to the object file.  */
      fixP->fx_done = 0;
      break;

    case BFD_RELOC_32:
      if (fixP->fx_done || !seg->use_rela_p)
	md_number_to_chars (buf, value, 4);
      break;

    case BFD_RELOC_16:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  if (value + 0x8000 > 0xffff + 0x8000)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("value too large for 2-byte field"));
	  md_number_to_chars (buf, value, 2);
	}
      break;

    case BFD_RELOC_8:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  if (value + 0x80 > 0xff + 0x80)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("value too large for 1-byte field"));
	  *buf = value;
	}
      break;

    case BFD_RELOC_C6000_ABS_S16:
    case BFD_RELOC_C6000_ABS_L16:
    case BFD_RELOC_C6000_SBR_S16:
    case BFD_RELOC_C6000_SBR_L16_B:
    case BFD_RELOC_C6000_SBR_L16_H:
    case BFD_RELOC_C6000_SBR_L16_W:
    case BFD_RELOC_C6000_SBR_GOT_L16_W:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);
	  int shift;

	  switch (fixP->fx_r_type)
	    {
	    case BFD_RELOC_C6000_SBR_L16_H:
	      shift = 1;
	      break;

	    case BFD_RELOC_C6000_SBR_L16_W:
	    case BFD_RELOC_C6000_SBR_GOT_L16_W:
	      shift = 2;
	      break;

	    default:
	      shift = 0;
	      break;
	    }

	  MODIFY_VALUE (newval, value, shift, 7, 16);
	  if ((value + 0x8000 > 0x7fff + 0x8000)
	      && (fixP->fx_r_type == BFD_RELOC_C6000_ABS_S16
		  || fixP->fx_r_type == BFD_RELOC_C6000_SBR_S16))
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("immediate offset out of range"));

	  md_number_to_chars (buf, newval, 4);
	}
      if (fixP->fx_done
	  && fixP->fx_r_type != BFD_RELOC_C6000_ABS_S16
	  && fixP->fx_r_type != BFD_RELOC_C6000_ABS_L16)
	abort ();
      break;

    case BFD_RELOC_C6000_ABS_H16:
    case BFD_RELOC_C6000_SBR_H16_B:
    case BFD_RELOC_C6000_SBR_H16_H:
    case BFD_RELOC_C6000_SBR_H16_W:
    case BFD_RELOC_C6000_SBR_GOT_H16_W:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);
	  int shift;

	  switch (fixP->fx_r_type)
	    {
	    case BFD_RELOC_C6000_SBR_H16_H:
	      shift = 17;
	      break;

	    case BFD_RELOC_C6000_SBR_H16_W:
	    case BFD_RELOC_C6000_SBR_GOT_H16_W:
	      shift = 18;
	      break;

	    default:
	      shift = 16;
	      break;
	    }

	  MODIFY_VALUE (newval, value, shift, 7, 16);

	  md_number_to_chars (buf, newval, 4);
	}
      if (fixP->fx_done && fixP->fx_r_type != BFD_RELOC_C6000_ABS_H16)
	abort ();
      break;

    case BFD_RELOC_C6000_PCR_H16:
    case BFD_RELOC_C6000_PCR_L16:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);
	  int shift = fixP->fx_r_type == BFD_RELOC_C6000_PCR_H16 ? 16 : 0;

	  MODIFY_VALUE (newval, value, shift, 7, 16);

	  md_number_to_chars (buf, newval, 4);
	}
      break;

    case BFD_RELOC_C6000_SBR_U15_B:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);

	  MODIFY_VALUE (newval, value, 0, 8, 15);
	  if (value > 0x7fff)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("immediate offset out of range"));

	  md_number_to_chars (buf, newval, 4);
	}
      break;

    case BFD_RELOC_C6000_SBR_U15_H:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);

	  /* Constant ADDA operands, processed as constant when the
	     instruction is parsed, are encoded as-is rather than
	     shifted.  If the operand of an ADDA instruction is now
	     constant (for example, the difference between two labels
	     found after the instruction), ensure it is encoded the
	     same way it would have been if the constant value had
	     been known when the instruction was parsed.  */
	  if (fixP->tc_fix_data.fix_adda && fixP->fx_done)
	    value <<= 1;

	  MODIFY_VALUE (newval, value, 1, 8, 15);
	  if (value & 1)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("immediate offset not 2-byte-aligned"));
	  if (value > 0xfffe)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("immediate offset out of range"));

	  md_number_to_chars (buf, newval, 4);
	}
      break;

    case BFD_RELOC_C6000_SBR_U15_W:
    case BFD_RELOC_C6000_SBR_GOT_U15_W:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);

	  /* Constant ADDA operands, processed as constant when the
	     instruction is parsed, are encoded as-is rather than
	     shifted.  If the operand of an ADDA instruction is now
	     constant (for example, the difference between two labels
	     found after the instruction), ensure it is encoded the
	     same way it would have been if the constant value had
	     been known when the instruction was parsed.  */
	  if (fixP->tc_fix_data.fix_adda && fixP->fx_done)
	    value <<= 2;

	  MODIFY_VALUE (newval, value, 2, 8, 15);
	  if (value & 3)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("immediate offset not 4-byte-aligned"));
	  if (value > 0x1fffc)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("immediate offset out of range"));

	  md_number_to_chars (buf, newval, 4);
	}
      if (fixP->fx_done && fixP->fx_r_type != BFD_RELOC_C6000_SBR_U15_W)
	abort ();
      break;

    case BFD_RELOC_C6000_DSBT_INDEX:
      if (value != 0)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("addend used with $DSBT_INDEX"));
      if (fixP->fx_done)
	abort ();
      break;

    case BFD_RELOC_C6000_PCR_S21:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);

	  MODIFY_VALUE (newval, value, 2, 7, 21);

	  if (value & 3)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("PC-relative offset not 4-byte-aligned"));
	  if (value + 0x400000 > 0x3ffffc + 0x400000)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("PC-relative offset out of range"));

	  md_number_to_chars (buf, newval, 4);
	}
      break;

    case BFD_RELOC_C6000_PCR_S12:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);

	  MODIFY_VALUE (newval, value, 2, 16, 12);

	  if (value & 3)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("PC-relative offset not 4-byte-aligned"));
	  if (value + 0x2000 > 0x1ffc + 0x2000)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("PC-relative offset out of range"));

	  md_number_to_chars (buf, newval, 4);
	}
      break;

    case BFD_RELOC_C6000_PCR_S10:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);

	  MODIFY_VALUE (newval, value, 2, 13, 10);

	  if (value & 3)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("PC-relative offset not 4-byte-aligned"));
	  if (value + 0x800 > 0x7fc + 0x800)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("PC-relative offset out of range"));

	  md_number_to_chars (buf, newval, 4);
	}
      break;

    case BFD_RELOC_C6000_PCR_S7:
      if (fixP->fx_done || !seg->use_rela_p)
	{
	  valueT newval = md_chars_to_number (buf, 4);

	  MODIFY_VALUE (newval, value, 2, 16, 7);

	  if (value & 3)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("PC-relative offset not 4-byte-aligned"));
	  if (value + 0x100 > 0xfc + 0x100)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("PC-relative offset out of range"));

	  md_number_to_chars (buf, newval, 4);
	}
      break;

    case BFD_RELOC_C6000_PREL31:
      /* Force output to the object file.  */
      fixP->fx_done = 0;
      break;

    default:
      abort ();
    }
}

/* Convert a floating-point number to target (IEEE) format.  */

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

/* Adjust the frags in SECTION (see tic6x_end).  */

static void
tic6x_adjust_section (bfd *abfd ATTRIBUTE_UNUSED, segT section,
		      void *dummy ATTRIBUTE_UNUSED)
{
  segment_info_type *info;
  frchainS *frchp;
  fragS *fragp;
  bfd_boolean have_code = FALSE;
  bfd_boolean have_non_code = FALSE;

  info = seg_info (section);
  if (info == NULL)
    return;

  for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
    for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
      switch (fragp->fr_type)
	{
	case rs_machine_dependent:
	  if (fragp->tc_frag_data.is_insns)
	    have_code = TRUE;
	  break;

	case rs_dummy:
	case rs_fill:
	  if (fragp->fr_fix > 0)
	    have_non_code = TRUE;
	  break;

	default:
	  have_non_code = TRUE;
	  break;
	}

  /* Process alignment requirements in a code-only section.  */
  if (have_code && !have_non_code)
    {
      /* If we need to insert an odd number of instructions to meet an
	 alignment requirement, there must have been an odd number of
	 instructions since the last 8-byte-aligned execute packet
	 boundary.  So there must have been an execute packet with an
	 odd number (and so a number fewer than 8) of instructions
	 into which we can insert a NOP without breaking any previous
	 alignments.

	 If then we need to insert a number 2 mod 4 of instructions,
	 the number of instructions since the last 16-byte-aligned
	 execute packet boundary must be 2 mod 4.  So between that
	 boundary and the following 8-byte-aligned boundary there must
	 either be at least one execute packet with 2-mod-4
	 instructions, or at least two with an odd number of
	 instructions; again, greedily inserting NOPs as soon as
	 possible suffices to meet the alignment requirement.

	 If then we need to insert 4 instructions, we look between the
	 last 32-byte-aligned boundary and the following
	 16-byte-aligned boundary.  The sizes of the execute packets
	 in this range total 4 instructions mod 8, so again there is
	 room for greedy insertion of NOPs to meet the alignment
	 requirement, and before any intermediate point with 8-byte
	 (2-instruction) alignment requirement the sizes of execute
	 packets (and so the room for NOPs) will total 2 instructions
	 mod 4 so greedy insertion will not break such alignments.

	 So we can always meet these alignment requirements by
	 inserting NOPs in parallel with existing execute packets, and
	 by induction the approach described above inserts the minimum
	 number of such NOPs.  */

      /* The number of NOPs we are currently looking to insert, if we
	 have gone back to insert NOPs.  */
      unsigned int want_insert = 0;

      /* Out of that number, the number inserted so far in the current
	 stage of the above algorithm.  */
      unsigned int want_insert_done_so_far = 0;

      /* The position mod 32 at the start of the current frag.  */
      unsigned int pos = 0;

      /* The locations in the frag chain of the most recent frags at
	 the start of which there is the given alignment.  */
      frchainS *frchp_last32, *frchp_last16, *frchp_last8;
      fragS *fragp_last32, *fragp_last16, *fragp_last8;
      unsigned int pos_last32, pos_last16, pos_last8;

      frchp_last32 = frchp_last16 = frchp_last8 = info->frchainP;
      fragp_last32 = fragp_last16 = fragp_last8 = info->frchainP->frch_root;
      pos_last32 = pos_last16 = pos_last8 = 0;

      for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
	for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
	look_at_frag:
	  {
	    bfd_boolean go_back = FALSE;
	    frchainS *frchp_next;
	    fragS *fragp_next;

	    if (fragp->fr_type != rs_machine_dependent)
	      continue;

	    if (fragp->tc_frag_data.is_insns
		&& pos + fragp->fr_fix > 32
		&& !fragp->tc_frag_data.can_cross_fp_boundary)
	      {
		/* As described above, we should always have met an
		   alignment requirement by the time we come back to
		   it.  */
		if (want_insert)
		  abort ();

		if (pos & 3)
		  abort ();
		want_insert = (32 - pos) >> 2;
		if (want_insert > 7)
		  abort ();
		want_insert_done_so_far = 0;
		go_back = TRUE;
	      }

	    if (!fragp->tc_frag_data.is_insns)
	      {
		unsigned int would_insert_bytes;

		if (!(pos & ((1 << fragp->fr_offset) - 1)))
		  /* This alignment requirement is already met.  */
		  continue;

		/* As described above, we should always have met an
		   alignment requirement by the time we come back to
		   it.  */
		if (want_insert)
		  abort ();

		/* We may not be able to meet this requirement within
		   the given number of characters.  */
		would_insert_bytes
		  = ((1 << fragp->fr_offset)
		     - (pos & ((1 << fragp->fr_offset) - 1)));

		if (fragp->fr_subtype != 0
		    && would_insert_bytes > fragp->fr_subtype)
		  continue;

		/* An unmet alignment must be 8, 16 or 32 bytes;
		   smaller ones must always be met within code-only
		   sections and larger ones cause the section not to
		   be code-only.  */
		if (fragp->fr_offset != 3
		    && fragp->fr_offset != 4
		    && fragp->fr_offset != 5)
		  abort ();

		if (would_insert_bytes & 3)
		  abort ();
		want_insert = would_insert_bytes >> 2;
		if (want_insert > 7)
		  abort ();
		want_insert_done_so_far = 0;
		go_back = TRUE;
	      }
	    else if (want_insert && !go_back)
	      {
		unsigned int num_insns = fragp->fr_fix >> 2;
		unsigned int max_poss_nops = 8 - num_insns;

		if (max_poss_nops)
		  {
		    unsigned int cur_want_nops, max_want_nops, do_nops, i;

		    if (want_insert & 1)
		      cur_want_nops = 1;
		    else if (want_insert & 2)
		      cur_want_nops = 2;
		    else if (want_insert & 4)
		      cur_want_nops = 4;
		    else
		      abort ();

		    max_want_nops = cur_want_nops - want_insert_done_so_far;

		    do_nops = (max_poss_nops < max_want_nops
			       ? max_poss_nops
			       : max_want_nops);
		    for (i = 0; i < do_nops; i++)
		      {
			md_number_to_chars (fragp->fr_literal + fragp->fr_fix,
					    0, 4);
			if (target_big_endian)
			  fragp->fr_literal[fragp->fr_fix - 1] |= 0x1;
			else
			  fragp->fr_literal[fragp->fr_fix - 4] |= 0x1;
			fragp->fr_fix += 4;
			fragp->fr_var -= 4;
		      }
		    want_insert_done_so_far += do_nops;
		    if (want_insert_done_so_far == cur_want_nops)
		      {
			want_insert -= want_insert_done_so_far;
			want_insert_done_so_far = 0;
			if (want_insert)
			  go_back = TRUE;
		      }
		  }
	      }
	    if (go_back)
	      {
		if (want_insert & 1)
		  {
		    frchp = frchp_last8;
		    fragp = fragp_last8;
		    pos = pos_last8;
		  }
		else if (want_insert & 2)
		  {
		    frchp = frchp_last8 = frchp_last16;
		    fragp = fragp_last8 = fragp_last16;
		    pos = pos_last8 = pos_last16;
		  }
		else if (want_insert & 4)
		  {
		    frchp = frchp_last8 = frchp_last16 = frchp_last32;
		    fragp = fragp_last8 = fragp_last16 = fragp_last32;
		    pos = pos_last8 = pos_last16 = pos_last32;
		  }
		else
		  abort ();

		goto look_at_frag;
	      }

	    /* Update current position for moving past a code
	       frag.  */
	    pos += fragp->fr_fix;
	    pos &= 31;
	    frchp_next = frchp;
	    fragp_next = fragp->fr_next;
	    if (fragp_next == NULL)
	      {
		frchp_next = frchp->frch_next;
		if (frchp_next != NULL)
		  fragp_next = frchp_next->frch_root;
	      }
	    if (!(pos & 7))
	      {
		frchp_last8 = frchp_next;
		fragp_last8 = fragp_next;
		pos_last8 = pos;
	      }
	    if (!(pos & 15))
	      {
		frchp_last16 = frchp_next;
		fragp_last16 = fragp_next;
		pos_last16 = pos;
	      }
	    if (!(pos & 31))
	      {
		frchp_last32 = frchp_next;
		fragp_last32 = fragp_next;
		pos_last32 = pos;
	      }
	  }
    }

  /* Now convert the machine-dependent frags to machine-independent
     ones.  */
  for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
    for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
      {
	if (fragp->fr_type == rs_machine_dependent)
	  {
	    if (fragp->tc_frag_data.is_insns)
	      frag_wane (fragp);
	    else
	      {
		fragp->fr_type = rs_align_code;
		fragp->fr_var = 1;
		*fragp->fr_literal = 0;
	      }
	  }
      }
}

/* Initialize the machine-dependent parts of a frag.  */

void
tic6x_frag_init (fragS *fragp)
{
  fragp->tc_frag_data.is_insns = FALSE;
  fragp->tc_frag_data.can_cross_fp_boundary = FALSE;
}

/* Set an attribute if it has not already been set by the user.  */

static void
tic6x_set_attribute_int (int tag, int value)
{
  if (tag < 1
      || tag >= NUM_KNOWN_OBJ_ATTRIBUTES)
    abort ();
  if (!tic6x_attributes_set_explicitly[tag])
    bfd_elf_add_proc_attr_int (stdoutput, tag, value);
}

/* Set object attributes deduced from the input file and command line
   rather than given explicitly.  */
static void
tic6x_set_attributes (void)
{
  if (tic6x_arch_attribute == C6XABI_Tag_ISA_none)
    tic6x_arch_attribute = C6XABI_Tag_ISA_C674X;

  tic6x_set_attribute_int (Tag_ISA, tic6x_arch_attribute);
  tic6x_set_attribute_int (Tag_ABI_DSBT, tic6x_dsbt);
  tic6x_set_attribute_int (Tag_ABI_PID, tic6x_pid);
  tic6x_set_attribute_int (Tag_ABI_PIC, tic6x_pic);
}

/* Do machine-dependent manipulations of the frag chains after all
   input has been read and before the machine-independent sizing and
   relaxing.  */

void
tic6x_end (void)
{
  /* Set object attributes at this point if not explicitly set.  */
  tic6x_set_attributes ();

  /* Meeting alignment requirements may require inserting NOPs in
     parallel in execute packets earlier in the segment.  Future
     16-bit instruction generation involves whole-segment optimization
     to determine the best choice and ordering of 32-bit or 16-bit
     instructions.  This doesn't fit will in the general relaxation
     framework, so handle alignment and 16-bit instruction generation
     here.  */
  bfd_map_over_sections (stdoutput, tic6x_adjust_section, NULL);
}

/* No machine-dependent frags at this stage; all converted in
   tic6x_end.  */

void
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
		 fragS *fragp ATTRIBUTE_UNUSED)
{
  abort ();
}

/* No machine-dependent frags at this stage; all converted in
   tic6x_end.  */

int
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
			       segT seg ATTRIBUTE_UNUSED)
{
  abort ();
}

/* Put a number into target byte order.  */

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);
}

/* Machine-dependent operand parsing not currently needed.  */

void
md_operand (expressionS *op ATTRIBUTE_UNUSED)
{
}

/* PC-relative operands are relative to the start of the fetch
   packet.  */

long
tic6x_pcrel_from_section (fixS *fixp, segT sec)
{
  if (fixp->fx_addsy != NULL
      && (!S_IS_DEFINED (fixp->fx_addsy)
	  || S_GET_SEGMENT (fixp->fx_addsy) != sec))
    return 0;
  return (fixp->fx_where + fixp->fx_frag->fr_address) & ~(long) 0x1f;
}

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

valueT
md_section_align (segT segment ATTRIBUTE_UNUSED,
		  valueT size)
{
  /* Round up section sizes to ensure that text sections consist of
     whole fetch packets.  */
  int align = bfd_section_alignment (segment);
  return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
}

/* No special undefined symbol handling needed for now.  */

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

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

arelent *
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
{
  arelent *reloc;
  asymbol *symbol;
  bfd_reloc_code_real_type r_type;

  reloc = XNEW (arelent);
  reloc->sym_ptr_ptr = XNEW (asymbol *);
  symbol = symbol_get_bfdsym (fixp->fx_addsy);
  *reloc->sym_ptr_ptr = symbol;
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
  reloc->addend = (tic6x_generate_rela ? fixp->fx_offset : 0);
  r_type = fixp->fx_r_type;
  reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);

  if (reloc->howto == NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
		    _("Cannot represent relocation type %s"),
		    bfd_get_reloc_code_name (r_type));
      return NULL;
    }

  /* Correct for adjustments bfd_install_relocation will make.  */
  if (reloc->howto->pcrel_offset && reloc->howto->partial_inplace)
    {
      reloc->addend += reloc->address;
      if (!bfd_is_com_section (bfd_asymbol_section (symbol)))
	reloc->addend -= symbol->value;
    }
  if (r_type == BFD_RELOC_C6000_PCR_H16
      || r_type == BFD_RELOC_C6000_PCR_L16)
    {
      symbolS *t = fixp->tc_fix_data.fix_subsy;
      segT sub_symbol_segment;

      resolve_symbol_value (t);
      sub_symbol_segment = S_GET_SEGMENT (t);
      if (sub_symbol_segment == undefined_section)
	as_bad_where (fixp->fx_file, fixp->fx_line,
		      _("undefined symbol %s in PCR relocation"),
		      S_GET_NAME (t));
      else
	{
	  reloc->addend = reloc->address & ~0x1F;
	  reloc->addend -= S_GET_VALUE (t);
	}
    }
  return reloc;
}

/* Convert REGNAME to a DWARF-2 register number.  */

int
tic6x_regname_to_dw2regnum (char *regname)
{
  bfd_boolean reg_ok;
  tic6x_register reg;
  char *rq = regname;

  reg_ok = tic6x_parse_register (&rq, &reg);

  if (!reg_ok)
    return -1;

  switch (reg.side)
    {
    case 1: /* A regs.  */
      if (reg.num < 16)
	return reg.num;
      else if (reg.num < 32)
	return (reg.num - 16) + 37;
      else
	return -1;

    case 2: /* B regs.  */
      if (reg.num < 16)
	return reg.num + 16;
      else if (reg.num < 32)
	return (reg.num - 16) + 53;
      else
	return -1;

    default:
      return -1;
    }
}

/* Initialize the DWARF-2 unwind information for this procedure.  */

void
tic6x_frame_initial_instructions (void)
{
  /* CFA is initial stack pointer (B15).  */
  cfi_add_CFA_def_cfa (31, 0);
}

/* Start an exception table entry.  If idx is nonzero this is an index table
   entry.  */

static void
tic6x_start_unwind_section (const segT text_seg, int idx)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
  const char * text_name;
  const char * prefix;
  const char * prefix_once;
  struct elf_section_match match;
  size_t prefix_len;
  size_t text_len;
  char * sec_name;
  size_t sec_name_len;
  int type;
  int flags;
  int linkonce;

  if (idx)
    {
      prefix = ELF_STRING_C6000_unwind;
      prefix_once = ELF_STRING_C6000_unwind_once;
      type = SHT_C6000_UNWIND;
    }
  else
    {
      prefix = ELF_STRING_C6000_unwind_info;
      prefix_once = ELF_STRING_C6000_unwind_info_once;
      type = SHT_PROGBITS;
    }

  text_name = segment_name (text_seg);
  if (streq (text_name, ".text"))
    text_name = "";

  if (strncmp (text_name, ".gnu.linkonce.t.",
	       strlen (".gnu.linkonce.t.")) == 0)
    {
      prefix = prefix_once;
      text_name += strlen (".gnu.linkonce.t.");
    }

  prefix_len = strlen (prefix);
  text_len = strlen (text_name);
  sec_name_len = prefix_len + text_len;
  sec_name = XNEWVEC (char, sec_name_len + 1);
  memcpy (sec_name, prefix, prefix_len);
  memcpy (sec_name + prefix_len, text_name, text_len);
  sec_name[prefix_len + text_len] = '\0';

  flags = SHF_ALLOC;
  linkonce = 0;
  memset (&match, 0, sizeof (match));

  /* Handle COMDAT group.  */
  if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
    {
      match.group_name = elf_group_name (text_seg);
      if (match.group_name == NULL)
	{
	  as_bad (_("group section `%s' has no group signature"),
		  segment_name (text_seg));
	  ignore_rest_of_line ();
	  return;
	}
      flags |= SHF_GROUP;
      linkonce = 1;
    }

  obj_elf_change_section (sec_name, type, flags, 0, &match,
			  linkonce, 0);

  /* Set the section link for index tables.  */
  if (idx)
    elf_linked_to_section (now_seg) = text_seg;

  seg_info (now_seg)->tc_segment_info_data.text_unwind = unwind;
}


static const int
tic6x_unwind_frame_regs[TIC6X_NUM_UNWIND_REGS] =
/* A15 B15 B14 B13 B12 B11 B10  B3 A14 A13 A12 A11 A10.  */
  { 15, 31, 30, 29, 28, 27, 26, 19, 14, 13, 12, 11, 10 };

/* Register save offsets for __c6xabi_push_rts.  */
static const int
tic6x_pop_rts_offset_little[TIC6X_NUM_UNWIND_REGS] =
/* A15 B15 B14 B13 B12 B11 B10  B3 A14 A13 A12 A11 A10.  */
  { -1,  1,  0, -3, -4, -7, -8,-11, -2, -5, -6, -9,-10};

static const int
tic6x_pop_rts_offset_big[TIC6X_NUM_UNWIND_REGS] =
/* A15 B15 B14 B13 B12 B11 B10  B3 A14 A13 A12 A11 A10.  */
  { -2,  1,  0, -4, -3, -8, -7,-12, -1, -6, -5,-10, -9};

/* Map from dwarf register number to unwind frame register number.  */
static int
tic6x_unwind_reg_from_dwarf (int dwarf)
{
  int reg;

  for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
    {
      if (tic6x_unwind_frame_regs[reg] == dwarf)
	return reg;
    }

  return -1;
}

/* Unwinding bytecode definitions.  */
#define UNWIND_OP_ADD_SP  0x00
#define UNWIND_OP_ADD_SP2 0xd2
#define UNWIND_OP2_POP 0x8000
#define UNWIND_OP2_POP_COMPACT 0xa000
#define UNWIND_OP_POP_REG 0xc0
#define UNWIND_OP_MV_FP 0xd0
#define UNWIND_OP_POP_RTS 0xd1
#define UNWIND_OP_RET 0xe0

/* Maximum stack adjustment for __c6xabi_unwind_cpp_pr3/4 */
#define MAX_COMPACT_SP_OFFSET (0x7f << 3)

static void
tic6x_flush_unwind_word (valueT data)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
  char *ptr;

  /* Create EXTAB entry if it does not exist.  */
  if (unwind->table_entry == NULL)
    {
      tic6x_start_unwind_section (unwind->saved_seg, 0);
      frag_align (2, 0, 0);
      record_alignment (now_seg, 2);
      unwind->table_entry = expr_build_dot ();
      ptr = frag_more (4);
      unwind->frag_start = ptr;
    }
  else
    {
      /* Append additional word of data.  */
      ptr = frag_more (4);
    }

  md_number_to_chars (ptr, data, 4);
}

/* Add a single byte of unwinding data.  */

static void
tic6x_unwind_byte (int byte)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();

  unwind->data_bytes++;
  /* Only flush the first word after we know multiple words are required.  */
  if (unwind->data_bytes == 5)
    {
      if (unwind->personality_index == -1)
	{
	  /* At this point we know we are too big for pr0.  */
	  unwind->personality_index = 1;
	  tic6x_flush_unwind_word (0x81000000 | ((unwind->data >> 8) & 0xffff));
	  unwind->data = ((unwind->data & 0xff) << 8) | byte;
	  unwind->data_bytes++;
	}
      else
	{
	  tic6x_flush_unwind_word (unwind->data);
	  unwind->data = byte;
	}
    }
  else
    {
      unwind->data = (unwind->data << 8) | byte;
      if ((unwind->data_bytes & 3) == 0 && unwind->data_bytes > 4)
	{
	  tic6x_flush_unwind_word (unwind->data);
	  unwind->data = 0;
	}
    }
}

/* Add a two-byte unwinding opcode.  */
static void
tic6x_unwind_2byte (int bytes)
{
  tic6x_unwind_byte (bytes >> 8);
  tic6x_unwind_byte (bytes & 0xff);
}

static void
tic6x_unwind_uleb (offsetT offset)
{
  while (offset > 0x7f)
    {
      tic6x_unwind_byte ((offset & 0x7f) | 0x80);
      offset >>= 7;
    }
  tic6x_unwind_byte (offset);
}

void
tic6x_cfi_startproc (void)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();

  unwind->personality_index = -1;
  unwind->personality_routine = NULL;
  if (unwind->table_entry)
    as_bad (_("missing .endp before .cfi_startproc"));

  unwind->table_entry = NULL;
  unwind->data_bytes = -1;
}

static void
tic6x_output_exidx_entry (void)
{
  char *ptr;
  long where;
  unsigned int marked_pr_dependency;
  segT old_seg;
  subsegT old_subseg;
  tic6x_unwind_info *unwind = tic6x_get_unwind ();

  old_seg = now_seg;
  old_subseg = now_subseg;

  /* Add index table entry.  This is two words.	 */
  tic6x_start_unwind_section (unwind->saved_seg, 1);
  frag_align (2, 0, 0);
  record_alignment (now_seg, 2);

  ptr = frag_more (8);
  memset (ptr, 0, 8);
  where = frag_now_fix () - 8;

  /* Self relative offset of the function start.  */
  fix_new (frag_now, where, 4, unwind->function_start, 0, 1,
	   BFD_RELOC_C6000_PREL31);

  /* Indicate dependency on ABI-defined personality routines to the
     linker, if it hasn't been done already.  */
  marked_pr_dependency
    = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
  if (unwind->personality_index >= 0 && unwind->personality_index < 5
      && !(marked_pr_dependency & (1 << unwind->personality_index)))
    {
      static const char *const name[] =
	{
	  "__c6xabi_unwind_cpp_pr0",
	  "__c6xabi_unwind_cpp_pr1",
	  "__c6xabi_unwind_cpp_pr2",
	  "__c6xabi_unwind_cpp_pr3",
	  "__c6xabi_unwind_cpp_pr4"
	};
      symbolS *pr = symbol_find_or_make (name[unwind->personality_index]);
      fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
      seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
	|= 1 << unwind->personality_index;
    }

  if (unwind->table_entry)
    {
      /* Self relative offset of the table entry.	 */
      fix_new (frag_now, where + 4, 4, unwind->table_entry, 0, 1,
	       BFD_RELOC_C6000_PREL31);
    }
  else
    {
      /* Inline exception table entry.  */
      md_number_to_chars (ptr + 4, unwind->data, 4);
    }

  /* Restore the original section.  */
  subseg_set (old_seg, old_subseg);
}

static void
tic6x_output_unwinding (bfd_boolean need_extab)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
  unsigned safe_mask = unwind->safe_mask;
  unsigned compact_mask = unwind->compact_mask;
  unsigned reg_saved_mask = unwind->reg_saved_mask;
  offsetT cfa_offset = unwind->cfa_offset;
  long where;
  int reg;

  if (unwind->personality_index == -2)
    {
      /* Function can not be unwound.  */
      unwind->data = 1;
      tic6x_output_exidx_entry ();
      return;
    }

  if (unwind->personality_index == -1 && unwind->personality_routine == NULL)
    {
      /* Auto-select a personality routine if none specified.  */
      if (reg_saved_mask || cfa_offset >= MAX_COMPACT_SP_OFFSET)
	unwind->personality_index = -1;
      else if (safe_mask)
	unwind->personality_index = 3;
      else
	unwind->personality_index = 4;
    }

  /* Calculate unwinding opcodes, and emit to EXTAB if necessary.  */
  unwind->table_entry = NULL;
  if (unwind->personality_index == 3 || unwind->personality_index == 4)
    {
      if (cfa_offset >= MAX_COMPACT_SP_OFFSET)
	{
	  as_bad (_("stack pointer offset too large for personality routine"));
	  return;
	}
      if (reg_saved_mask
	  || (unwind->personality_index == 3 && compact_mask != 0)
	  || (unwind->personality_index == 4 && safe_mask != 0))
	{
	  as_bad (_("stack frame layout does not match personality routine"));
	  return;
	}

      unwind->data = (1u << 31) | (unwind->personality_index << 24);
      if (unwind->cfa_reg == 15)
	unwind->data |= 0x7f << 17;
      else
	unwind->data |= cfa_offset << (17 - 3);

      if (unwind->personality_index == 3)
	unwind->data |= safe_mask << 4;
      else
	unwind->data |= compact_mask << 4;
      unwind->data |= unwind->return_reg;
      unwind->data_bytes = 4;
    }
  else
    {
      if (unwind->personality_routine)
	{
	  unwind->data = 0;
	  unwind->data_bytes = 5;
	  tic6x_flush_unwind_word (0);
	  /* First word is personality routine.  */
	  where = frag_now_fix () - 4;
	  fix_new (frag_now, where, 4, unwind->personality_routine, 0, 1,
		   BFD_RELOC_C6000_PREL31);
	}
      else if (unwind->personality_index > 0)
	{
	  unwind->data = 0x8000 | (unwind->personality_index << 8);
	  unwind->data_bytes = 2;
	}
      else /* pr0 or undecided */
	{
	  unwind->data = 0x80;
	  unwind->data_bytes = 1;
	}

      if (unwind->return_reg != UNWIND_B3)
	{
	  tic6x_unwind_byte (UNWIND_OP_RET | unwind->return_reg);
	}

      if (unwind->cfa_reg == 15)
	{
	  tic6x_unwind_byte (UNWIND_OP_MV_FP);
	}
      else if (cfa_offset != 0)
	{
	  cfa_offset >>= 3;
	  if (cfa_offset > 0x80)
	    {
	      tic6x_unwind_byte (UNWIND_OP_ADD_SP2);
	      tic6x_unwind_uleb (cfa_offset - 0x81);
	    }
	  else if (cfa_offset > 0x40)
	    {
	      tic6x_unwind_byte (UNWIND_OP_ADD_SP | 0x3f);
	      tic6x_unwind_byte (UNWIND_OP_ADD_SP | (cfa_offset - 0x40));
	    }
	  else
	    {
	      tic6x_unwind_byte (UNWIND_OP_ADD_SP | (cfa_offset - 1));
	    }
	}

      if (safe_mask)
	tic6x_unwind_2byte (UNWIND_OP2_POP | unwind->safe_mask);
      else if (unwind->pop_rts)
	tic6x_unwind_byte (UNWIND_OP_POP_RTS);
      else if (compact_mask)
	tic6x_unwind_2byte (UNWIND_OP2_POP_COMPACT | unwind->compact_mask);
      else if (reg_saved_mask)
	{
	  offsetT cur_offset;
	  int val;
	  int last_val;

	  tic6x_unwind_byte (UNWIND_OP_POP_REG | unwind->saved_reg_count);
	  last_val = 0;
	  for (cur_offset = 0; unwind->saved_reg_count > 0; cur_offset -= 4)
	    {
	      val = 0xf;
	      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
		{
		  if (!unwind->reg_saved[reg])
		    continue;

		  if (unwind->reg_offset[reg] == cur_offset)
		    {
		      unwind->saved_reg_count--;
		      val = reg;
		      break;
		    }
		}
	      if ((cur_offset & 4) == 4)
		tic6x_unwind_byte ((last_val << 4) | val);
	      else
		last_val = val;
	    }
	  if ((cur_offset & 4) == 4)
	    tic6x_unwind_byte ((last_val << 4) | 0xf);
	}

      /* Pad with RETURN opcodes.  */
      while ((unwind->data_bytes & 3) != 0)
	tic6x_unwind_byte (UNWIND_OP_RET | UNWIND_B3);

      if (unwind->personality_index == -1 && unwind->personality_routine == NULL)
	unwind->personality_index = 0;
    }

  /* Force creation of an EXTAB entry if an LSDA is required.  */
  if (need_extab && !unwind->table_entry)
    {
      if (unwind->data_bytes != 4)
	abort ();

      tic6x_flush_unwind_word (unwind->data);
    }
  else if (unwind->table_entry && !need_extab)
    {
      /* Add an empty descriptor if there is no user-specified data.   */
      char *ptr = frag_more (4);
      md_number_to_chars (ptr, 0, 4);
    }

  /* Fill in length of unwinding bytecode.  */
  if (unwind->table_entry)
    {
      valueT tmp;
      if (unwind->data_bytes > 0x400)
	as_bad (_("too many unwinding instructions"));

      if (unwind->personality_index == -1)
	{
	  tmp = md_chars_to_number (unwind->frag_start + 4, 4);
	  tmp |= (valueT) ((unwind->data_bytes - 8) >> 2) << 24;
	  md_number_to_chars (unwind->frag_start + 4, tmp, 4);
	}
      else if (unwind->personality_index == 1 || unwind->personality_index == 2)
	{
	  tmp = md_chars_to_number (unwind->frag_start, 4);
	  tmp |= ((unwind->data_bytes - 4) >> 2) << 16;
	  md_number_to_chars (unwind->frag_start, tmp, 4);
	}
    }
  tic6x_output_exidx_entry ();
}

/* FIXME: This will get horribly confused if cfi directives are emitted for
   function epilogue.  */
void
tic6x_cfi_endproc (struct fde_entry *fde)
{
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
  struct cfi_insn_data *insn;
  int reg;
  unsigned safe_mask = 0;
  unsigned compact_mask = 0;
  unsigned reg_saved_mask = 0;
  offsetT cfa_offset = 0;
  offsetT save_offset = 0;

  unwind->cfa_reg = 31;
  unwind->return_reg = UNWIND_B3;
  unwind->saved_reg_count = 0;
  unwind->pop_rts = FALSE;

  unwind->saved_seg = now_seg;
  unwind->saved_subseg = now_subseg;

  for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
    unwind->reg_saved[reg] = FALSE;

  /* Scan FDE instructions to build up stack frame layout.  */
  for (insn = fde->data; insn; insn = insn->next)
    {
      switch (insn->insn)
	{
	case DW_CFA_advance_loc:
	  break;

	case DW_CFA_def_cfa:
	  unwind->cfa_reg = insn->u.ri.reg;
	  cfa_offset = insn->u.ri.offset;
	  break;

	case DW_CFA_def_cfa_register:
	  unwind->cfa_reg = insn->u.r;
	  break;

	case DW_CFA_def_cfa_offset:
	  cfa_offset = insn->u.i;
	  break;

	case DW_CFA_undefined:
	case DW_CFA_same_value:
	  reg = tic6x_unwind_reg_from_dwarf (insn->u.r);
	  if (reg >= 0)
	    unwind->reg_saved[reg] = FALSE;
	  break;

	case DW_CFA_offset:
	  reg = tic6x_unwind_reg_from_dwarf (insn->u.ri.reg);
	  if (reg < 0)
	    {
	      as_bad (_("unable to generate unwinding opcode for reg %d"),
		      insn->u.ri.reg);
	      return;
	    }
	  unwind->reg_saved[reg] = TRUE;
	  unwind->reg_offset[reg] = insn->u.ri.offset;
	  if (insn->u.ri.reg == UNWIND_B3)
	    unwind->return_reg = UNWIND_B3;
	  break;

	case DW_CFA_register:
	  if (insn->u.rr.reg1 != 19)
	    {
	      as_bad (_("unable to generate unwinding opcode for reg %d"),
		      insn->u.rr.reg1);
	      return;
	    }

	  reg = tic6x_unwind_reg_from_dwarf (insn->u.rr.reg2);
	  if (reg < 0)
	    {
	      as_bad (_("unable to generate unwinding opcode for reg %d"),
		      insn->u.rr.reg2);
	      return;
	    }

	  unwind->return_reg = reg;
	  unwind->reg_saved[UNWIND_B3] = FALSE;
	  if (unwind->reg_saved[reg])
	    {
	      as_bad (_("unable to restore return address from "
			"previously restored reg"));
	      return;
	    }
	  break;

	case DW_CFA_restore:
	case DW_CFA_remember_state:
	case DW_CFA_restore_state:
	case DW_CFA_GNU_window_save:
	case CFI_escape:
	case CFI_val_encoded_addr:
	  as_bad (_("unhandled CFA insn for unwinding (%d)"), insn->insn);
	  break;

	default:
	  abort ();
	}
    }

  if (unwind->cfa_reg != 15 && unwind->cfa_reg != 31)
    {
      as_bad (_("unable to generate unwinding opcode for frame pointer reg %d"),
	      unwind->cfa_reg);
      return;
    }

  if (unwind->cfa_reg == 15)
    {
      if (cfa_offset != 0)
	{
	  as_bad (_("unable to generate unwinding opcode for "
		    "frame pointer offset"));
	  return;
	}
    }
  else
    {
      if ((cfa_offset & 7) != 0)
	{
	  as_bad (_("unwound stack pointer not doubleword aligned"));
	  return;
	}
    }

  for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
    {
      if (unwind->reg_saved[reg])
	reg_saved_mask |= 1 << (TIC6X_NUM_UNWIND_REGS - (reg + 1));
    }

  /* Check for standard "safe debug" frame layout */
  if (reg_saved_mask)
    {
      save_offset = 0;
      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
	{
	  if (!unwind->reg_saved[reg])
	    continue;

	  if (target_big_endian
	      && reg < TIC6X_NUM_UNWIND_REGS - 1
	      && unwind->reg_saved[reg + 1]
	      && tic6x_unwind_frame_regs[reg]
		  == tic6x_unwind_frame_regs[reg + 1] + 1
	      && (tic6x_unwind_frame_regs[reg] & 1) == 1
	      && (save_offset & 4) == 4)
	    {
	      /* Swapped pair */
	      if (save_offset != unwind->reg_offset[reg + 1]
		  || save_offset - 4 != unwind->reg_offset[reg])
		break;
	      save_offset -= 8;
	      reg++;
	    }
	  else
	    {
	      if (save_offset != unwind->reg_offset[reg])
		break;
	      save_offset -= 4;
	    }
	}
      if (reg == TIC6X_NUM_UNWIND_REGS)
	{
	  safe_mask = reg_saved_mask;
	  reg_saved_mask = 0;
	}
    }

  /* Check for compact frame layout.  */
  if (reg_saved_mask)
    {
      save_offset = 0;
      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
	{
	  int reg2;

	  if (!unwind->reg_saved[reg])
	    continue;

	  if (reg < TIC6X_NUM_UNWIND_REGS - 1)
	    {
	      reg2 = reg + 1;

	      if (!unwind->reg_saved[reg2]
		  || tic6x_unwind_frame_regs[reg]
		      != tic6x_unwind_frame_regs[reg2] + 1
		  || (tic6x_unwind_frame_regs[reg2] & 1) != 0
		  || save_offset == 0)
		reg2 = -1;
	    }
	  else
	    reg2 = -1;

	  if (reg2 >= 0)
	    {
	      int high_offset;
	      if (target_big_endian)
		high_offset = 4; /* lower address = positive stack offset.  */
	      else
		high_offset = 0;

	      if (save_offset + 4 - high_offset != unwind->reg_offset[reg]
		  || save_offset + high_offset != unwind->reg_offset[reg2])
		{
		  break;
		}
	      reg++;
	    }
	  else
	    {
	      if (save_offset != unwind->reg_offset[reg])
		break;
	    }
	  save_offset -= 8;
	}

      if (reg == TIC6X_NUM_UNWIND_REGS)
	{
	  compact_mask = reg_saved_mask;
	  reg_saved_mask = 0;
	}
    }

  /* Check for __c6xabi_pop_rts format */
  if (reg_saved_mask == 0x17ff)
    {
      const int *pop_rts_offset = target_big_endian
				? tic6x_pop_rts_offset_big
			       	: tic6x_pop_rts_offset_little;

      save_offset = 0;
      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
	{
	  if (reg == UNWIND_B15)
	    continue;

	  if (unwind->reg_offset[reg] != pop_rts_offset[reg] * 4)
	    break;
	}

      if (reg == TIC6X_NUM_UNWIND_REGS)
	{
	  unwind->pop_rts = TRUE;
	  reg_saved_mask = 0;
	}
    }
  /* If all else fails then describe the frame manually.  */
  if (reg_saved_mask)
    {
      save_offset = 0;

      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
	{
	  if (!unwind->reg_saved[reg])
	    continue;

	  unwind->saved_reg_count++;
	  /* Encoding uses 4 bits per word, so size of unwinding opcode data
	     limits the save area size.  The exact cap will be figured out
	     later due to overflow, the 0x800 here is just a quick sanity
	     check to weed out obviously excessive offsets.  */
	  if (unwind->reg_offset[reg] > 0 || unwind->reg_offset[reg] < -0x800
	      || (unwind->reg_offset[reg] & 3) != 0)
	    {
	      as_bad (_("stack frame layout too complex for unwinder"));
	      return;
	    }

	  if (unwind->reg_offset[reg] < save_offset)
	    save_offset = unwind->reg_offset[reg] - 4;
	}
    }

  /* Align to 8-byte boundary (stack grows towards negative offsets).  */
  save_offset &= ~7;

  if (unwind->cfa_reg == 31 && !reg_saved_mask)
    {
      cfa_offset += save_offset;
      if (cfa_offset < 0)
	{
	  as_bad (_("unwound frame has negative size"));
	  return;
	}
    }

  unwind->safe_mask = safe_mask;
  unwind->compact_mask = compact_mask;
  unwind->reg_saved_mask = reg_saved_mask;
  unwind->cfa_offset = cfa_offset;
  unwind->function_start = fde->start_address;
}
