13595Sksrini/* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
23900Sksrini   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
33595Sksrini   2009, 2010  Free Software Foundation, Inc.
43595Sksrini   Contributed by Timothy Wall (twall@cygnus.com)
53595Sksrini
63595Sksrini   This file is part of GAS, the GNU Assembler.
73595Sksrini
83595Sksrini   GAS is free software; you can redistribute it and/or modify
93595Sksrini   it under the terms of the GNU General Public License as published by
103595Sksrini   the Free Software Foundation; either version 3, or (at your option)
113595Sksrini   any later version.
123595Sksrini
133595Sksrini   GAS is distributed in the hope that it will be useful,
143595Sksrini   but WITHOUT ANY WARRANTY; without even the implied warranty of
153595Sksrini   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
163595Sksrini   GNU General Public License for more details.
173595Sksrini
183595Sksrini   You should have received a copy of the GNU General Public License
193595Sksrini   along with GAS; see the file COPYING.  If not, write to the Free
203595Sksrini   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
213595Sksrini   02110-1301, USA.  */
223595Sksrini
233595Sksrini/* Texas Instruments TMS320C54X machine specific gas.
243595Sksrini   Written by Timothy Wall (twall@alum.mit.edu).
253595Sksrini
263595Sksrini   Valuable things to do:
273595Sksrini   Pipeline conflict warnings
283595Sksrini   We encode/decode "ld #_label, dp" differently in relocatable files
293595Sksrini     This means we're not compatible with TI output containing those
303595Sksrini     expressions.  We store the upper nine bits; TI stores the lower nine
313595Sksrini     bits.  How they recover the original upper nine bits is beyond me.
323595Sksrini
334073Sksrini   Tests to add to expect testsuite:
343595Sksrini     '=' and '==' with .if, .elseif, and .break
353595Sksrini
363595Sksrini   Incompatibilities (mostly trivial):
373595Sksrini   We don't allow '''
383595Sksrini   We fill text section with zeroes instead of "nop"s
393595Sksrini   We don't convert '' or "" to a single instance
403595Sksrini   We don't convert '' to '\0'
413595Sksrini   We don't allow strings with .byte/.half/.short/.long
423595Sksrini   Probably details of the subsym stuff are different
433595Sksrini   TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
443595Sksrini
453595Sksrini   COFF1 limits section names to 8 characters.
463595Sksrini   Some of the default behavior changed from COFF1 to COFF2.  */
473595Sksrini
483595Sksrini#include <limits.h>
493595Sksrini#include "as.h"
503595Sksrini#include "safe-ctype.h"
513595Sksrini#include "sb.h"
523595Sksrini#include "macro.h"
533595Sksrini#include "subsegs.h"
543595Sksrini#include "struc-symbol.h"
553595Sksrini#include "opcode/tic54x.h"
563595Sksrini#include "obj-coff.h"
574066Sksrini#include <math.h>
583595Sksrini
593595Sksrini
603595Sksrinistatic struct stag
613595Sksrini{
623595Sksrini  symbolS *sym;		        /* Symbol for this stag; value is offset.  */
633595Sksrini  const char *name;		/* Shortcut to symbol name.  */
643595Sksrini  bfd_vma size;		        /* Size of struct/union.  */
654066Sksrini  int current_bitfield_offset;  /* Temporary for tracking fields.  */
663595Sksrini  int is_union;
673595Sksrini  struct stag_field		/* List of fields.  */
684066Sksrini  {
694066Sksrini    const char *name;
703595Sksrini    bfd_vma offset;		/* Of start of this field.  */
713595Sksrini    int bitfield_offset;	/* Of start of this field.  */
723595Sksrini    struct stag *stag;	        /* If field is struct/union.  */
733595Sksrini    struct stag_field *next;
743595Sksrini  } *field;
753595Sksrini  /* For nesting; used only in stag construction.  */
763595Sksrini  struct stag *inner;	        /* Enclosed .struct.  */
773595Sksrini  struct stag *outer;	        /* Enclosing .struct.  */
784066Sksrini} *current_stag = NULL;
794073Sksrini
803900Sksrini#define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm.  */
814066Sksrini
823691Sksrinitypedef struct _tic54x_insn
833595Sksrini{
843595Sksrini  const insn_template *tm;	/* Opcode template.  */
853900Sksrini
863595Sksrini  char mnemonic[MAX_LINE];	/* Opcode name/mnemonic.  */
873595Sksrini  char parmnemonic[MAX_LINE];   /* 2nd mnemonic of parallel insn.  */
883595Sksrini
893595Sksrini  int opcount;
903595Sksrini  struct opstruct
913595Sksrini  {
923595Sksrini    char buf[MAX_LINE];
933595Sksrini    enum optype type;
943595Sksrini    expressionS exp;
953595Sksrini  } operands[MAX_OPERANDS];
963595Sksrini
973595Sksrini  int paropcount;
983595Sksrini  struct opstruct paroperands[MAX_OPERANDS];
993595Sksrini
1003595Sksrini  int is_lkaddr;
1013595Sksrini  int lkoperand;
1023595Sksrini  int words;			/* Size of insn in 16-bit words.  */
1033595Sksrini  int using_default_dst;	/* Do we need to explicitly set an
1043595Sksrini				   omitted OP_DST operand?  */
1053595Sksrini  struct
1063595Sksrini  {
1073595Sksrini    unsigned short word;	     /* Final encoded opcode data.  */
1083595Sksrini    int unresolved;
1093595Sksrini    int r_nchars;		     /* Relocation size.  */
1103595Sksrini    bfd_reloc_code_real_type r_type; /* Relocation type.  */
1113595Sksrini    expressionS addr_expr;	     /* Storage for unresolved expressions.  */
1123595Sksrini  } opcode[3];
1133595Sksrini} tic54x_insn;
1143595Sksrini
1153595Sksrinienum cpu_version
1163595Sksrini{
1173595Sksrini  VNONE = 0, V541 = 1, V542 = 2, V543 = 3, V545 = 5, V548 = 8, V549 = 9,
1183595Sksrini  V545LP = 15, V546LP = 16
1193595Sksrini};
1203595Sksrini
1213595Sksrinienum address_mode
1223595Sksrini{
1233595Sksrini  c_mode,   /* 16-bit addresses.  */
1243595Sksrini  far_mode  /* >16-bit addresses.  */
1253595Sksrini};
1263595Sksrini
1273595Sksrinistatic segT stag_saved_seg;
1283595Sksrinistatic subsegT stag_saved_subseg;
1293595Sksrini
1303595Sksriniconst char comment_chars[] = ";";
1313595Sksriniconst char line_comment_chars[] = ";*#"; /* At column zero only.  */
1323595Sksriniconst char line_separator_chars[] = ""; /* Not permitted.  */
1333595Sksrini
1343595Sksriniint emitting_long = 0;
1353595Sksrini
1363595Sksrini/* Characters which indicate that this is a floating point constant.  */
1373595Sksriniconst char FLT_CHARS[] = "fF";
1383595Sksrini
1393595Sksrini/* Characters that can be used to separate mantissa from exp in FP
1403595Sksrini   nums.  */
1413595Sksriniconst char EXP_CHARS[] = "eE";
1423595Sksrini
1433595Sksriniconst char *md_shortopts = "";
1443595Sksrini
1453786Sksrini#define OPTION_ADDRESS_MODE     (OPTION_MD_BASE)
1463595Sksrini#define OPTION_CPU_VERSION      (OPTION_ADDRESS_MODE + 1)
1473595Sksrini#define OPTION_COFF_VERSION     (OPTION_CPU_VERSION + 1)
1483595Sksrini#define OPTION_STDERR_TO_FILE   (OPTION_COFF_VERSION + 1)
1493595Sksrini
1503595Sksrinistruct option md_longopts[] =
1513595Sksrini{
1523595Sksrini  { "mfar-mode",       no_argument,	    NULL, OPTION_ADDRESS_MODE },
1533595Sksrini  { "mf",	       no_argument,	    NULL, OPTION_ADDRESS_MODE },
1543595Sksrini  { "mcpu",	       required_argument,   NULL, OPTION_CPU_VERSION },
1553595Sksrini  { "merrors-to-file", required_argument,   NULL, OPTION_STDERR_TO_FILE },
1563595Sksrini  { "me",	       required_argument,   NULL, OPTION_STDERR_TO_FILE },
1573595Sksrini  { NULL,              no_argument,         NULL, 0},
1583595Sksrini};
1593595Sksrini
1603595Sksrinisize_t md_longopts_size = sizeof (md_longopts);
1613595Sksrini
1623595Sksrinistatic int assembly_begun = 0;
1633595Sksrini/* Addressing mode is not entirely implemented; the latest rev of the Other
1644066Sksrini   assembler doesn't seem to make any distinction whatsoever; all relocations
1653595Sksrini   are stored as extended relocatiosn.  Older versions used REL16 vs RELEXT16,
1663595Sksrini   but now it seems all relocations are RELEXT16.  We use all RELEXT16.
1673691Sksrini
1684066Sksrini   The cpu version is kind of a waste of time as well.  There is one
1693595Sksrini   instruction (RND) for LP devices only, and several for devices with
1703595Sksrini   extended addressing only.  We include it for compatibility.  */
1713595Sksrinistatic enum address_mode amode = c_mode;
1723595Sksrinistatic enum cpu_version cpu = VNONE;
1733595Sksrini
1743595Sksrini/* Include string substitutions in listing?  */
1753595Sksrinistatic int listing_sslist = 0;
1763595Sksrini
1773595Sksrini/* Did we do subsym substitutions on the line?  */
1783595Sksrinistatic int substitution_line = 0;
1793595Sksrini
1803595Sksrini/* Last label seen.  */
1813595Sksrinistatic symbolS *last_label_seen = NULL;
1823595Sksrini
1833595Sksrini/* This ensures that all new labels are unique.  */
1843595Sksrinistatic int local_label_id;
1853595Sksrini
1863595Sksrinistatic struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse.  */
1873595Sksrinistatic struct hash_control *math_hash; /* Built-in math functions.  */
1883595Sksrini/* Allow maximum levels of macro nesting; level 0 is the main substitution
1893595Sksrini   symbol table.  The other assembler only does 32 levels, so there!  */
1903595Sksrinistatic struct hash_control *subsym_hash[100];
1913595Sksrini
1923595Sksrini/* Keep track of local labels so we can substitute them before GAS sees them
1933595Sksrini   since macros use their own 'namespace' for local labels, use a separate hash
1943595Sksrini
1953595Sksrini   We do our own local label handling 'cuz it's subtly different from the
1963595Sksrini   stock GAS handling.
1973595Sksrini
1983595Sksrini   We use our own macro nesting counter, since GAS overloads it when expanding
1993595Sksrini   other things (like conditionals and repeat loops).  */
2003595Sksrinistatic int macro_level = 0;
2013595Sksrinistatic struct hash_control *local_label_hash[100];
2023595Sksrini/* Keep track of struct/union tags.  */
2033595Sksrinistatic struct hash_control *stag_hash;
2043595Sksrinistatic struct hash_control *op_hash;
2053595Sksrinistatic struct hash_control *parop_hash;
2063595Sksrinistatic struct hash_control *reg_hash;
2073595Sksrinistatic struct hash_control *mmreg_hash;
2083595Sksrinistatic struct hash_control *cc_hash;
2093595Sksrinistatic struct hash_control *cc2_hash;
2103595Sksrinistatic struct hash_control *cc3_hash;
2113595Sksrinistatic struct hash_control *sbit_hash;
2123691Sksrinistatic struct hash_control *misc_symbol_hash;
2134066Sksrini
2144066Sksrini/* Only word (et al.), align, or conditionals are allowed within
2153691Sksrini   .struct/.union.  */
2164066Sksrini#define ILLEGAL_WITHIN_STRUCT()					\
2174066Sksrini  do								\
2184066Sksrini    if (current_stag != NULL)					\
2194066Sksrini      { 							\
2204066Sksrini	as_bad (_("pseudo-op illegal within .struct/.union"));	\
2214066Sksrini	return;							\
2224066Sksrini      }								\
2234066Sksrini  while (0)
2244066Sksrini
2254066Sksrini
2264066Sksrinistatic void subsym_create_or_replace (char *, char *);
2274066Sksrinistatic char *subsym_lookup (char *, int);
2284066Sksrinistatic char *subsym_substitute (char *, int);
2293595Sksrini
2303595Sksrini
2313595Sksrinivoid
2323595Sksrinimd_show_usage (FILE *stream)
2333595Sksrini{
2343595Sksrini  fprintf (stream, _("C54x-specific command line  options:\n"));
2353595Sksrini  fprintf (stream, _("-mfar-mode | -mf          Use extended addressing\n"));
2363595Sksrini  fprintf (stream, _("-mcpu=<CPU version>       Specify the CPU version\n"));
2373595Sksrini  fprintf (stream, _("-merrors-to-file <filename>\n"));
2383595Sksrini  fprintf (stream, _("-me <filename>            Redirect errors to a file\n"));
2393595Sksrini}
2403595Sksrini
2413595Sksrini/* Output a single character (upper octect is zero).  */
2423595Sksrini
2433595Sksrinistatic void
2443595Sksrinitic54x_emit_char (char c)
2453595Sksrini{
2463595Sksrini  expressionS expn;
2473595Sksrini
2483595Sksrini  expn.X_op = O_constant;
2493786Sksrini  expn.X_add_number = c;
2503595Sksrini  emit_expr (&expn, 2);
2513786Sksrini}
2523786Sksrini
2533786Sksrini/* Walk backwards in the frag chain.  */
2543786Sksrini
2553786Sksrinistatic fragS *
2563786Sksrinifrag_prev (fragS *frag, segT seg)
2573786Sksrini{
2583786Sksrini  segment_info_type *seginfo = seg_info (seg);
2593786Sksrini  fragS *fragp;
2603786Sksrini
2613786Sksrini  for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
2623786Sksrini    if (fragp->fr_next == frag)
2633786Sksrini      return fragp;
2643786Sksrini
2653786Sksrini  return NULL;
2663786Sksrini}
2673786Sksrini
2683786Sksrinistatic fragS *
2693786Sksrinibit_offset_frag (fragS *frag, segT seg)
2703786Sksrini{
2713595Sksrini  while (frag != NULL)
2723595Sksrini    {
2733595Sksrini      if (frag->fr_fix == 0
2743595Sksrini	  && frag->fr_opcode == NULL
2753595Sksrini	  && frag->tc_frag_data == 0)
2763595Sksrini	frag = frag_prev (frag, seg);
2773595Sksrini      else
2783786Sksrini	return frag;
2793595Sksrini    }
2803595Sksrini  return NULL;
2813595Sksrini}
2823595Sksrini
2833595Sksrini/* Return the number of bits allocated in the most recent word, or zero if
2843595Sksrini   none. .field/.space/.bes may leave words partially allocated.  */
2853595Sksrini
2863595Sksrinistatic int
2873786Sksrinifrag_bit_offset (fragS *frag, segT seg)
2883786Sksrini{
2893786Sksrini  frag = bit_offset_frag (frag, seg);
2903595Sksrini
2913595Sksrini  if (frag)
2923595Sksrini    return frag->fr_opcode != NULL ? -1 : frag->tc_frag_data;
2933595Sksrini
2943595Sksrini  return 0;
2953595Sksrini}
2963786Sksrini
2973595Sksrini/* Read an expression from a C string; returns a pointer past the end of the
2983786Sksrini   expression.  */
2993786Sksrini
3003786Sksrinistatic char *
3013786Sksriniparse_expression (char *str, expressionS *expn)
3023786Sksrini{
3033786Sksrini  char *s;
3043786Sksrini  char *tmp;
3053786Sksrini
3063786Sksrini  tmp = input_line_pointer;	/* Save line pointer.  */
3073595Sksrini  input_line_pointer = str;
3083595Sksrini  expression (expn);
3093595Sksrini  s = input_line_pointer;
3103595Sksrini  input_line_pointer = tmp;	/* Restore line pointer.  */
3113595Sksrini  return s;			/* Return pointer to where parsing stopped.  */
3123786Sksrini}
3133595Sksrini
3143595Sksrini/* .asg "character-string"|character-string, symbol
3153595Sksrini
3163595Sksrini   .eval is the only pseudo-op allowed to perform arithmetic on substitution
3173595Sksrini   symbols.  all other use of symbols defined with .asg are currently
3183595Sksrini   unsupported.  */
3193595Sksrini
3203595Sksrinistatic void
3213595Sksrinitic54x_asg (int x ATTRIBUTE_UNUSED)
3223595Sksrini{
3233595Sksrini  int c;
3243595Sksrini  char *name;
3253595Sksrini  char *str;
3263595Sksrini  char *tmp;
3273595Sksrini  int quoted = *input_line_pointer == '"';
3283595Sksrini
3293595Sksrini  ILLEGAL_WITHIN_STRUCT ();
3303595Sksrini
3313595Sksrini  if (quoted)
3323595Sksrini    {
3333595Sksrini      int len;
3343595Sksrini      str = demand_copy_C_string (&len);
3353595Sksrini      c = *input_line_pointer;
3363595Sksrini    }
3373595Sksrini  else
3383595Sksrini    {
3393595Sksrini      str = input_line_pointer;
3403595Sksrini      while ((c = *input_line_pointer) != ',')
3413691Sksrini	{
3423595Sksrini	  if (is_end_of_line[(int) *input_line_pointer])
3433691Sksrini	    break;
3443595Sksrini	  ++input_line_pointer;
3453595Sksrini	}
3463595Sksrini      *input_line_pointer = 0;
3473595Sksrini    }
3483595Sksrini  if (c != ',')
3493595Sksrini    {
3503595Sksrini      as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
3513595Sksrini      ignore_rest_of_line ();
3523595Sksrini      return;
3533595Sksrini    }
3543595Sksrini
3553595Sksrini  name = ++input_line_pointer;
3563595Sksrini  c = get_symbol_end ();	/* Get terminator.  */
3573595Sksrini  if (!ISALPHA (*name))
3583595Sksrini    {
3593595Sksrini      as_bad (_("symbols assigned with .asg must begin with a letter"));
3603595Sksrini      ignore_rest_of_line ();
3613595Sksrini      return;
3623595Sksrini    }
3634066Sksrini
3644066Sksrini  tmp = xmalloc (strlen (str) + 1);
3654066Sksrini  strcpy (tmp, str);
3664066Sksrini  str = tmp;
3674066Sksrini  tmp = xmalloc (strlen (name) + 1);
3684066Sksrini  strcpy (tmp, name);
3694066Sksrini  name = tmp;
3704066Sksrini  subsym_create_or_replace (name, str);
3714066Sksrini  *input_line_pointer = c;
3724066Sksrini  demand_empty_rest_of_line ();
3734066Sksrini}
3744066Sksrini
3754066Sksrini/* .eval expression, symbol
3764066Sksrini   There's something screwy about this.  The other assembler sometimes does and
3774066Sksrini   sometimes doesn't substitute symbols defined with .eval.
3784066Sksrini   We'll put the symbols into the subsym table as well as the normal symbol
3794066Sksrini   table, since that's what works best.  */
3804066Sksrini
3814066Sksrinistatic void
3824066Sksrinitic54x_eval (int x ATTRIBUTE_UNUSED)
3834066Sksrini{
3844066Sksrini  char c;
3854066Sksrini  int value;
3864066Sksrini  char *name;
3874066Sksrini  symbolS *symbolP;
3884066Sksrini  char valuestr[32], *tmp;
3894066Sksrini  int quoted;
3904066Sksrini
3914066Sksrini  ILLEGAL_WITHIN_STRUCT ();
3924066Sksrini
3934066Sksrini  SKIP_WHITESPACE ();
3944066Sksrini
3954066Sksrini  quoted = *input_line_pointer == '"';
3964066Sksrini  if (quoted)
3974066Sksrini    ++input_line_pointer;
3984066Sksrini  value = get_absolute_expression ();
3994066Sksrini  if (quoted)
4004066Sksrini    {
4014066Sksrini      if (*input_line_pointer != '"')
4024066Sksrini	{
4034066Sksrini	  as_bad (_("Unterminated string after absolute expression"));
4044066Sksrini	  ignore_rest_of_line ();
4054066Sksrini	  return;
4064066Sksrini	}
4074066Sksrini      ++input_line_pointer;
4084066Sksrini    }
4093595Sksrini  if (*input_line_pointer++ != ',')
4103691Sksrini    {
4113595Sksrini      as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
4123595Sksrini      ignore_rest_of_line ();
4133595Sksrini      return;
4143595Sksrini    }
4153595Sksrini  name = input_line_pointer;
4163595Sksrini  c = get_symbol_end ();	/* Get terminator.  */
4174066Sksrini  tmp = xmalloc (strlen (name) + 1);
4184066Sksrini  name = strcpy (tmp, name);
4193691Sksrini  *input_line_pointer = c;
4203691Sksrini
4214066Sksrini  if (!ISALPHA (*name))
4224066Sksrini    {
4234066Sksrini      as_bad (_("symbols assigned with .eval must begin with a letter"));
4243595Sksrini      ignore_rest_of_line ();
4254066Sksrini      return;
4264066Sksrini    }
4274066Sksrini  symbolP = symbol_new (name, absolute_section,
4283595Sksrini			(valueT) value, &zero_address_frag);
4293595Sksrini  SF_SET_LOCAL (symbolP);
4303595Sksrini  symbol_table_insert (symbolP);
4313595Sksrini
4323595Sksrini  /* The "other" assembler sometimes doesn't put .eval's in the subsym table
4333595Sksrini     But since there's not written rule as to when, don't even bother trying
4343595Sksrini     to match their behavior.  */
4353595Sksrini  sprintf (valuestr, "%d", value);
4363595Sksrini  tmp = xmalloc (strlen (valuestr) + 1);
4373595Sksrini  strcpy (tmp, valuestr);
4383595Sksrini  subsym_create_or_replace (name, tmp);
4393595Sksrini
4403827Smcimadamore  demand_empty_rest_of_line ();
4413595Sksrini}
4423595Sksrini
4433595Sksrini/* .bss symbol, size [, [blocking flag] [, alignment flag]
4443595Sksrini
4453595Sksrini   alignment is to a longword boundary; blocking is to 128-word boundary.
4463595Sksrini
4473595Sksrini   1) if there is a hole in memory, this directive should attempt to fill it
4483595Sksrini      (not yet implemented).
4493595Sksrini
4503595Sksrini   2) if the blocking flag is not set, allocate at the current SPC
4513595Sksrini      otherwise, check to see if the current SPC plus the space to be
4523595Sksrini      allocated crosses the page boundary (128 words).
4533595Sksrini      if there's not enough space, create a hole and align with the next page
4543595Sksrini      boundary.
4553595Sksrini      (not yet implemented).  */
4563595Sksrini
4573595Sksrinistatic void
4583595Sksrinitic54x_bss (int x ATTRIBUTE_UNUSED)
4593595Sksrini{
4603595Sksrini  char c;
4613595Sksrini  char *name;
4623595Sksrini  char *p;
4633595Sksrini  int words;
4643595Sksrini  segT current_seg;
4653595Sksrini  subsegT current_subseg;
4663595Sksrini  symbolS *symbolP;
4673595Sksrini  int block = 0;
4683595Sksrini  int align = 0;
4693595Sksrini
4703595Sksrini  ILLEGAL_WITHIN_STRUCT ();
4713595Sksrini
4723595Sksrini  current_seg = now_seg;	/* Save current seg.  */
4733595Sksrini  current_subseg = now_subseg;	/* Save current subseg.  */
4743595Sksrini
4753595Sksrini  name = input_line_pointer;
4763595Sksrini  c = get_symbol_end ();	/* Get terminator.  */
4773595Sksrini  if (c != ',')
4783595Sksrini    {
4793595Sksrini      as_bad (_(".bss size argument missing\n"));
4803595Sksrini      ignore_rest_of_line ();
4813595Sksrini      return;
4823595Sksrini    }
4833595Sksrini
4843595Sksrini  ++input_line_pointer;
4853595Sksrini  words = get_absolute_expression ();
4863595Sksrini  if (words < 0)
4873827Smcimadamore    {
4883595Sksrini      as_bad (_(".bss size %d < 0!"), words);
4893595Sksrini      ignore_rest_of_line ();
4903595Sksrini      return;
4913595Sksrini    }
4923595Sksrini
4933595Sksrini  if (*input_line_pointer == ',')
4943595Sksrini    {
4953595Sksrini      /* The blocking flag may be missing.  */
4963595Sksrini      ++input_line_pointer;
4973595Sksrini      if (*input_line_pointer != ',')
4983595Sksrini	block = get_absolute_expression ();
4993595Sksrini      else
5003595Sksrini	block = 0;
5013595Sksrini
5023595Sksrini      if (*input_line_pointer == ',')
5033595Sksrini	{
5043595Sksrini	  ++input_line_pointer;
5053595Sksrini	  align = get_absolute_expression ();
5063595Sksrini	}
5073691Sksrini      else
5083595Sksrini	align = 0;
5093595Sksrini    }
5103827Smcimadamore  else
5113595Sksrini    block = align = 0;
5123595Sksrini
5133595Sksrini  subseg_set (bss_section, 0);
5143595Sksrini  symbolP = symbol_find_or_make (name);
5153595Sksrini
5163595Sksrini  if (S_GET_SEGMENT (symbolP) == bss_section)
5173595Sksrini    symbolP->sy_frag->fr_symbol = (symbolS *) NULL;
5184066Sksrini
5194066Sksrini  symbol_set_frag (symbolP, frag_now);
5204066Sksrini  p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
5213691Sksrini		(offsetT) (words * OCTETS_PER_BYTE), (char *) 0);
5224066Sksrini  *p = 0;			/* Fill char.  */
5234066Sksrini
5243595Sksrini  S_SET_SEGMENT (symbolP, bss_section);
5254073Sksrini
5264073Sksrini  /* The symbol may already have been created with a preceding
5274073Sksrini     ".globl" directive -- be careful not to step on storage class
5284073Sksrini     in that case.  Otherwise, set it to static.  */
5294073Sksrini  if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
5304066Sksrini    S_SET_STORAGE_CLASS (symbolP, C_STAT);
5314073Sksrini
5324066Sksrini  if (align)
5334073Sksrini    {
5344066Sksrini      /* s_align eats end of line; restore it */
5354066Sksrini      s_align_bytes (4);
5364073Sksrini      --input_line_pointer;
5374073Sksrini    }
5384073Sksrini
5394073Sksrini  if (block)
5404066Sksrini    bss_section->flags |= SEC_TIC54X_BLOCK;
5414066Sksrini
5424066Sksrini  subseg_set (current_seg, current_subseg);	/* Restore current seg.  */
5434066Sksrini  demand_empty_rest_of_line ();
5444066Sksrini}
5454066Sksrini
5464066Sksrinistatic void
5474066Sksrinistag_add_field_symbols (struct stag *stag,
5484066Sksrini			const char *path,
5494066Sksrini			bfd_vma base_offset,
5504066Sksrini			symbolS *rootsym,
5514066Sksrini			const char *root_stag_name)
5524066Sksrini{
5534066Sksrini  char prefix[strlen (path) + 2];
5544066Sksrini  struct stag_field *field = stag->field;
5553595Sksrini
5564066Sksrini  /* Construct a symbol for every field contained within this structure
5574066Sksrini     including fields within structure fields.  */
5584066Sksrini  strcpy (prefix, path);
5593595Sksrini  if (*path)
5603595Sksrini    strcat (prefix, ".");
5613595Sksrini
5623595Sksrini  while (field != NULL)
5633595Sksrini    {
5643595Sksrini      int len = strlen (prefix) + strlen (field->name) + 2;
5653595Sksrini      char *name = xmalloc (len);
5664073Sksrini      strcpy (name, prefix);
5674073Sksrini      strcat (name, field->name);
5683595Sksrini
5693595Sksrini      if (rootsym == NULL)
5703595Sksrini	{
5714073Sksrini	  symbolS *sym;
5723595Sksrini	  sym = symbol_new (name, absolute_section,
5733595Sksrini			    (field->stag ? field->offset :
5744073Sksrini			     (valueT) (base_offset + field->offset)),
5754073Sksrini			    &zero_address_frag);
5764073Sksrini	  SF_SET_LOCAL (sym);
5774073Sksrini	  symbol_table_insert (sym);
5784073Sksrini	}
5794073Sksrini      else
5804073Sksrini	{
5814073Sksrini	  char *replacement = xmalloc (strlen (name)
5824073Sksrini				       + strlen (stag->name) + 2);
5834073Sksrini	  strcpy (replacement, S_GET_NAME (rootsym));
5843595Sksrini	  strcat (replacement, "+");
5853595Sksrini	  strcat (replacement, root_stag_name);
5863595Sksrini	  strcat (replacement, name + strlen (S_GET_NAME (rootsym)));
5873595Sksrini	  hash_insert (subsym_hash[0], name, replacement);
5883595Sksrini	}
5894073Sksrini
5904073Sksrini      /* Recurse if the field is a structure.
5914073Sksrini	 Note the field offset is relative to the outermost struct.  */
5924073Sksrini      if (field->stag != NULL)
5934073Sksrini	stag_add_field_symbols (field->stag, name,
5944073Sksrini				field->offset,
5954073Sksrini				rootsym, root_stag_name);
5964073Sksrini      field = field->next;
5974073Sksrini    }
5984073Sksrini}
5994073Sksrini
6004073Sksrini/* Keep track of stag fields so that when structures are nested we can add the
6014073Sksrini   complete dereferencing symbols to the symbol table.  */
6024073Sksrini
6034073Sksrinistatic void
6044073Sksrinistag_add_field (struct stag *parent,
6054073Sksrini		const char *name,
6064073Sksrini		bfd_vma offset,
6074073Sksrini		struct stag *stag)
6084073Sksrini{
6094073Sksrini  struct stag_field *sfield = xmalloc (sizeof (struct stag_field));
6104073Sksrini
6113595Sksrini  memset (sfield, 0, sizeof (*sfield));
6123595Sksrini  sfield->name = strcpy (xmalloc (strlen (name) + 1), name);
6133595Sksrini  sfield->offset = offset;
6143595Sksrini  sfield->bitfield_offset = parent->current_bitfield_offset;
6153595Sksrini  sfield->stag = stag;
6163595Sksrini  if (parent->field == NULL)
6173595Sksrini    parent->field = sfield;
6183595Sksrini  else
6193595Sksrini    {
6203595Sksrini      struct stag_field *sf = parent->field;
6213595Sksrini      while (sf->next != NULL)
6223595Sksrini	sf = sf->next;
6233786Sksrini      sf->next = sfield;
6243595Sksrini    }
6253595Sksrini  /* Only create a symbol for this field if the parent has no name.  */
6263595Sksrini  if (!strncmp (".fake", parent->name, 5))
6273595Sksrini    {
6283595Sksrini      symbolS *sym = symbol_new (name, absolute_section,
6293595Sksrini				 (valueT) offset, &zero_address_frag);
6303595Sksrini      SF_SET_LOCAL (sym);
6313595Sksrini      symbol_table_insert (sym);
6323595Sksrini    }
6333595Sksrini}
6343595Sksrini
6353595Sksrini/* [STAG] .struct       [OFFSET]
6363595Sksrini   Start defining structure offsets (symbols in absolute section).  */
6373595Sksrini
6383595Sksrinistatic void
6393595Sksrinitic54x_struct (int arg)
6403595Sksrini{
6413595Sksrini  int start_offset = 0;
6423595Sksrini  int is_union = arg;
6433595Sksrini
6443595Sksrini  if (!current_stag)
6453595Sksrini    {
6463595Sksrini      /* Starting a new struct, switch to absolute section.  */
6473595Sksrini      stag_saved_seg = now_seg;
6483595Sksrini      stag_saved_subseg = now_subseg;
6493691Sksrini      subseg_set (absolute_section, 0);
6503595Sksrini    }
6513691Sksrini  /* Align the current pointer.  */
6524066Sksrini  else if (current_stag->current_bitfield_offset != 0)
6534066Sksrini    {
6544073Sksrini      ++abs_section_offset;
6554073Sksrini      current_stag->current_bitfield_offset = 0;
6564073Sksrini    }
6574066Sksrini
6584073Sksrini  /* Offset expression is only meaningful for global .structs.  */
6594073Sksrini  if (!is_union)
6604073Sksrini    {
6614073Sksrini      /* Offset is ignored in inner structs.  */
6623691Sksrini      SKIP_WHITESPACE ();
6633595Sksrini      if (!is_end_of_line[(int) *input_line_pointer])
6643595Sksrini	start_offset = get_absolute_expression ();
6653595Sksrini      else
6663595Sksrini	start_offset = 0;
6673691Sksrini    }
6683715Sksrini
6693595Sksrini  if (current_stag)
6703595Sksrini    {
6713595Sksrini      /* Nesting, link to outer one.  */
6723715Sksrini      current_stag->inner = (struct stag *) xmalloc (sizeof (struct stag));
6733715Sksrini      memset (current_stag->inner, 0, sizeof (struct stag));
6743715Sksrini      current_stag->inner->outer = current_stag;
6753595Sksrini      current_stag = current_stag->inner;
6763595Sksrini      if (start_offset)
6773595Sksrini	as_warn (_("Offset on nested structures is ignored"));
6783715Sksrini      start_offset = abs_section_offset;
6793715Sksrini    }
6803715Sksrini  else
6813715Sksrini    {
6823715Sksrini      current_stag = (struct stag *) xmalloc (sizeof (struct stag));
6833595Sksrini      memset (current_stag, 0, sizeof (struct stag));
6843595Sksrini      abs_section_offset = start_offset;
6853715Sksrini    }
6863715Sksrini  current_stag->is_union = is_union;
6873715Sksrini
6883715Sksrini  if (line_label == NULL)
6893715Sksrini    {
6903595Sksrini      static int struct_count = 0;
6913595Sksrini      char fake[] = ".fake_stagNNNNNNN";
6923595Sksrini      sprintf (fake, ".fake_stag%d", struct_count++);
6933595Sksrini      current_stag->sym = symbol_new (fake, absolute_section,
6943595Sksrini				      (valueT) abs_section_offset,
6953595Sksrini				      &zero_address_frag);
6963595Sksrini    }
6973595Sksrini  else
6983595Sksrini    {
6993595Sksrini      char label[strlen (S_GET_NAME (line_label)) + 1];
7003595Sksrini      strcpy (label, S_GET_NAME (line_label));
7013595Sksrini      current_stag->sym = symbol_new (label, absolute_section,
7023595Sksrini				      (valueT) abs_section_offset,
7033595Sksrini				      &zero_address_frag);
7043595Sksrini    }
7053595Sksrini  current_stag->name = S_GET_NAME (current_stag->sym);
7063595Sksrini  SF_SET_LOCAL (current_stag->sym);
7073595Sksrini  /* Nested .structs don't go into the symbol table.  */
7083595Sksrini  if (current_stag->outer == NULL)
7093595Sksrini    symbol_table_insert (current_stag->sym);
7103595Sksrini
7113595Sksrini  line_label = NULL;
7123595Sksrini}
7133595Sksrini
7143595Sksrini/* [LABEL] .endstruct
7153595Sksrini   finish defining structure offsets; optional LABEL's value will be the size
7163595Sksrini   of the structure.  */
7173595Sksrini
7183595Sksrinistatic void
7193595Sksrinitic54x_endstruct (int is_union)
7203595Sksrini{
7213595Sksrini  int size;
7223824Sjlahoda  const char *path =
7233824Sjlahoda    !strncmp (current_stag->name, ".fake", 5) ? "" : current_stag->name;
7243595Sksrini
7253595Sksrini  if (!current_stag || current_stag->is_union != is_union)
7263595Sksrini    {
7273595Sksrini      as_bad (_(".end%s without preceding .%s"),
7283595Sksrini	      is_union ? "union" : "struct",
7293595Sksrini	      is_union ? "union" : "struct");
7303595Sksrini      ignore_rest_of_line ();
7313595Sksrini      return;
7323595Sksrini    }
7333595Sksrini
7343595Sksrini  /* Align end of structures.  */
7353595Sksrini  if (current_stag->current_bitfield_offset)
7363824Sjlahoda    {
7373595Sksrini      ++abs_section_offset;
7383595Sksrini      current_stag->current_bitfield_offset = 0;
7393715Sksrini    }
7403595Sksrini
7413595Sksrini  if (current_stag->is_union)
7423595Sksrini    size = current_stag->size;
7433595Sksrini  else
7443595Sksrini    size = abs_section_offset - S_GET_VALUE (current_stag->sym);
7453595Sksrini  if (line_label != NULL)
7463595Sksrini    {
7473595Sksrini      S_SET_VALUE (line_label, size);
7483595Sksrini      symbol_table_insert (line_label);
7493691Sksrini      line_label = NULL;
7503595Sksrini    }
7513595Sksrini
7523691Sksrini  /* Union size has already been calculated.  */
7533595Sksrini  if (!current_stag->is_union)
7543595Sksrini    current_stag->size = size;
7553595Sksrini  /* Nested .structs don't get put in the stag table.  */
7563595Sksrini  if (current_stag->outer == NULL)
7573595Sksrini    {
7583595Sksrini      hash_insert (stag_hash, current_stag->name, current_stag);
7593595Sksrini      stag_add_field_symbols (current_stag, path,
7604073Sksrini			      S_GET_VALUE (current_stag->sym),
7613595Sksrini			      NULL, NULL);
7623595Sksrini    }
7633595Sksrini  current_stag = current_stag->outer;
7643595Sksrini
7653595Sksrini  /* If this is a nested .struct/.union, add it as a field to the enclosing
7663595Sksrini     one.  otherwise, restore the section we were in.  */
7673595Sksrini  if (current_stag != NULL)
7683595Sksrini    {
7693691Sksrini      stag_add_field (current_stag, current_stag->inner->name,
7703595Sksrini		      S_GET_VALUE (current_stag->inner->sym),
7713595Sksrini		      current_stag->inner);
7723595Sksrini    }
7733595Sksrini  else
7743595Sksrini    subseg_set (stag_saved_seg, stag_saved_subseg);
7753595Sksrini}
7763595Sksrini
7773595Sksrini/* [LABEL]      .tag    STAG
7783595Sksrini   Reference a structure within a structure, as a sized field with an optional
7793691Sksrini   label.
7803595Sksrini   If used outside of a .struct/.endstruct, overlays the given structure
7813786Sksrini   format on the existing allocated space.  */
7823595Sksrini
7833595Sksrinistatic void
7843595Sksrinitic54x_tag (int ignore ATTRIBUTE_UNUSED)
7853595Sksrini{
7863595Sksrini  char *name = input_line_pointer;
7873691Sksrini  int c = get_symbol_end ();
7883595Sksrini  struct stag *stag = (struct stag *) hash_find (stag_hash, name);
7893595Sksrini
7903691Sksrini  if (!stag)
7913691Sksrini    {
7923595Sksrini      if (*name)
7933595Sksrini	as_bad (_("Unrecognized struct/union tag '%s'"), name);
7943595Sksrini      else
7953691Sksrini	as_bad (_(".tag requires a structure tag"));
7963595Sksrini      ignore_rest_of_line ();
7973595Sksrini      return;
7983595Sksrini    }
7993595Sksrini  if (line_label == NULL)
8003691Sksrini    {
8013691Sksrini      as_bad (_("Label required for .tag"));
8023595Sksrini      ignore_rest_of_line ();
8033595Sksrini      return;
8043595Sksrini    }
8053595Sksrini  else
8063691Sksrini    {
8073691Sksrini      char label[strlen (S_GET_NAME (line_label)) + 1];
8083691Sksrini
8093595Sksrini      strcpy (label, S_GET_NAME (line_label));
8103595Sksrini      if (current_stag != NULL)
8113595Sksrini	stag_add_field (current_stag, label,
8123595Sksrini			abs_section_offset - S_GET_VALUE (current_stag->sym),
8133595Sksrini			stag);
8143595Sksrini      else
8153595Sksrini	{
8163595Sksrini	  symbolS *sym = symbol_find (label);
8173595Sksrini
8183595Sksrini	  if (!sym)
8193595Sksrini	    {
8203595Sksrini	      as_bad (_(".tag target '%s' undefined"), label);
8213595Sksrini	      ignore_rest_of_line ();
8223691Sksrini	      return;
8233595Sksrini	    }
8243595Sksrini	  stag_add_field_symbols (stag, S_GET_NAME (sym),
8253595Sksrini				  S_GET_VALUE (stag->sym), sym, stag->name);
8263595Sksrini	}
8273595Sksrini    }
8283595Sksrini
8293595Sksrini  /* Bump by the struct size, but only if we're within a .struct section.  */
8303595Sksrini  if (current_stag != NULL && !current_stag->is_union)
8313595Sksrini    abs_section_offset += stag->size;
8323595Sksrini
8333595Sksrini  *input_line_pointer = c;
8343691Sksrini  demand_empty_rest_of_line ();
8353595Sksrini  line_label = NULL;
8363691Sksrini}
8373691Sksrini
8383595Sksrini/* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
8393595Sksrini   .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
8403595Sksrini   and .word.  */
8413595Sksrini
8423595Sksrinistatic void
8433595Sksrinitic54x_struct_field (int type)
8443595Sksrini{
8454066Sksrini  int size;
8464066Sksrini  int count = 1;
8473595Sksrini  int new_bitfield_offset = 0;
8483595Sksrini  int field_align = current_stag->current_bitfield_offset != 0;
8493595Sksrini  int longword_align = 0;
8504066Sksrini
8514073Sksrini  SKIP_WHITESPACE ();
8524073Sksrini  if (!is_end_of_line[(int) *input_line_pointer])
8534073Sksrini    count = get_absolute_expression ();
8544073Sksrini
8554073Sksrini  switch (type)
8563691Sksrini    {
8573595Sksrini    case 'b':
8583595Sksrini    case 'B':
8593595Sksrini    case 'c':
8603595Sksrini    case 'C':
8613595Sksrini    case 'h':
8623595Sksrini    case 'H':
8633595Sksrini    case 'i':
8643595Sksrini    case 'I':
8653595Sksrini    case 's':
8663595Sksrini    case 'S':
8673595Sksrini    case 'w':
8683595Sksrini    case 'W':
8693595Sksrini    case '*': /* String.  */
8703595Sksrini      size = 1;
8713595Sksrini      break;
8723595Sksrini    case 'f':
8734066Sksrini    case 'l':
8744066Sksrini    case 'L':
8754066Sksrini      longword_align = 1;
8763595Sksrini      size = 2;
8773595Sksrini      break;
8783595Sksrini    case '.': /* Bitfield.  */
8794066Sksrini      size = 0;
8803595Sksrini      if (count < 1 || count > 32)
8813595Sksrini	{
8823595Sksrini	  as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count);
8833595Sksrini	  ignore_rest_of_line ();
8844066Sksrini	  return;
8853595Sksrini	}
8864066Sksrini      if (current_stag->current_bitfield_offset + count > 16)
8873691Sksrini	{
8883691Sksrini	  /* Set the appropriate size and new field offset.  */
8894066Sksrini	  if (count == 32)
8904066Sksrini	    {
8914066Sksrini	      size = 2;
8924066Sksrini	      count = 1;
8934066Sksrini	    }
8944066Sksrini	  else if (count > 16)
8954066Sksrini	    {
8964066Sksrini	      size = 1;
8974066Sksrini	      count = 1;
8984066Sksrini	      new_bitfield_offset = count - 16;
8994066Sksrini	    }
9004066Sksrini	  else
9014066Sksrini	    new_bitfield_offset = count;
9024066Sksrini	}
9034066Sksrini      else
9044066Sksrini	{
9054066Sksrini	  field_align = 0;
9064066Sksrini	  new_bitfield_offset = current_stag->current_bitfield_offset + count;
9074066Sksrini	}
9084066Sksrini      break;
9094066Sksrini    default:
9104066Sksrini      as_bad (_("Unrecognized field type '%c'"), type);
9114066Sksrini      ignore_rest_of_line ();
9124066Sksrini      return;
9134066Sksrini    }
9144066Sksrini
9154066Sksrini  if (field_align)
9163691Sksrini    {
9173770Sjjg      /* Align to the actual starting position of the field.  */
9183691Sksrini      current_stag->current_bitfield_offset = 0;
9193691Sksrini      ++abs_section_offset;
9203691Sksrini    }
9213691Sksrini  /* Align to longword boundary.  */
9223595Sksrini  if (longword_align && (abs_section_offset & 0x1))
9233595Sksrini    ++abs_section_offset;
9243595Sksrini
9253595Sksrini  if (line_label == NULL)
9263595Sksrini    {
9273595Sksrini      static int fieldno = 0;
9283595Sksrini      char fake[] = ".fake_fieldNNNNN";
9293595Sksrini
9303595Sksrini      sprintf (fake, ".fake_field%d", fieldno++);
9313595Sksrini      stag_add_field (current_stag, fake,
9323595Sksrini		      abs_section_offset - S_GET_VALUE (current_stag->sym),
9333595Sksrini		      NULL);
9343595Sksrini    }
9353595Sksrini  else
9363595Sksrini    {
9373595Sksrini      char label[strlen (S_GET_NAME (line_label) + 1)];
9383595Sksrini
9393595Sksrini      strcpy (label, S_GET_NAME (line_label));
9403595Sksrini      stag_add_field (current_stag, label,
9413595Sksrini		      abs_section_offset - S_GET_VALUE (current_stag->sym),
9423595Sksrini		      NULL);
9433595Sksrini    }
9443595Sksrini
9453595Sksrini  if (current_stag->is_union)
9463595Sksrini    {
9473595Sksrini      /* Note we treat the element as if it were an array of COUNT.  */
9483595Sksrini      if (current_stag->size < (unsigned) size * count)
9493595Sksrini	current_stag->size = size * count;
9503595Sksrini    }
9513595Sksrini  else
9523595Sksrini    {
9533595Sksrini      abs_section_offset += (unsigned) size * count;
9543595Sksrini      current_stag->current_bitfield_offset = new_bitfield_offset;
9553595Sksrini    }
9563786Sksrini  line_label = NULL;
9573595Sksrini}
9583595Sksrini
9593595Sksrini/* Handle .byte, .word. .int, .long and all variants.  */
9603595Sksrini
9613786Sksrinistatic void
9623595Sksrinitic54x_cons (int type)
9633595Sksrini{
9643595Sksrini  unsigned int c;
9653691Sksrini  int octets;
9663691Sksrini
9673691Sksrini  /* If we're within a .struct construct, don't actually allocate space.  */
9683691Sksrini  if (current_stag != NULL)
9693595Sksrini    {
9703595Sksrini      tic54x_struct_field (type);
9713595Sksrini      return;
9723595Sksrini    }
9733595Sksrini
9743595Sksrini#ifdef md_flush_pending_output
9753595Sksrini  md_flush_pending_output ();
9763595Sksrini#endif
9773595Sksrini
9783595Sksrini  generate_lineno_debug ();
9793595Sksrini
9803786Sksrini  /* Align long words to long word boundaries (4 octets).  */
9813595Sksrini  if (type == 'l' || type == 'L')
9823595Sksrini    {
9833595Sksrini      frag_align (2, 0, 2);
9843786Sksrini      /* If there's a label, assign it to the first allocated word.  */
9853900Sksrini      if (line_label != NULL)
9863786Sksrini	{
9873786Sksrini	  symbol_set_frag (line_label, frag_now);
9883786Sksrini	  S_SET_VALUE (line_label, frag_now_fix ());
9893595Sksrini	}
9903786Sksrini    }
9913786Sksrini
9923786Sksrini  switch (type)
9933786Sksrini    {
9943786Sksrini    case 'l':
9953786Sksrini    case 'L':
9963786Sksrini    case 'x':
9973786Sksrini      octets = 4;
9983595Sksrini      break;
9993786Sksrini    case 'b':
10003786Sksrini    case 'B':
10013786Sksrini    case 'c':
10023786Sksrini    case 'C':
10033786Sksrini      octets = 1;
10043786Sksrini      break;
10053625Sjlahoda    default:
10063595Sksrini      octets = 2;
10073786Sksrini      break;
10083786Sksrini    }
10093786Sksrini
10103786Sksrini  do
10113786Sksrini    {
10123786Sksrini      if (*input_line_pointer == '"')
10133786Sksrini	{
10143786Sksrini	  input_line_pointer++;
10153786Sksrini	  while (is_a_char (c = next_char_of_string ()))
10163786Sksrini	    tic54x_emit_char (c);
10173786Sksrini	  know (input_line_pointer[-1] == '\"');
10183786Sksrini	}
10193786Sksrini      else
10203786Sksrini	{
10213786Sksrini	  expressionS expn;
10223595Sksrini
10233595Sksrini	  input_line_pointer = parse_expression (input_line_pointer, &expn);
10243625Sjlahoda	  if (expn.X_op == O_constant)
10253786Sksrini	    {
10263786Sksrini	      offsetT value = expn.X_add_number;
10273595Sksrini	      /* Truncate overflows.  */
10283595Sksrini	      switch (octets)
10293625Sjlahoda		{
10303786Sksrini		case 1:
10313786Sksrini		  if ((value > 0 && value > 0xFF)
10323595Sksrini		      || (value < 0 && value < - 0x100))
10333595Sksrini		    as_warn (_("Overflow in expression, truncated to 8 bits"));
10343595Sksrini		  break;
10353786Sksrini		case 2:
10363595Sksrini		  if ((value > 0 && value > 0xFFFF)
10373595Sksrini		      || (value < 0 && value < - 0x10000))
10383595Sksrini		    as_warn (_("Overflow in expression, truncated to 16 bits"));
10393595Sksrini		  break;
10403595Sksrini		}
10413595Sksrini	    }
10423595Sksrini	  if (expn.X_op != O_constant && octets < 2)
10433595Sksrini	    {
10443595Sksrini	      /* Disallow .byte with a non constant expression that will
10453625Sjlahoda		 require relocation.  */
10463595Sksrini	      as_bad (_("Relocatable values require at least WORD storage"));
10473595Sksrini	      ignore_rest_of_line ();
10483595Sksrini	      return;
10493595Sksrini	    }
10503595Sksrini
10513625Sjlahoda	  if (expn.X_op != O_constant
10523595Sksrini	      && amode == c_mode
10533595Sksrini	      && octets == 4)
10543595Sksrini	    {
10553595Sksrini	      /* FIXME -- at one point TI tools used to output REL16
10563595Sksrini		 relocations, but I don't think the latest tools do at all
10573625Sjlahoda		 The current tools output extended relocations regardless of
10583595Sksrini		 the addressing mode (I actually think that ".c_mode" is
10593595Sksrini		 totally ignored in the latest tools).  */
10603595Sksrini	      amode = far_mode;
10613595Sksrini	      emitting_long = 1;
10623786Sksrini	      emit_expr (&expn, 4);
10633595Sksrini	      emitting_long = 0;
10643595Sksrini	      amode = c_mode;
10653595Sksrini	    }
10663595Sksrini	  else
10673595Sksrini	    {
10683595Sksrini	      emitting_long = octets == 4;
10693595Sksrini	      emit_expr (&expn, (octets == 1) ? 2 : octets);
10703595Sksrini	      emitting_long = 0;
10713595Sksrini	    }
10723595Sksrini	}
10733595Sksrini    }
10743595Sksrini  while (*input_line_pointer++ == ',');
10753595Sksrini
10763595Sksrini  input_line_pointer--;		/* Put terminator back into stream.  */
10773595Sksrini  demand_empty_rest_of_line ();
10783595Sksrini}
10793595Sksrini
10803595Sksrini/* .global <symbol>[,...,<symbolN>]
10813595Sksrini   .def    <symbol>[,...,<symbolN>]
10823595Sksrini   .ref    <symbol>[,...,<symbolN>]
10833595Sksrini
10843595Sksrini   These all identify global symbols.
10853595Sksrini
10863625Sjlahoda   .def means the symbol is defined in the current module and can be accessed
10873595Sksrini   by other files.  The symbol should be placed in the symbol table.
10883595Sksrini
10893595Sksrini   .ref means the symbol is used in the current module but defined in another
10903786Sksrini   module.  The linker is to resolve this symbol's definition at link time.
10913595Sksrini
10923595Sksrini   .global should act as a .ref or .def, as needed.
10933595Sksrini
10943595Sksrini   global, def and ref all have symbol storage classes of C_EXT.
10953595Sksrini
10963595Sksrini   I can't identify any difference in how the "other" c54x assembler treats
10973595Sksrini   these, so we ignore the type here.  */
10983595Sksrini
10993595Sksrinivoid
11003595Sksrinitic54x_global (int type)
11013595Sksrini{
11023595Sksrini  char *name;
11033595Sksrini  int c;
11043625Sjlahoda  symbolS *symbolP;
11053595Sksrini
11063595Sksrini  if (type == 'r')
11073595Sksrini    as_warn (_("Use of .def/.ref is deprecated.  Use .global instead"));
11083595Sksrini
11093595Sksrini  ILLEGAL_WITHIN_STRUCT ();
11103595Sksrini
11113595Sksrini  do
11123595Sksrini    {
11133595Sksrini      name = input_line_pointer;
11143595Sksrini      c = get_symbol_end ();
11153595Sksrini      symbolP = symbol_find_or_make (name);
11163595Sksrini
11173595Sksrini      *input_line_pointer = c;
11183595Sksrini      S_SET_STORAGE_CLASS (symbolP, C_EXT);
11193595Sksrini      if (c == ',')
11203595Sksrini	{
11213595Sksrini	  input_line_pointer++;
11223595Sksrini	  if (is_end_of_line[(int) *input_line_pointer])
11233595Sksrini	    c = *input_line_pointer;
11243595Sksrini	}
11253595Sksrini    }
11263595Sksrini  while (c == ',');
11273595Sksrini
11283595Sksrini  demand_empty_rest_of_line ();
11293595Sksrini}
11303595Sksrini
11313595Sksrini/* Remove the symbol from the local label hash lookup.  */
11323595Sksrini
11333595Sksrinistatic void
11343595Sksrinitic54x_remove_local_label (const char *key, void *value ATTRIBUTE_UNUSED)
11353595Sksrini{
11363595Sksrini  void *elem = hash_delete (local_label_hash[macro_level], key, FALSE);
11373595Sksrini  free (elem);
11383595Sksrini}
11393595Sksrini
11403595Sksrini/* Reset all local labels.  */
11413595Sksrini
11423595Sksrinistatic void
11433595Sksrinitic54x_clear_local_labels (int ignored ATTRIBUTE_UNUSED)
11443595Sksrini{
11453595Sksrini  hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label);
11463595Sksrini}
11473595Sksrini
11483595Sksrini/* .text
11493595Sksrini   .data
11503595Sksrini   .sect "section name"
11513595Sksrini
11523595Sksrini   Initialized section
11533595Sksrini   make sure local labels get cleared when changing sections
11543595Sksrini
11553595Sksrini   ARG is 't' for text, 'd' for data, or '*' for a named section
11563595Sksrini
11573595Sksrini   For compatibility, '*' sections are SEC_CODE if instructions are
11583595Sksrini   encountered, or SEC_DATA if not.
11593595Sksrini*/
11603595Sksrini
11613595Sksrinistatic void
11623595Sksrinitic54x_sect (int arg)
11633595Sksrini{
11643595Sksrini  ILLEGAL_WITHIN_STRUCT ();
11653595Sksrini
11663595Sksrini  /* Local labels are cleared when changing sections.  */
11673595Sksrini  tic54x_clear_local_labels (0);
11683595Sksrini
11693595Sksrini  if (arg == 't')
11703595Sksrini    s_text (0);
11713595Sksrini  else if (arg == 'd')
11723595Sksrini    s_data (0);
11733595Sksrini  else
11743595Sksrini    {
11753595Sksrini      char *name = NULL;
11763595Sksrini      int len;
11773595Sksrini
11783595Sksrini      /* If there are quotes, remove them.  */
11793595Sksrini      if (*input_line_pointer == '"')
11803595Sksrini	{
11813595Sksrini	  name = demand_copy_C_string (&len);
11823595Sksrini	  demand_empty_rest_of_line ();
11833595Sksrini	  name = strcpy (xmalloc (len + 10), name);
11843595Sksrini	}
11853595Sksrini      else
11863595Sksrini	{
11873595Sksrini	  int c;
11883595Sksrini	  name = input_line_pointer;
11893595Sksrini	  c = get_symbol_end ();
11903595Sksrini          len = strlen(name);
11913595Sksrini	  name = strcpy (xmalloc (len + 10), name);
11923595Sksrini	  *input_line_pointer = c;
11933595Sksrini	  demand_empty_rest_of_line ();
11943595Sksrini	}
11953595Sksrini      /* Make sure all named initialized sections flagged properly.  If we
11963595Sksrini         encounter instructions, we'll flag it with SEC_CODE as well.  */
11973595Sksrini      strcat (name, ",\"w\"\n");
11983595Sksrini      input_scrub_insert_line (name);
11993595Sksrini      obj_coff_section (0);
12003595Sksrini
12013595Sksrini      /* If there was a line label, make sure that it gets assigned the proper
12023595Sksrini	 section.  This is for compatibility, even though the actual behavior
12033595Sksrini	 is not explicitly defined.  For consistency, we make .sect behave
12043595Sksrini	 like .usect, since that is probably what people expect.  */
12053595Sksrini      if (line_label != NULL)
12063595Sksrini	{
12073595Sksrini	  S_SET_SEGMENT (line_label, now_seg);
12083595Sksrini	  symbol_set_frag (line_label, frag_now);
12093595Sksrini	  S_SET_VALUE (line_label, frag_now_fix ());
12103595Sksrini	  if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
12113595Sksrini	    S_SET_STORAGE_CLASS (line_label, C_LABEL);
12123595Sksrini	}
12133595Sksrini    }
12143595Sksrini}
12153595Sksrini
12163595Sksrini/* [symbol] .space space_in_bits
12173595Sksrini   [symbol] .bes space_in_bits
12183595Sksrini   BES puts the symbol at the *last* word allocated
12193595Sksrini
12203595Sksrini   cribbed from s_space.  */
12213595Sksrini
12223595Sksrinistatic void
12233595Sksrinitic54x_space (int arg)
12243595Sksrini{
12253595Sksrini  expressionS expn;
12263595Sksrini  char *p = 0;
12273595Sksrini  int octets = 0;
12283595Sksrini  long words;
12293595Sksrini  int bits_per_byte = (OCTETS_PER_BYTE * 8);
12303595Sksrini  int bit_offset = 0;
12313595Sksrini  symbolS *label = line_label;
12323595Sksrini  int bes = arg;
12333595Sksrini
12343595Sksrini  ILLEGAL_WITHIN_STRUCT ();
12353595Sksrini
12363595Sksrini#ifdef md_flush_pending_output
12373595Sksrini  md_flush_pending_output ();
12383595Sksrini#endif
12393595Sksrini
12403595Sksrini  /* Read the bit count.  */
12413595Sksrini  expression (&expn);
12423595Sksrini
12433595Sksrini  /* Some expressions are unresolvable until later in the assembly pass;
12443595Sksrini     postpone until relaxation/fixup.  we also have to postpone if a previous
12453595Sksrini     partial allocation has not been completed yet.  */
12463595Sksrini  if (expn.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
12473595Sksrini    {
12483595Sksrini      struct bit_info *bi = xmalloc (sizeof (struct bit_info));
12493595Sksrini
12503595Sksrini      bi->seg = now_seg;
12513595Sksrini      bi->type = bes;
12523595Sksrini      bi->sym = label;
12533595Sksrini      p = frag_var (rs_machine_dependent,
12543595Sksrini		    65536 * 2, 1, (relax_substateT) 0,
12553595Sksrini		    make_expr_symbol (&expn), (offsetT) 0,
12563595Sksrini		    (char *) bi);
12573595Sksrini      if (p)
12583595Sksrini	*p = 0;
12593595Sksrini
12603595Sksrini      return;
12613595Sksrini    }
12623595Sksrini
12633595Sksrini  /* Reduce the required size by any bit offsets currently left over
12643595Sksrini     from a previous .space/.bes/.field directive.  */
12653595Sksrini  bit_offset = frag_now->tc_frag_data;
12663595Sksrini  if (bit_offset != 0 && bit_offset < 16)
12673595Sksrini    {
12683595Sksrini      int spare_bits = bits_per_byte - bit_offset;
12693595Sksrini
12703595Sksrini      if (spare_bits >= expn.X_add_number)
12713595Sksrini	{
12723595Sksrini	  /* Don't have to do anything; sufficient bits have already been
12733595Sksrini	     allocated; just point the label to the right place.  */
12743595Sksrini	  if (label != NULL)
12753595Sksrini	    {
12763595Sksrini	      symbol_set_frag (label, frag_now);
12773595Sksrini	      S_SET_VALUE (label, frag_now_fix () - 1);
12783595Sksrini	      label = NULL;
12793595Sksrini	    }
12803595Sksrini	  frag_now->tc_frag_data += expn.X_add_number;
12813595Sksrini	  goto getout;
12823595Sksrini	}
12833595Sksrini      expn.X_add_number -= spare_bits;
12843595Sksrini      /* Set the label to point to the first word allocated, which in this
12853595Sksrini	 case is the previous word, which was only partially filled.  */
12863595Sksrini      if (!bes && label != NULL)
12873595Sksrini	{
12883595Sksrini	  symbol_set_frag (label, frag_now);
12893595Sksrini	  S_SET_VALUE (label, frag_now_fix () - 1);
12903595Sksrini	  label = NULL;
12913595Sksrini	}
12923595Sksrini    }
12933595Sksrini  /* Convert bits to bytes/words and octets, rounding up.  */
12943595Sksrini  words = ((expn.X_add_number + bits_per_byte - 1) / bits_per_byte);
12953595Sksrini  /* How many do we have left over?  */
12963595Sksrini  bit_offset = expn.X_add_number % bits_per_byte;
12973595Sksrini  octets = words * OCTETS_PER_BYTE;
12983595Sksrini  if (octets < 0)
12993595Sksrini    {
1300      as_warn (_(".space/.bes repeat count is negative, ignored"));
1301      goto getout;
1302    }
1303  else if (octets == 0)
1304    {
1305      as_warn (_(".space/.bes repeat count is zero, ignored"));
1306      goto getout;
1307    }
1308
1309  /* If we are in the absolute section, just bump the offset.  */
1310  if (now_seg == absolute_section)
1311    {
1312      abs_section_offset += words;
1313      if (bes && label != NULL)
1314	S_SET_VALUE (label, abs_section_offset - 1);
1315      frag_now->tc_frag_data = bit_offset;
1316      goto getout;
1317    }
1318
1319  if (!need_pass_2)
1320    p = frag_var (rs_fill, 1, 1,
1321		  (relax_substateT) 0, (symbolS *) 0,
1322		  (offsetT) octets, (char *) 0);
1323
1324  /* Make note of how many bits of this word we've allocated so far.  */
1325  frag_now->tc_frag_data = bit_offset;
1326
1327  /* .bes puts label at *last* word allocated.  */
1328  if (bes && label != NULL)
1329    {
1330      symbol_set_frag (label, frag_now);
1331      S_SET_VALUE (label, frag_now_fix () - 1);
1332    }
1333
1334  if (p)
1335    *p = 0;
1336
1337 getout:
1338
1339  demand_empty_rest_of_line ();
1340}
1341
1342/* [symbol] .usect "section-name", size-in-words
1343		   [, [blocking-flag] [, alignment-flag]]
1344
1345   Uninitialized section.
1346   Non-zero blocking means that if the section would cross a page (128-word)
1347   boundary, it will be page-aligned.
1348   Non-zero alignment aligns on a longword boundary.
1349
1350   Has no effect on the current section.  */
1351
1352static void
1353tic54x_usect (int x ATTRIBUTE_UNUSED)
1354{
1355  char c;
1356  char *name;
1357  char *section_name;
1358  char *p;
1359  segT seg;
1360  int size, blocking_flag, alignment_flag;
1361  segT current_seg;
1362  subsegT current_subseg;
1363  flagword flags;
1364
1365  ILLEGAL_WITHIN_STRUCT ();
1366
1367  current_seg = now_seg;	/* Save current seg.  */
1368  current_subseg = now_subseg;	/* Save current subseg.  */
1369
1370  if (*input_line_pointer == '"')
1371    input_line_pointer++;
1372  section_name = input_line_pointer;
1373  c = get_symbol_end ();	/* Get terminator.  */
1374  input_line_pointer++;		/* Skip null symbol terminator.  */
1375  name = xmalloc (input_line_pointer - section_name + 1);
1376  strcpy (name, section_name);
1377
1378  if (*input_line_pointer == ',')
1379    ++input_line_pointer;
1380  else if (c != ',')
1381    {
1382      as_bad (_("Missing size argument"));
1383      ignore_rest_of_line ();
1384      return;
1385    }
1386
1387  size = get_absolute_expression ();
1388
1389  /* Read a possibly present third argument (blocking flag).  */
1390  if (*input_line_pointer == ',')
1391    {
1392      ++input_line_pointer;
1393      if (*input_line_pointer != ',')
1394	blocking_flag = get_absolute_expression ();
1395      else
1396	blocking_flag = 0;
1397
1398      /* Read a possibly present fourth argument (alignment flag).  */
1399      if (*input_line_pointer == ',')
1400	{
1401	  ++input_line_pointer;
1402	  alignment_flag = get_absolute_expression ();
1403	}
1404      else
1405	alignment_flag = 0;
1406    }
1407  else
1408    blocking_flag = alignment_flag = 0;
1409
1410  seg = subseg_new (name, 0);
1411  flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC;
1412
1413  if (alignment_flag)
1414    {
1415      /* s_align eats end of line; restore it.  */
1416      s_align_bytes (4);
1417      --input_line_pointer;
1418    }
1419
1420  if (line_label != NULL)
1421    {
1422      S_SET_SEGMENT (line_label, seg);
1423      symbol_set_frag (line_label, frag_now);
1424      S_SET_VALUE (line_label, frag_now_fix ());
1425      /* Set scl to label, since that's what TI does.  */
1426      if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1427	S_SET_STORAGE_CLASS (line_label, C_LABEL);
1428    }
1429
1430  seg_info (seg)->bss = 1;	/* Uninitialized data.  */
1431
1432  p = frag_var (rs_fill, 1, 1,
1433		(relax_substateT) 0, (symbolS *) line_label,
1434		size * OCTETS_PER_BYTE, (char *) 0);
1435  *p = 0;
1436
1437  if (blocking_flag)
1438    flags |= SEC_TIC54X_BLOCK;
1439
1440  if (!bfd_set_section_flags (stdoutput, seg, flags))
1441    as_warn (_("Error setting flags for \"%s\": %s"), name,
1442	     bfd_errmsg (bfd_get_error ()));
1443
1444  subseg_set (current_seg, current_subseg);	/* Restore current seg.  */
1445  demand_empty_rest_of_line ();
1446}
1447
1448static enum cpu_version
1449lookup_version (const char *ver)
1450{
1451  enum cpu_version version = VNONE;
1452
1453  if (ver[0] == '5' && ver[1] == '4')
1454    {
1455      if (strlen (ver) == 3
1456	  && (ver[2] == '1' || ver[2] == '2' || ver[2] == '3'
1457	      || ver[2] == '5' || ver[2] == '8' || ver[2] == '9'))
1458	version = ver[2] - '0';
1459      else if (strlen (ver) == 5
1460	       && TOUPPER (ver[3]) == 'L'
1461	       && TOUPPER (ver[4]) == 'P'
1462	       && (ver[2] == '5' || ver[2] == '6'))
1463	version = ver[2] - '0' + 10;
1464    }
1465
1466  return version;
1467}
1468
1469static void
1470set_cpu (enum cpu_version version)
1471{
1472  cpu = version;
1473  if (version == V545LP || version == V546LP)
1474    {
1475      symbolS *symbolP = symbol_new ("__allow_lp", absolute_section,
1476				     (valueT) 1, &zero_address_frag);
1477      SF_SET_LOCAL (symbolP);
1478      symbol_table_insert (symbolP);
1479    }
1480}
1481
1482/* .version cpu-version
1483   cpu-version may be one of the following:
1484   541
1485   542
1486   543
1487   545
1488   545LP
1489   546LP
1490   548
1491   549
1492
1493   This is for compatibility only.  It currently has no affect on assembly.  */
1494static int cpu_needs_set = 1;
1495
1496static void
1497tic54x_version (int x ATTRIBUTE_UNUSED)
1498{
1499  enum cpu_version version = VNONE;
1500  enum cpu_version old_version = cpu;
1501  int c;
1502  char *ver;
1503
1504  ILLEGAL_WITHIN_STRUCT ();
1505
1506  SKIP_WHITESPACE ();
1507  ver = input_line_pointer;
1508  while (!is_end_of_line[(int) *input_line_pointer])
1509    ++input_line_pointer;
1510  c = *input_line_pointer;
1511  *input_line_pointer = 0;
1512
1513  version = lookup_version (ver);
1514
1515  if (cpu != VNONE && cpu != version)
1516    as_warn (_("CPU version has already been set"));
1517
1518  if (version == VNONE)
1519    {
1520      as_bad (_("Unrecognized version '%s'"), ver);
1521      ignore_rest_of_line ();
1522      return;
1523    }
1524  else if (assembly_begun && version != old_version)
1525    {
1526      as_bad (_("Changing of CPU version on the fly not supported"));
1527      ignore_rest_of_line ();
1528      return;
1529    }
1530
1531  set_cpu (version);
1532
1533  *input_line_pointer = c;
1534  demand_empty_rest_of_line ();
1535}
1536
1537/* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble.  */
1538
1539static void
1540tic54x_float_cons (int type)
1541{
1542  if (current_stag != 0)
1543    tic54x_struct_field ('f');
1544
1545#ifdef md_flush_pending_output
1546  md_flush_pending_output ();
1547#endif
1548
1549  /* Align to long word boundary (4 octets) unless it's ".xfloat".  */
1550  if (type != 'x')
1551    {
1552      frag_align (2, 0, 2);
1553      /* If there's a label, assign it to the first allocated word.  */
1554      if (line_label != NULL)
1555	{
1556	  symbol_set_frag (line_label, frag_now);
1557	  S_SET_VALUE (line_label, frag_now_fix ());
1558	}
1559    }
1560
1561  float_cons ('f');
1562}
1563
1564/* The argument is capitalized if it should be zero-terminated
1565   's' is normal string with upper 8-bits zero-filled, 'p' is packed.
1566   Code copied from stringer, and slightly modified so that strings are packed
1567   and encoded into the correct octets.  */
1568
1569static void
1570tic54x_stringer (int type)
1571{
1572  unsigned int c;
1573  int append_zero = type == 'S' || type == 'P';
1574  int packed = type == 'p' || type == 'P';
1575  int last_char = -1; /* Packed strings need two bytes at a time to encode.  */
1576
1577  if (current_stag != NULL)
1578    {
1579      tic54x_struct_field ('*');
1580      return;
1581    }
1582
1583#ifdef md_flush_pending_output
1584  md_flush_pending_output ();
1585#endif
1586
1587  c = ',';			/* Do loop.  */
1588  while (c == ',')
1589    {
1590      SKIP_WHITESPACE ();
1591      switch (*input_line_pointer)
1592	{
1593	default:
1594	  {
1595	    unsigned short value = get_absolute_expression ();
1596	    FRAG_APPEND_1_CHAR ( value       & 0xFF);
1597	    FRAG_APPEND_1_CHAR ((value >> 8) & 0xFF);
1598	    break;
1599	  }
1600	case '\"':
1601	  ++input_line_pointer;	/* -> 1st char of string.  */
1602	  while (is_a_char (c = next_char_of_string ()))
1603	    {
1604	      if (!packed)
1605		{
1606		  FRAG_APPEND_1_CHAR (c);
1607		  FRAG_APPEND_1_CHAR (0);
1608		}
1609	      else
1610		{
1611		  /* Packed strings are filled MS octet first.  */
1612		  if (last_char == -1)
1613		    last_char = c;
1614		  else
1615		    {
1616		      FRAG_APPEND_1_CHAR (c);
1617		      FRAG_APPEND_1_CHAR (last_char);
1618		      last_char = -1;
1619		    }
1620		}
1621	    }
1622	  if (append_zero)
1623	    {
1624	      if (packed && last_char != -1)
1625		{
1626		  FRAG_APPEND_1_CHAR (0);
1627		  FRAG_APPEND_1_CHAR (last_char);
1628		  last_char = -1;
1629		}
1630	      else
1631		{
1632		  FRAG_APPEND_1_CHAR (0);
1633		  FRAG_APPEND_1_CHAR (0);
1634		}
1635	    }
1636	  know (input_line_pointer[-1] == '\"');
1637	  break;
1638	}
1639      SKIP_WHITESPACE ();
1640      c = *input_line_pointer;
1641      if (!is_end_of_line[c])
1642	++input_line_pointer;
1643    }
1644
1645  /* Finish up any leftover packed string.  */
1646  if (packed && last_char != -1)
1647    {
1648      FRAG_APPEND_1_CHAR (0);
1649      FRAG_APPEND_1_CHAR (last_char);
1650    }
1651  demand_empty_rest_of_line ();
1652}
1653
1654static void
1655tic54x_p2align (int arg ATTRIBUTE_UNUSED)
1656{
1657  as_bad (_("p2align not supported on this target"));
1658}
1659
1660static void
1661tic54x_align_words (int arg)
1662{
1663  /* Only ".align" with no argument is allowed within .struct/.union.  */
1664  int count = arg;
1665
1666  if (!is_end_of_line[(int) *input_line_pointer])
1667    {
1668      if (arg == 2)
1669	as_warn (_("Argument to .even ignored"));
1670      else
1671	count = get_absolute_expression ();
1672    }
1673
1674  if (current_stag != NULL && arg == 128)
1675    {
1676      if (current_stag->current_bitfield_offset != 0)
1677	{
1678	  current_stag->current_bitfield_offset = 0;
1679	  ++abs_section_offset;
1680	}
1681      demand_empty_rest_of_line ();
1682      return;
1683    }
1684
1685  ILLEGAL_WITHIN_STRUCT ();
1686
1687  s_align_bytes (count << 1);
1688}
1689
1690/* Initialize multiple-bit fields withing a single word of memory.  */
1691
1692static void
1693tic54x_field (int ignore ATTRIBUTE_UNUSED)
1694{
1695  expressionS expn;
1696  int size = 16;
1697  char *p;
1698  valueT value;
1699  symbolS *label = line_label;
1700
1701  if (current_stag != NULL)
1702    {
1703      tic54x_struct_field ('.');
1704      return;
1705    }
1706
1707  input_line_pointer = parse_expression (input_line_pointer, &expn);
1708
1709  if (*input_line_pointer == ',')
1710    {
1711      ++input_line_pointer;
1712      size = get_absolute_expression ();
1713      if (size < 1 || size > 32)
1714	{
1715	  as_bad (_("Invalid field size, must be from 1 to 32"));
1716	  ignore_rest_of_line ();
1717	  return;
1718	}
1719    }
1720
1721  /* Truncate values to the field width.  */
1722  if (expn.X_op != O_constant)
1723    {
1724      /* If the expression value is relocatable, the field size *must*
1725         be 16.  */
1726      if (size != 16)
1727	{
1728	  as_bad (_("field size must be 16 when value is relocatable"));
1729	  ignore_rest_of_line ();
1730	  return;
1731	}
1732
1733      frag_now->tc_frag_data = 0;
1734      emit_expr (&expn, 2);
1735    }
1736  else
1737    {
1738      unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1;
1739
1740      value = expn.X_add_number;
1741      expn.X_add_number &= fmask;
1742      if (value != (valueT) expn.X_add_number)
1743	as_warn (_("field value truncated"));
1744      value = expn.X_add_number;
1745      /* Bits are stored MS first.  */
1746      while (size >= 16)
1747	{
1748	  frag_now->tc_frag_data = 0;
1749	  p = frag_more (2);
1750	  md_number_to_chars (p, (value >> (size - 16)) & 0xFFFF, 2);
1751	  size -= 16;
1752	}
1753      if (size > 0)
1754	{
1755	  int bit_offset = frag_bit_offset (frag_now, now_seg);
1756
1757	  fragS *alloc_frag = bit_offset_frag (frag_now, now_seg);
1758	  if (bit_offset == -1)
1759	    {
1760	      struct bit_info *bi = xmalloc (sizeof (struct bit_info));
1761	      /* We don't know the previous offset at this time, so store the
1762		 info we need and figure it out later.  */
1763	      expressionS size_exp;
1764
1765	      size_exp.X_op = O_constant;
1766	      size_exp.X_add_number = size;
1767	      bi->seg = now_seg;
1768	      bi->type = TYPE_FIELD;
1769	      bi->value = value;
1770	      p = frag_var (rs_machine_dependent,
1771			    4, 1, (relax_substateT) 0,
1772			    make_expr_symbol (&size_exp), (offsetT) 0,
1773			    (char *) bi);
1774	      goto getout;
1775	    }
1776	  else if (bit_offset == 0 || bit_offset + size > 16)
1777	    {
1778	      /* Align a new field.  */
1779	      p = frag_more (2);
1780	      frag_now->tc_frag_data = 0;
1781	      alloc_frag = frag_now;
1782	    }
1783	  else
1784	    {
1785	      /* Put the new value entirely within the existing one.  */
1786	      p = alloc_frag == frag_now ?
1787		frag_now->fr_literal + frag_now_fix_octets () - 2 :
1788		alloc_frag->fr_literal;
1789	      if (label != NULL)
1790		{
1791		  symbol_set_frag (label, alloc_frag);
1792		  if (alloc_frag == frag_now)
1793		    S_SET_VALUE (label, frag_now_fix () - 1);
1794		  label = NULL;
1795		}
1796	    }
1797	  value <<= 16 - alloc_frag->tc_frag_data - size;
1798
1799	  /* OR in existing value.  */
1800	  if (alloc_frag->tc_frag_data)
1801	    value |= ((unsigned short) p[1] << 8) | p[0];
1802	  md_number_to_chars (p, value, 2);
1803	  alloc_frag->tc_frag_data += size;
1804	  if (alloc_frag->tc_frag_data == 16)
1805	    alloc_frag->tc_frag_data = 0;
1806	}
1807    }
1808 getout:
1809  demand_empty_rest_of_line ();
1810}
1811
1812/* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
1813   available yet.  seg_info ()->bss is the next best thing.  */
1814
1815static int
1816tic54x_initialized_section (segT seg)
1817{
1818  return !seg_info (seg)->bss;
1819}
1820
1821/* .clink ["section name"]
1822
1823   Marks the section as conditionally linked (link only if contents are
1824   referenced elsewhere.
1825   Without a name, refers to the current initialized section.
1826   Name is required for uninitialized sections.  */
1827
1828static void
1829tic54x_clink (int ignored ATTRIBUTE_UNUSED)
1830{
1831  segT seg = now_seg;
1832
1833  ILLEGAL_WITHIN_STRUCT ();
1834
1835  if (*input_line_pointer == '\"')
1836    {
1837      char *section_name = ++input_line_pointer;
1838      char *name;
1839
1840      while (is_a_char (next_char_of_string ()))
1841	;
1842      know (input_line_pointer[-1] == '\"');
1843      input_line_pointer[-1] = 0;
1844      name = xmalloc (input_line_pointer - section_name + 1);
1845      strcpy (name, section_name);
1846
1847      seg = bfd_get_section_by_name (stdoutput, name);
1848      if (seg == NULL)
1849	{
1850	  as_bad (_("Unrecognized section '%s'"), section_name);
1851	  ignore_rest_of_line ();
1852	  return;
1853	}
1854    }
1855  else
1856    {
1857      if (!tic54x_initialized_section (seg))
1858	{
1859	  as_bad (_("Current section is unitialized, "
1860		    "section name required for .clink"));
1861	  ignore_rest_of_line ();
1862	  return;
1863	}
1864    }
1865
1866  seg->flags |= SEC_TIC54X_CLINK;
1867
1868  demand_empty_rest_of_line ();
1869}
1870
1871/* Change the default include directory to be the current source file's
1872   directory, instead of the current working directory.  If DOT is non-zero,
1873   set to "." instead.  */
1874
1875static void
1876tic54x_set_default_include (int dot)
1877{
1878  char *dir = ".";
1879  char *tmp = NULL;
1880
1881  if (!dot)
1882    {
1883      char *curfile;
1884      unsigned lineno;
1885
1886      as_where (&curfile, &lineno);
1887      dir = strcpy (xmalloc (strlen (curfile) + 1), curfile);
1888      tmp = strrchr (dir, '/');
1889    }
1890  if (tmp != NULL)
1891    {
1892      int len;
1893
1894      *tmp = '\0';
1895      len = strlen (dir);
1896      if (include_dir_count == 0)
1897	{
1898	  include_dirs = (char **) xmalloc (sizeof (*include_dirs));
1899	  include_dir_count = 1;
1900	}
1901      include_dirs[0] = dir;
1902      if (len > include_dir_maxlen)
1903	include_dir_maxlen = len;
1904    }
1905  else if (include_dirs != NULL)
1906    include_dirs[0] = ".";
1907}
1908
1909/* .include "filename" | filename
1910   .copy    "filename" | filename
1911
1912   FIXME 'include' file should be omitted from any output listing,
1913     'copy' should be included in any output listing
1914   FIXME -- prevent any included files from changing listing (compat only)
1915   FIXME -- need to include source file directory in search path; what's a
1916      good way to do this?
1917
1918   Entering/exiting included/copied file clears all local labels.  */
1919
1920static void
1921tic54x_include (int ignored ATTRIBUTE_UNUSED)
1922{
1923  char newblock[] = " .newblock\n";
1924  char *filename;
1925  char *input;
1926  int len, c = -1;
1927
1928  ILLEGAL_WITHIN_STRUCT ();
1929
1930  SKIP_WHITESPACE ();
1931
1932  if (*input_line_pointer == '"')
1933    {
1934      filename = demand_copy_C_string (&len);
1935      demand_empty_rest_of_line ();
1936    }
1937  else
1938    {
1939      filename = input_line_pointer;
1940      while (!is_end_of_line[(int) *input_line_pointer])
1941	++input_line_pointer;
1942      c = *input_line_pointer;
1943      *input_line_pointer = '\0';
1944      filename = strcpy (xmalloc (strlen (filename) + 1), filename);
1945      *input_line_pointer = c;
1946      demand_empty_rest_of_line ();
1947    }
1948  /* Insert a partial line with the filename (for the sake of s_include)
1949     and a .newblock.
1950     The included file will be inserted before the newblock, so that the
1951     newblock is executed after the included file is processed.  */
1952  input = xmalloc (sizeof (newblock) + strlen (filename) + 4);
1953  sprintf (input, "\"%s\"\n%s", filename, newblock);
1954  input_scrub_insert_line (input);
1955
1956  tic54x_clear_local_labels (0);
1957
1958  tic54x_set_default_include (0);
1959
1960  s_include (0);
1961}
1962
1963static void
1964tic54x_message (int type)
1965{
1966  char *msg;
1967  char c;
1968  int len;
1969
1970  ILLEGAL_WITHIN_STRUCT ();
1971
1972  if (*input_line_pointer == '"')
1973    msg = demand_copy_C_string (&len);
1974  else
1975    {
1976      msg = input_line_pointer;
1977      while (!is_end_of_line[(int) *input_line_pointer])
1978	++input_line_pointer;
1979      c = *input_line_pointer;
1980      *input_line_pointer = 0;
1981      msg = strcpy (xmalloc (strlen (msg) + 1), msg);
1982      *input_line_pointer = c;
1983    }
1984
1985  switch (type)
1986    {
1987    case 'm':
1988      as_tsktsk ("%s", msg);
1989      break;
1990    case 'w':
1991      as_warn ("%s", msg);
1992      break;
1993    case 'e':
1994      as_bad ("%s", msg);
1995      break;
1996    }
1997
1998  demand_empty_rest_of_line ();
1999}
2000
2001/* .label <symbol>
2002   Define a special symbol that refers to the loadtime address rather than the
2003   runtime address within the current section.
2004
2005   This symbol gets a special storage class so that when it is resolved, it is
2006   resolved relative to the load address (lma) of the section rather than the
2007   run address (vma).  */
2008
2009static void
2010tic54x_label (int ignored ATTRIBUTE_UNUSED)
2011{
2012  char *name = input_line_pointer;
2013  symbolS *symbolP;
2014  int c;
2015
2016  ILLEGAL_WITHIN_STRUCT ();
2017
2018  c = get_symbol_end ();
2019  symbolP = colon (name);
2020  S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
2021
2022  *input_line_pointer = c;
2023  demand_empty_rest_of_line ();
2024}
2025
2026/* .mmregs
2027   Install all memory-mapped register names into the symbol table as
2028   absolute local symbols.  */
2029
2030static void
2031tic54x_mmregs (int ignored ATTRIBUTE_UNUSED)
2032{
2033  symbol *sym;
2034
2035  ILLEGAL_WITHIN_STRUCT ();
2036
2037  for (sym = (symbol *) mmregs; sym->name; sym++)
2038    {
2039      symbolS *symbolP = symbol_new (sym->name, absolute_section,
2040				     (valueT) sym->value, &zero_address_frag);
2041      SF_SET_LOCAL (symbolP);
2042      symbol_table_insert (symbolP);
2043    }
2044}
2045
2046/* .loop [count]
2047   Count defaults to 1024.  */
2048
2049static void
2050tic54x_loop (int count)
2051{
2052  ILLEGAL_WITHIN_STRUCT ();
2053
2054  SKIP_WHITESPACE ();
2055  if (!is_end_of_line[(int) *input_line_pointer])
2056    count = get_absolute_expression ();
2057
2058  do_repeat (count, "LOOP", "ENDLOOP");
2059}
2060
2061/* Normally, endloop gets eaten by the preceding loop.  */
2062
2063static void
2064tic54x_endloop (int ignore ATTRIBUTE_UNUSED)
2065{
2066  as_bad (_("ENDLOOP without corresponding LOOP"));
2067  ignore_rest_of_line ();
2068}
2069
2070/* .break [condition].  */
2071
2072static void
2073tic54x_break (int ignore ATTRIBUTE_UNUSED)
2074{
2075  int cond = 1;
2076
2077  ILLEGAL_WITHIN_STRUCT ();
2078
2079  SKIP_WHITESPACE ();
2080  if (!is_end_of_line[(int) *input_line_pointer])
2081    cond = get_absolute_expression ();
2082
2083  if (cond)
2084    end_repeat (substitution_line ? 1 : 0);
2085}
2086
2087static void
2088set_address_mode (int mode)
2089{
2090  amode = mode;
2091  if (mode == far_mode)
2092    {
2093      symbolS *symbolP = symbol_new ("__allow_far", absolute_section,
2094				     (valueT) 1, &zero_address_frag);
2095      SF_SET_LOCAL (symbolP);
2096      symbol_table_insert (symbolP);
2097    }
2098}
2099
2100static int address_mode_needs_set = 1;
2101
2102static void
2103tic54x_address_mode (int mode)
2104{
2105  if (assembly_begun && amode != (unsigned) mode)
2106    {
2107      as_bad (_("Mixing of normal and extended addressing not supported"));
2108      ignore_rest_of_line ();
2109      return;
2110    }
2111  if (mode == far_mode && cpu != VNONE && cpu != V548 && cpu != V549)
2112    {
2113      as_bad (_("Extended addressing not supported on the specified CPU"));
2114      ignore_rest_of_line ();
2115      return;
2116    }
2117
2118  set_address_mode (mode);
2119  demand_empty_rest_of_line ();
2120}
2121
2122/* .sblock "section"|section [,...,"section"|section]
2123   Designate initialized sections for blocking.  */
2124
2125static void
2126tic54x_sblock (int ignore ATTRIBUTE_UNUSED)
2127{
2128  int c = ',';
2129
2130  ILLEGAL_WITHIN_STRUCT ();
2131
2132  while (c == ',')
2133    {
2134      segT seg;
2135      char *name;
2136
2137      if (*input_line_pointer == '"')
2138	{
2139	  int len;
2140
2141	  name = demand_copy_C_string (&len);
2142	}
2143      else
2144	{
2145	  char *section_name = input_line_pointer;
2146
2147	  c = get_symbol_end ();
2148	  name = xmalloc (strlen (section_name) + 1);
2149	  strcpy (name, section_name);
2150	  *input_line_pointer = c;
2151	}
2152
2153      seg = bfd_get_section_by_name (stdoutput, name);
2154      if (seg == NULL)
2155	{
2156	  as_bad (_("Unrecognized section '%s'"), name);
2157	  ignore_rest_of_line ();
2158	  return;
2159	}
2160      else if (!tic54x_initialized_section (seg))
2161	{
2162	  as_bad (_(".sblock may be used for initialized sections only"));
2163	  ignore_rest_of_line ();
2164	  return;
2165	}
2166      seg->flags |= SEC_TIC54X_BLOCK;
2167
2168      c = *input_line_pointer;
2169      if (!is_end_of_line[(int) c])
2170	++input_line_pointer;
2171    }
2172
2173  demand_empty_rest_of_line ();
2174}
2175
2176/* symbol .set value
2177   symbol .equ value
2178
2179   value must be defined externals; no forward-referencing allowed
2180   symbols assigned with .set/.equ may not be redefined.  */
2181
2182static void
2183tic54x_set (int ignore ATTRIBUTE_UNUSED)
2184{
2185  symbolS *symbolP;
2186  char *name;
2187
2188  ILLEGAL_WITHIN_STRUCT ();
2189
2190  if (!line_label)
2191    {
2192      as_bad (_("Symbol missing for .set/.equ"));
2193      ignore_rest_of_line ();
2194      return;
2195    }
2196  name = xstrdup (S_GET_NAME (line_label));
2197  line_label = NULL;
2198  if ((symbolP = symbol_find (name)) == NULL
2199      && (symbolP = md_undefined_symbol (name)) == NULL)
2200    {
2201      symbolP = symbol_new (name, absolute_section, 0, &zero_address_frag);
2202      S_SET_STORAGE_CLASS (symbolP, C_STAT);
2203    }
2204  free (name);
2205  S_SET_DATA_TYPE (symbolP, T_INT);
2206  S_SET_SEGMENT (symbolP, absolute_section);
2207  symbol_table_insert (symbolP);
2208  pseudo_set (symbolP);
2209  demand_empty_rest_of_line ();
2210}
2211
2212/* .fclist
2213   .fcnolist
2214   List false conditional blocks.  */
2215
2216static void
2217tic54x_fclist (int show)
2218{
2219  if (show)
2220    listing &= ~LISTING_NOCOND;
2221  else
2222    listing |= LISTING_NOCOND;
2223  demand_empty_rest_of_line ();
2224}
2225
2226static void
2227tic54x_sslist (int show)
2228{
2229  ILLEGAL_WITHIN_STRUCT ();
2230
2231  listing_sslist = show;
2232}
2233
2234/* .var SYM[,...,SYMN]
2235   Define a substitution string to be local to a macro.  */
2236
2237static void
2238tic54x_var (int ignore ATTRIBUTE_UNUSED)
2239{
2240  static char empty[] = "";
2241  char *name;
2242  int c;
2243
2244  ILLEGAL_WITHIN_STRUCT ();
2245
2246  if (macro_level == 0)
2247    {
2248      as_bad (_(".var may only be used within a macro definition"));
2249      ignore_rest_of_line ();
2250      return;
2251    }
2252  do
2253    {
2254      if (!ISALPHA (*input_line_pointer))
2255	{
2256	  as_bad (_("Substitution symbols must begin with a letter"));
2257	  ignore_rest_of_line ();
2258	  return;
2259	}
2260      name = input_line_pointer;
2261      c = get_symbol_end ();
2262      /* .var symbols start out with a null string.  */
2263      name = strcpy (xmalloc (strlen (name) + 1), name);
2264      hash_insert (subsym_hash[macro_level], name, empty);
2265      *input_line_pointer = c;
2266      if (c == ',')
2267	{
2268	  ++input_line_pointer;
2269	  if (is_end_of_line[(int) *input_line_pointer])
2270	    c = *input_line_pointer;
2271	}
2272    }
2273  while (c == ',');
2274
2275  demand_empty_rest_of_line ();
2276}
2277
2278/* .mlib <macro library filename>
2279
2280   Macro libraries are archived (standard AR-format) text macro definitions
2281   Expand the file and include it.
2282
2283   FIXME need to try the source file directory as well.  */
2284
2285static void
2286tic54x_mlib (int ignore ATTRIBUTE_UNUSED)
2287{
2288  char *filename;
2289  char *path;
2290  int len, i;
2291  bfd *abfd, *mbfd;
2292
2293  ILLEGAL_WITHIN_STRUCT ();
2294
2295  /* Parse the filename.  */
2296  if (*input_line_pointer == '"')
2297    {
2298      if ((filename = demand_copy_C_string (&len)) == NULL)
2299	return;
2300    }
2301  else
2302    {
2303      SKIP_WHITESPACE ();
2304      len = 0;
2305      while (!is_end_of_line[(int) *input_line_pointer]
2306	     && !ISSPACE (*input_line_pointer))
2307	{
2308	  obstack_1grow (&notes, *input_line_pointer);
2309	  ++input_line_pointer;
2310	  ++len;
2311	}
2312      obstack_1grow (&notes, '\0');
2313      filename = obstack_finish (&notes);
2314    }
2315  demand_empty_rest_of_line ();
2316
2317  tic54x_set_default_include (0);
2318  path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
2319
2320  for (i = 0; i < include_dir_count; i++)
2321    {
2322      FILE *try;
2323
2324      strcpy (path, include_dirs[i]);
2325      strcat (path, "/");
2326      strcat (path, filename);
2327      if ((try = fopen (path, "r")) != NULL)
2328	{
2329	  fclose (try);
2330	  break;
2331	}
2332    }
2333
2334  if (i >= include_dir_count)
2335    {
2336      free (path);
2337      path = filename;
2338    }
2339
2340  /* FIXME: if path is found, malloc'd storage is not freed.  Of course, this
2341     happens all over the place, and since the assembler doesn't usually keep
2342     running for a very long time, it really doesn't matter.  */
2343  register_dependency (path);
2344
2345  /* Expand all archive entries to temporary files and include them.  */
2346  abfd = bfd_openr (path, NULL);
2347  if (!abfd)
2348    {
2349      as_bad (_("can't open macro library file '%s' for reading: %s"),
2350	      path, bfd_errmsg (bfd_get_error ()));
2351      ignore_rest_of_line ();
2352      return;
2353    }
2354  if (!bfd_check_format (abfd, bfd_archive))
2355    {
2356      as_bad (_("File '%s' not in macro archive format"), path);
2357      ignore_rest_of_line ();
2358      return;
2359    }
2360
2361  /* Open each BFD as binary (it should be straight ASCII text).  */
2362  for (mbfd = bfd_openr_next_archived_file (abfd, NULL);
2363       mbfd != NULL; mbfd = bfd_openr_next_archived_file (abfd, mbfd))
2364    {
2365      /* Get a size at least as big as the archive member.  */
2366      bfd_size_type size = bfd_get_size (mbfd);
2367      char *buf = xmalloc (size);
2368      char *fname = tmpnam (NULL);
2369      FILE *ftmp;
2370
2371      /* We're not sure how big it is, but it will be smaller than "size".  */
2372      bfd_bread (buf, size, mbfd);
2373
2374      /* Write to a temporary file, then use s_include to include it
2375	 a bit of a hack.  */
2376      ftmp = fopen (fname, "w+b");
2377      fwrite ((void *) buf, size, 1, ftmp);
2378      if (buf[size - 1] != '\n')
2379	fwrite ("\n", 1, 1, ftmp);
2380      fclose (ftmp);
2381      free (buf);
2382      input_scrub_insert_file (fname);
2383      unlink (fname);
2384    }
2385}
2386
2387const pseudo_typeS md_pseudo_table[] =
2388{
2389  { "algebraic", s_ignore                 ,          0 },
2390  { "align"    , tic54x_align_words       ,        128 },
2391  { "ascii"    , tic54x_stringer          ,        'p' },
2392  { "asciz"    , tic54x_stringer          ,        'P' },
2393  { "even"     , tic54x_align_words       ,          2 },
2394  { "asg"      , tic54x_asg               ,          0 },
2395  { "eval"     , tic54x_eval              ,          0 },
2396  { "bss"      , tic54x_bss               ,          0 },
2397  { "byte"     , tic54x_cons              ,        'b' },
2398  { "ubyte"    , tic54x_cons              ,        'B' },
2399  { "char"     , tic54x_cons              ,        'c' },
2400  { "uchar"    , tic54x_cons              ,        'C' },
2401  { "clink"    , tic54x_clink             ,          0 },
2402  { "c_mode"   , tic54x_address_mode      ,     c_mode },
2403  { "copy"     , tic54x_include           ,        'c' },
2404  { "include"  , tic54x_include           ,        'i' },
2405  { "data"     , tic54x_sect              ,        'd' },
2406  { "double"   , tic54x_float_cons        ,        'd' },
2407  { "ldouble"  , tic54x_float_cons        ,        'l' },
2408  { "drlist"   , s_ignore                 ,          0 },
2409  { "drnolist" , s_ignore                 ,          0 },
2410  { "emsg"     , tic54x_message           ,        'e' },
2411  { "mmsg"     , tic54x_message           ,        'm' },
2412  { "wmsg"     , tic54x_message           ,        'w' },
2413  { "far_mode" , tic54x_address_mode      ,   far_mode },
2414  { "fclist"   , tic54x_fclist            ,          1 },
2415  { "fcnolist" , tic54x_fclist            ,          0 },
2416  { "field"    , tic54x_field             ,         -1 },
2417  { "float"    , tic54x_float_cons        ,        'f' },
2418  { "xfloat"   , tic54x_float_cons        ,        'x' },
2419  { "global"   , tic54x_global            ,        'g' },
2420  { "def"      , tic54x_global            ,        'd' },
2421  { "ref"      , tic54x_global            ,        'r' },
2422  { "half"     , tic54x_cons              ,        'h' },
2423  { "uhalf"    , tic54x_cons              ,        'H' },
2424  { "short"    , tic54x_cons              ,        's' },
2425  { "ushort"   , tic54x_cons              ,        'S' },
2426  { "if"       , s_if                     , (int) O_ne },
2427  { "elseif"   , s_elseif                 , (int) O_ne },
2428  { "else"     , s_else                   ,          0 },
2429  { "endif"    , s_endif                  ,          0 },
2430  { "int"      , tic54x_cons              ,        'i' },
2431  { "uint"     , tic54x_cons              ,        'I' },
2432  { "word"     , tic54x_cons              ,        'w' },
2433  { "uword"    , tic54x_cons              ,        'W' },
2434  { "label"    , tic54x_label             ,          0 }, /* Loadtime
2435                                                             address.  */
2436  { "length"   , s_ignore                 ,          0 },
2437  { "width"    , s_ignore                 ,          0 },
2438  { "long"     , tic54x_cons              ,        'l' },
2439  { "ulong"    , tic54x_cons              ,        'L' },
2440  { "xlong"    , tic54x_cons              ,        'x' },
2441  { "loop"     , tic54x_loop              ,       1024 },
2442  { "break"    , tic54x_break             ,          0 },
2443  { "endloop"  , tic54x_endloop           ,          0 },
2444  { "mlib"     , tic54x_mlib              ,          0 },
2445  { "mlist"    , s_ignore                 ,          0 },
2446  { "mnolist"  , s_ignore                 ,          0 },
2447  { "mmregs"   , tic54x_mmregs            ,          0 },
2448  { "newblock" , tic54x_clear_local_labels,          0 },
2449  { "option"   , s_ignore                 ,          0 },
2450  { "p2align"  , tic54x_p2align           ,          0 },
2451  { "sblock"   , tic54x_sblock            ,          0 },
2452  { "sect"     , tic54x_sect              ,        '*' },
2453  { "set"      , tic54x_set               ,          0 },
2454  { "equ"      , tic54x_set               ,          0 },
2455  { "space"    , tic54x_space             ,          0 },
2456  { "bes"      , tic54x_space             ,          1 },
2457  { "sslist"   , tic54x_sslist            ,          1 },
2458  { "ssnolist" , tic54x_sslist            ,          0 },
2459  { "string"   , tic54x_stringer          ,        's' },
2460  { "pstring"  , tic54x_stringer          ,        'p' },
2461  { "struct"   , tic54x_struct            ,          0 },
2462  { "tag"      , tic54x_tag               ,          0 },
2463  { "endstruct", tic54x_endstruct         ,          0 },
2464  { "tab"      , s_ignore                 ,          0 },
2465  { "text"     , tic54x_sect              ,        't' },
2466  { "union"    , tic54x_struct            ,          1 },
2467  { "endunion" , tic54x_endstruct         ,          1 },
2468  { "usect"    , tic54x_usect             ,          0 },
2469  { "var"      , tic54x_var               ,          0 },
2470  { "version"  , tic54x_version           ,          0 },
2471  {0           , 0                        ,          0 }
2472};
2473
2474int
2475md_parse_option (int c, char *arg)
2476{
2477  switch (c)
2478    {
2479    default:
2480      return 0;
2481    case OPTION_COFF_VERSION:
2482      {
2483	int version = atoi (arg);
2484
2485	if (version != 0 && version != 1 && version != 2)
2486	  as_fatal (_("Bad COFF version '%s'"), arg);
2487	/* FIXME -- not yet implemented.  */
2488	break;
2489      }
2490    case OPTION_CPU_VERSION:
2491      {
2492	cpu = lookup_version (arg);
2493	cpu_needs_set = 1;
2494	if (cpu == VNONE)
2495	  as_fatal (_("Bad CPU version '%s'"), arg);
2496	break;
2497      }
2498    case OPTION_ADDRESS_MODE:
2499      amode = far_mode;
2500      address_mode_needs_set = 1;
2501      break;
2502    case OPTION_STDERR_TO_FILE:
2503      {
2504	char *filename = arg;
2505	FILE *fp = fopen (filename, "w+");
2506
2507	if (fp == NULL)
2508	  as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
2509	fclose (fp);
2510	if ((fp = freopen (filename, "w+", stderr)) == NULL)
2511	  as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
2512	break;
2513      }
2514    }
2515
2516  return 1;
2517}
2518
2519/* Create a "local" substitution string hash table for a new macro level
2520   Some docs imply that macros have to use .newblock in order to be able
2521   to re-use a local label.  We effectively do an automatic .newblock by
2522   deleting the local label hash between macro invocations.  */
2523
2524void
2525tic54x_macro_start (void)
2526{
2527  ++macro_level;
2528  subsym_hash[macro_level] = hash_new ();
2529  local_label_hash[macro_level] = hash_new ();
2530}
2531
2532void
2533tic54x_macro_info (const macro_entry *macro)
2534{
2535  const formal_entry *entry;
2536
2537  /* Put the formal args into the substitution symbol table.  */
2538  for (entry = macro->formals; entry; entry = entry->next)
2539    {
2540      char *name = strncpy (xmalloc (entry->name.len + 1),
2541			    entry->name.ptr, entry->name.len);
2542      char *value = strncpy (xmalloc (entry->actual.len + 1),
2543			     entry->actual.ptr, entry->actual.len);
2544
2545      name[entry->name.len] = '\0';
2546      value[entry->actual.len] = '\0';
2547      hash_insert (subsym_hash[macro_level], name, value);
2548    }
2549}
2550
2551/* Get rid of this macro's .var's, arguments, and local labels.  */
2552
2553void
2554tic54x_macro_end (void)
2555{
2556  hash_die (subsym_hash[macro_level]);
2557  subsym_hash[macro_level] = NULL;
2558  hash_die (local_label_hash[macro_level]);
2559  local_label_hash[macro_level] = NULL;
2560  --macro_level;
2561}
2562
2563static int
2564subsym_symlen (char *a, char *ignore ATTRIBUTE_UNUSED)
2565{
2566  return strlen (a);
2567}
2568
2569/* Compare symbol A to string B.  */
2570
2571static int
2572subsym_symcmp (char *a, char *b)
2573{
2574  return strcmp (a, b);
2575}
2576
2577/* Return the index of the first occurrence of B in A, or zero if none
2578   assumes b is an integer char value as a string.  Index is one-based.  */
2579
2580static int
2581subsym_firstch (char *a, char *b)
2582{
2583  int val = atoi (b);
2584  char *tmp = strchr (a, val);
2585
2586  return tmp ? tmp - a + 1 : 0;
2587}
2588
2589/* Similar to firstch, but returns index of last occurrence of B in A.  */
2590
2591static int
2592subsym_lastch (char *a, char *b)
2593{
2594  int val = atoi (b);
2595  char *tmp = strrchr (a, val);
2596
2597  return tmp ? tmp - a + 1 : 0;
2598}
2599
2600/* Returns 1 if string A is defined in the symbol table (NOT the substitution
2601   symbol table).  */
2602
2603static int
2604subsym_isdefed (char *a, char *ignore ATTRIBUTE_UNUSED)
2605{
2606  symbolS *symbolP = symbol_find (a);
2607
2608  return symbolP != NULL;
2609}
2610
2611/* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
2612   A, or zero if B is a null string.  Both arguments *must* be substitution
2613   symbols, unsubstituted.  */
2614
2615static int
2616subsym_ismember (char *sym, char *list)
2617{
2618  char *elem, *ptr, *listv;
2619
2620  if (!list)
2621    return 0;
2622
2623  listv = subsym_lookup (list, macro_level);
2624  if (!listv)
2625    {
2626      as_bad (_("Undefined substitution symbol '%s'"), list);
2627      ignore_rest_of_line ();
2628      return 0;
2629    }
2630
2631  ptr = elem = xmalloc (strlen (listv) + 1);
2632  strcpy (elem, listv);
2633  while (*ptr && *ptr != ',')
2634    ++ptr;
2635  *ptr++ = 0;
2636
2637  subsym_create_or_replace (sym, elem);
2638
2639  /* Reassign the list.  */
2640  subsym_create_or_replace (list, ptr);
2641
2642  /* Assume this value, docs aren't clear.  */
2643  return *list != 0;
2644}
2645
2646/* Return zero if not a constant; otherwise:
2647   1 if binary
2648   2 if octal
2649   3 if hexadecimal
2650   4 if character
2651   5 if decimal.  */
2652
2653static int
2654subsym_iscons (char *a, char *ignore ATTRIBUTE_UNUSED)
2655{
2656  expressionS expn;
2657
2658  parse_expression (a, &expn);
2659
2660  if (expn.X_op == O_constant)
2661    {
2662      int len = strlen (a);
2663
2664      switch (TOUPPER (a[len - 1]))
2665	{
2666	case 'B':
2667	  return 1;
2668	case 'Q':
2669	  return 2;
2670	case 'H':
2671	  return 3;
2672	case '\'':
2673	  return 4;
2674	default:
2675	  break;
2676	}
2677      /* No suffix; either octal, hex, or decimal.  */
2678      if (*a == '0' && len > 1)
2679	{
2680	  if (TOUPPER (a[1]) == 'X')
2681	    return 3;
2682	  return 2;
2683	}
2684      return 5;
2685    }
2686
2687  return 0;
2688}
2689
2690/* Return 1 if A is a valid symbol name.  Expects string input.   */
2691
2692static int
2693subsym_isname (char *a, char *ignore ATTRIBUTE_UNUSED)
2694{
2695  if (!is_name_beginner (*a))
2696    return 0;
2697  while (*a)
2698    {
2699      if (!is_part_of_name (*a))
2700	return 0;
2701      ++a;
2702    }
2703  return 1;
2704}
2705
2706/* Return whether the string is a register; accepts ar0-7, unless .mmregs has
2707   been seen; if so, recognize any memory-mapped register.
2708   Note this does not recognize "A" or "B" accumulators.  */
2709
2710static int
2711subsym_isreg (char *a, char *ignore ATTRIBUTE_UNUSED)
2712{
2713  if (hash_find (reg_hash, a))
2714    return 1;
2715  if (hash_find (mmreg_hash, a))
2716    return 1;
2717  return 0;
2718}
2719
2720/* Return the structure size, given the stag.  */
2721
2722static int
2723subsym_structsz (char *name, char *ignore ATTRIBUTE_UNUSED)
2724{
2725  struct stag *stag = (struct stag *) hash_find (stag_hash, name);
2726
2727  if (stag)
2728    return stag->size;
2729
2730  return 0;
2731}
2732
2733/* If anybody actually uses this, they can fix it :)
2734   FIXME I'm not sure what the "reference point" of a structure is.  It might
2735   be either the initial offset given .struct, or it may be the offset of the
2736   structure within another structure, or it might be something else
2737   altogether.  since the TI assembler doesn't seem to ever do anything but
2738   return zero, we punt and return zero.  */
2739
2740static int
2741subsym_structacc (char *stag_name ATTRIBUTE_UNUSED,
2742		  char *ignore ATTRIBUTE_UNUSED)
2743{
2744  return 0;
2745}
2746
2747static float
2748math_ceil (float arg1, float ignore ATTRIBUTE_UNUSED)
2749{
2750  return (float) ceil (arg1);
2751}
2752
2753static float
2754math_cvi (float arg1, float ignore ATTRIBUTE_UNUSED)
2755{
2756  return (int) arg1;
2757}
2758
2759static float
2760math_floor (float arg1, float ignore ATTRIBUTE_UNUSED)
2761{
2762  return (float) floor (arg1);
2763}
2764
2765static float
2766math_fmod (float arg1, float arg2)
2767{
2768  return (int) arg1 % (int) arg2;
2769}
2770
2771static float
2772math_int (float arg1, float ignore ATTRIBUTE_UNUSED)
2773{
2774  return ((float) ((int) arg1)) == arg1;
2775}
2776
2777static float
2778math_round (float arg1, float ignore ATTRIBUTE_UNUSED)
2779{
2780  return arg1 > 0 ? (int) (arg1 + 0.5) : (int) (arg1 - 0.5);
2781}
2782
2783static float
2784math_sgn (float arg1, float ignore ATTRIBUTE_UNUSED)
2785{
2786  return (arg1 < 0) ? -1 : (arg1 ? 1 : 0);
2787}
2788
2789static float
2790math_trunc (float arg1, float ignore ATTRIBUTE_UNUSED)
2791{
2792  return (int) arg1;
2793}
2794
2795static float
2796math_acos (float arg1, float ignore ATTRIBUTE_UNUSED)
2797{
2798  return (float) acos (arg1);
2799}
2800
2801static float
2802math_asin (float arg1, float ignore ATTRIBUTE_UNUSED)
2803{
2804  return (float) asin (arg1);
2805}
2806
2807static float
2808math_atan (float arg1, float ignore ATTRIBUTE_UNUSED)
2809{
2810  return (float) atan (arg1);
2811}
2812
2813static float
2814math_atan2 (float arg1, float arg2)
2815{
2816  return (float) atan2 (arg1, arg2);
2817}
2818
2819static float
2820math_cosh (float arg1, float ignore ATTRIBUTE_UNUSED)
2821{
2822  return (float) cosh (arg1);
2823}
2824
2825static float
2826math_cos (float arg1, float ignore ATTRIBUTE_UNUSED)
2827{
2828  return (float) cos (arg1);
2829}
2830
2831static float
2832math_cvf (float arg1, float ignore ATTRIBUTE_UNUSED)
2833{
2834  return (float) arg1;
2835}
2836
2837static float
2838math_exp (float arg1, float ignore ATTRIBUTE_UNUSED)
2839{
2840  return (float) exp (arg1);
2841}
2842
2843static float
2844math_fabs (float arg1, float ignore ATTRIBUTE_UNUSED)
2845{
2846  return (float) fabs (arg1);
2847}
2848
2849/* expr1 * 2^expr2.  */
2850
2851static float
2852math_ldexp (float arg1, float arg2)
2853{
2854  return arg1 * (float) pow (2.0, arg2);
2855}
2856
2857static float
2858math_log10 (float arg1, float ignore ATTRIBUTE_UNUSED)
2859{
2860  return (float) log10 (arg1);
2861}
2862
2863static float
2864math_log (float arg1, float ignore ATTRIBUTE_UNUSED)
2865{
2866  return (float) log (arg1);
2867}
2868
2869static float
2870math_max (float arg1, float arg2)
2871{
2872  return (arg1 > arg2) ? arg1 : arg2;
2873}
2874
2875static float
2876math_min (float arg1, float arg2)
2877{
2878  return (arg1 < arg2) ? arg1 : arg2;
2879}
2880
2881static float
2882math_pow (float arg1, float arg2)
2883{
2884  return (float) pow (arg1, arg2);
2885}
2886
2887static float
2888math_sin (float arg1, float ignore ATTRIBUTE_UNUSED)
2889{
2890  return (float) sin (arg1);
2891}
2892
2893static float
2894math_sinh (float arg1, float ignore ATTRIBUTE_UNUSED)
2895{
2896  return (float) sinh (arg1);
2897}
2898
2899static float
2900math_sqrt (float arg1, float ignore ATTRIBUTE_UNUSED)
2901{
2902  return (float) sqrt (arg1);
2903}
2904
2905static float
2906math_tan (float arg1, float ignore ATTRIBUTE_UNUSED)
2907{
2908  return (float) tan (arg1);
2909}
2910
2911static float
2912math_tanh (float arg1, float ignore ATTRIBUTE_UNUSED)
2913{
2914  return (float) tanh (arg1);
2915}
2916
2917/* Built-in substitution symbol functions and math functions.  */
2918typedef struct
2919{
2920  char *name;
2921  int (*proc) (char *, char *);
2922  int nargs;
2923} subsym_proc_entry;
2924
2925static const subsym_proc_entry subsym_procs[] =
2926{
2927  /* Assembler built-in string substitution functions.  */
2928  { "$symlen", subsym_symlen, 1,  },
2929  { "$symcmp", subsym_symcmp, 2,  },
2930  { "$firstch", subsym_firstch, 2,  },
2931  { "$lastch", subsym_lastch, 2,  },
2932  { "$isdefed", subsym_isdefed, 1,  },
2933  { "$ismember", subsym_ismember, 2,  },
2934  { "$iscons", subsym_iscons, 1,  },
2935  { "$isname", subsym_isname, 1,  },
2936  { "$isreg", subsym_isreg, 1,  },
2937  { "$structsz", subsym_structsz, 1,  },
2938  { "$structacc", subsym_structacc, 1,  },
2939  { NULL, NULL, 0 },
2940};
2941
2942typedef struct
2943{
2944  char *name;
2945  float (*proc) (float, float);
2946  int nargs;
2947  int int_return;
2948} math_proc_entry;
2949
2950static const math_proc_entry math_procs[] =
2951{
2952  /* Integer-returning built-in math functions.  */
2953  { "$cvi", math_cvi, 1, 1 },
2954  { "$int", math_int, 1, 1 },
2955  { "$sgn", math_sgn, 1, 1 },
2956
2957  /* Float-returning built-in math functions.  */
2958  { "$acos", math_acos, 1, 0 },
2959  { "$asin", math_asin, 1, 0 },
2960  { "$atan", math_atan, 1, 0 },
2961  { "$atan2", math_atan2, 2, 0 },
2962  { "$ceil", math_ceil, 1, 0 },
2963  { "$cosh", math_cosh, 1, 0 },
2964  { "$cos", math_cos, 1, 0 },
2965  { "$cvf", math_cvf, 1, 0 },
2966  { "$exp", math_exp, 1, 0 },
2967  { "$fabs", math_fabs, 1, 0 },
2968  { "$floor", math_floor, 1, 0 },
2969  { "$fmod", math_fmod, 2, 0 },
2970  { "$ldexp", math_ldexp, 2, 0 },
2971  { "$log10", math_log10, 1, 0 },
2972  { "$log", math_log, 1, 0 },
2973  { "$max", math_max, 2, 0 },
2974  { "$min", math_min, 2, 0 },
2975  { "$pow", math_pow, 2, 0 },
2976  { "$round", math_round, 1, 0 },
2977  { "$sin", math_sin, 1, 0 },
2978  { "$sinh", math_sinh, 1, 0 },
2979  { "$sqrt", math_sqrt, 1, 0 },
2980  { "$tan", math_tan, 1, 0 },
2981  { "$tanh", math_tanh, 1, 0 },
2982  { "$trunc", math_trunc, 1, 0 },
2983  { NULL, NULL, 0, 0 },
2984};
2985
2986void
2987md_begin (void)
2988{
2989  insn_template *tm;
2990  symbol *sym;
2991  const subsym_proc_entry *subsym_proc;
2992  const math_proc_entry *math_proc;
2993  const char *hash_err;
2994  char **symname;
2995  char *TIC54X_DIR = getenv ("TIC54X_DIR");
2996  char *A_DIR = TIC54X_DIR ? TIC54X_DIR : getenv ("A_DIR");
2997
2998  local_label_id = 0;
2999
3000  /* Look for A_DIR and add it to the include list.  */
3001  if (A_DIR != NULL)
3002    {
3003      char *tmp = xstrdup (A_DIR);
3004
3005      do
3006	{
3007	  char *next = strchr (tmp, ';');
3008
3009	  if (next)
3010	    *next++ = '\0';
3011	  add_include_dir (tmp);
3012	  tmp = next;
3013	}
3014      while (tmp != NULL);
3015    }
3016
3017  op_hash = hash_new ();
3018  for (tm = (insn_template *) tic54x_optab; tm->name; tm++)
3019    {
3020      if (hash_find (op_hash, tm->name))
3021	continue;
3022      hash_err = hash_insert (op_hash, tm->name, (char *) tm);
3023      if (hash_err)
3024	as_fatal ("Internal Error: Can't hash %s: %s",
3025		  tm->name, hash_err);
3026    }
3027  parop_hash = hash_new ();
3028  for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
3029    {
3030      if (hash_find (parop_hash, tm->name))
3031	continue;
3032      hash_err = hash_insert (parop_hash, tm->name, (char *) tm);
3033      if (hash_err)
3034	as_fatal ("Internal Error: Can't hash %s: %s",
3035		  tm->name, hash_err);
3036    }
3037  reg_hash = hash_new ();
3038  for (sym = (symbol *) regs; sym->name; sym++)
3039    {
3040      /* Add basic registers to the symbol table.  */
3041      symbolS *symbolP = symbol_new (sym->name, absolute_section,
3042				     (valueT) sym->value, &zero_address_frag);
3043      SF_SET_LOCAL (symbolP);
3044      symbol_table_insert (symbolP);
3045      hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
3046    }
3047  for (sym = (symbol *) mmregs; sym->name; sym++)
3048    hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
3049  mmreg_hash = hash_new ();
3050  for (sym = (symbol *) mmregs; sym->name; sym++)
3051    hash_err = hash_insert (mmreg_hash, sym->name, (char *) sym);
3052
3053  cc_hash = hash_new ();
3054  for (sym = (symbol *) condition_codes; sym->name; sym++)
3055    hash_err = hash_insert (cc_hash, sym->name, (char *) sym);
3056
3057  cc2_hash = hash_new ();
3058  for (sym = (symbol *) cc2_codes; sym->name; sym++)
3059    hash_err = hash_insert (cc2_hash, sym->name, (char *) sym);
3060
3061  cc3_hash = hash_new ();
3062  for (sym = (symbol *) cc3_codes; sym->name; sym++)
3063    hash_err = hash_insert (cc3_hash, sym->name, (char *) sym);
3064
3065  sbit_hash = hash_new ();
3066  for (sym = (symbol *) status_bits; sym->name; sym++)
3067    hash_err = hash_insert (sbit_hash, sym->name, (char *) sym);
3068
3069  misc_symbol_hash = hash_new ();
3070  for (symname = (char **) misc_symbols; *symname; symname++)
3071    hash_err = hash_insert (misc_symbol_hash, *symname, *symname);
3072
3073  /* Only the base substitution table and local label table are initialized;
3074     the others (for local macro substitution) get instantiated as needed.  */
3075  local_label_hash[0] = hash_new ();
3076  subsym_hash[0] = hash_new ();
3077  for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++)
3078    hash_err = hash_insert (subsym_hash[0], subsym_proc->name,
3079			    (char *) subsym_proc);
3080
3081  math_hash = hash_new ();
3082  for (math_proc = math_procs; math_proc->name; math_proc++)
3083    {
3084      /* Insert into the main subsym hash for recognition; insert into
3085	 the math hash to actually store information.  */
3086      hash_err = hash_insert (subsym_hash[0], math_proc->name,
3087			      (char *) math_proc);
3088      hash_err = hash_insert (math_hash, math_proc->name,
3089			      (char *) math_proc);
3090    }
3091  subsym_recurse_hash = hash_new ();
3092  stag_hash = hash_new ();
3093}
3094
3095static int
3096is_accumulator (struct opstruct *operand)
3097{
3098  return strcasecmp (operand->buf, "a") == 0
3099    || strcasecmp (operand->buf, "b") == 0;
3100}
3101
3102/* Return the number of operands found, or -1 on error, copying the
3103   operands into the given array and the accompanying expressions into
3104   the next array.  */
3105
3106static int
3107get_operands (struct opstruct operands[], char *line)
3108{
3109  char *lptr = line;
3110  int numexp = 0;
3111  int expecting_operand = 0;
3112  int i;
3113
3114  while (numexp < MAX_OPERANDS && !is_end_of_line[(int) *lptr])
3115    {
3116      int paren_not_balanced = 0;
3117      char *op_start, *op_end;
3118
3119      while (*lptr && ISSPACE (*lptr))
3120	++lptr;
3121      op_start = lptr;
3122      while (paren_not_balanced || *lptr != ',')
3123	{
3124	  if (*lptr == '\0')
3125	    {
3126	      if (paren_not_balanced)
3127		{
3128		  as_bad (_("Unbalanced parenthesis in operand %d"), numexp);
3129		  return -1;
3130		}
3131	      else
3132		break;
3133	    }
3134	  if (*lptr == '(')
3135	    ++paren_not_balanced;
3136	  else if (*lptr == ')')
3137	    --paren_not_balanced;
3138	  ++lptr;
3139	}
3140      op_end = lptr;
3141      if (op_end != op_start)
3142	{
3143	  int len = op_end - op_start;
3144
3145	  strncpy (operands[numexp].buf, op_start, len);
3146	  operands[numexp].buf[len] = 0;
3147	  /* Trim trailing spaces; while the preprocessor gets rid of most,
3148	     there are weird usage patterns that can introduce them
3149	     (i.e. using strings for macro args).  */
3150	  while (len > 0 && ISSPACE (operands[numexp].buf[len - 1]))
3151	    operands[numexp].buf[--len] = 0;
3152	  lptr = op_end;
3153	  ++numexp;
3154	}
3155      else
3156	{
3157	  if (expecting_operand || *lptr == ',')
3158	    {
3159	      as_bad (_("Expecting operand after ','"));
3160	      return -1;
3161	    }
3162	}
3163      if (*lptr == ',')
3164	{
3165	  if (*++lptr == '\0')
3166	    {
3167	      as_bad (_("Expecting operand after ','"));
3168	      return -1;
3169	    }
3170	  expecting_operand = 1;
3171	}
3172    }
3173
3174  while (*lptr && ISSPACE (*lptr++))
3175    ;
3176  if (!is_end_of_line[(int) *lptr])
3177    {
3178      as_bad (_("Extra junk on line"));
3179      return -1;
3180    }
3181
3182  /* OK, now parse them into expressions.  */
3183  for (i = 0; i < numexp; i++)
3184    {
3185      memset (&operands[i].exp, 0, sizeof (operands[i].exp));
3186      if (operands[i].buf[0] == '#')
3187	{
3188	  /* Immediate.  */
3189	  parse_expression (operands[i].buf + 1, &operands[i].exp);
3190	}
3191      else if (operands[i].buf[0] == '@')
3192	{
3193	  /* Direct notation.  */
3194	  parse_expression (operands[i].buf + 1, &operands[i].exp);
3195	}
3196      else if (operands[i].buf[0] == '*')
3197	{
3198	  /* Indirect.  */
3199	  char *paren = strchr (operands[i].buf, '(');
3200
3201	  /* Allow immediate syntax in the inner expression.  */
3202	  if (paren && paren[1] == '#')
3203	    *++paren = '(';
3204
3205	  /* Pull out the lk expression or SP offset, if present.  */
3206	  if (paren != NULL)
3207	    {
3208	      int len = strlen (paren);
3209	      char *end = paren + len;
3210	      int c;
3211
3212	      while (end[-1] != ')')
3213		if (--end <= paren)
3214		  {
3215		    as_bad (_("Badly formed address expression"));
3216		    return -1;
3217		  }
3218	      c = *end;
3219	      *end = '\0';
3220	      parse_expression (paren, &operands[i].exp);
3221	      *end = c;
3222	    }
3223	  else
3224	    operands[i].exp.X_op = O_absent;
3225	}
3226      else
3227	parse_expression (operands[i].buf, &operands[i].exp);
3228    }
3229
3230  return numexp;
3231}
3232
3233/* Predicates for different operand types.  */
3234
3235static int
3236is_immediate (struct opstruct *operand)
3237{
3238  return *operand->buf == '#';
3239}
3240
3241/* This is distinguished from immediate because some numbers must be constants
3242   and must *not* have the '#' prefix.  */
3243
3244static int
3245is_absolute (struct opstruct *operand)
3246{
3247  return operand->exp.X_op == O_constant && !is_immediate (operand);
3248}
3249
3250/* Is this an indirect operand?  */
3251
3252static int
3253is_indirect (struct opstruct *operand)
3254{
3255  return operand->buf[0] == '*';
3256}
3257
3258/* Is this a valid dual-memory operand?  */
3259
3260static int
3261is_dual (struct opstruct *operand)
3262{
3263  if (is_indirect (operand) && strncasecmp (operand->buf, "*ar", 3) == 0)
3264    {
3265      char *tmp = operand->buf + 3;
3266      int arf;
3267      int valid_mod;
3268
3269      arf = *tmp++ - '0';
3270      /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%.  */
3271      valid_mod = *tmp == '\0' ||
3272	strcasecmp (tmp, "-") == 0 ||
3273	strcasecmp (tmp, "+") == 0 ||
3274	strcasecmp (tmp, "+0%") == 0;
3275      return arf >= 2 && arf <= 5 && valid_mod;
3276    }
3277  return 0;
3278}
3279
3280static int
3281is_mmreg (struct opstruct *operand)
3282{
3283  return (is_absolute (operand)
3284	  || is_immediate (operand)
3285	  || hash_find (mmreg_hash, operand->buf) != 0);
3286}
3287
3288static int
3289is_type (struct opstruct *operand, enum optype type)
3290{
3291  switch (type)
3292    {
3293    case OP_None:
3294      return operand->buf[0] == 0;
3295    case OP_Xmem:
3296    case OP_Ymem:
3297      return is_dual (operand);
3298    case OP_Sind:
3299      return is_indirect (operand);
3300    case OP_xpmad_ms7:
3301      /* This one *must* be immediate.  */
3302      return is_immediate (operand);
3303    case OP_xpmad:
3304    case OP_pmad:
3305    case OP_PA:
3306    case OP_dmad:
3307    case OP_Lmem:
3308    case OP_MMR:
3309      return 1;
3310    case OP_Smem:
3311      /* Address may be a numeric, indirect, or an expression.  */
3312      return !is_immediate (operand);
3313    case OP_MMRY:
3314    case OP_MMRX:
3315      return is_mmreg (operand);
3316    case OP_SRC:
3317    case OP_SRC1:
3318    case OP_RND:
3319    case OP_DST:
3320      return is_accumulator (operand);
3321    case OP_B:
3322      return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'B';
3323    case OP_A:
3324      return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'A';
3325    case OP_ARX:
3326      return strncasecmp ("ar", operand->buf, 2) == 0
3327	&& ISDIGIT (operand->buf[2]);
3328    case OP_SBIT:
3329      return hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand);
3330    case OP_CC:
3331      return hash_find (cc_hash, operand->buf) != 0;
3332    case OP_CC2:
3333      return hash_find (cc2_hash, operand->buf) != 0;
3334    case OP_CC3:
3335      return hash_find (cc3_hash, operand->buf) != 0
3336	|| is_immediate (operand) || is_absolute (operand);
3337    case OP_16:
3338      return (is_immediate (operand) || is_absolute (operand))
3339	&& operand->exp.X_add_number == 16;
3340    case OP_N:
3341      /* Allow st0 or st1 instead of a numeric.  */
3342      return is_absolute (operand) || is_immediate (operand) ||
3343	strcasecmp ("st0", operand->buf) == 0 ||
3344	strcasecmp ("st1", operand->buf) == 0;
3345    case OP_12:
3346    case OP_123:
3347      return is_absolute (operand) || is_immediate (operand);
3348    case OP_SHFT:
3349      return (is_immediate (operand) || is_absolute (operand))
3350	&& operand->exp.X_add_number >= 0 && operand->exp.X_add_number < 16;
3351    case OP_SHIFT:
3352      /* Let this one catch out-of-range values.  */
3353      return (is_immediate (operand) || is_absolute (operand))
3354	&& operand->exp.X_add_number != 16;
3355    case OP_BITC:
3356    case OP_031:
3357    case OP_k8:
3358      return is_absolute (operand) || is_immediate (operand);
3359    case OP_k8u:
3360      return is_immediate (operand)
3361	&& operand->exp.X_op == O_constant
3362	&& operand->exp.X_add_number >= 0
3363	&& operand->exp.X_add_number < 256;
3364    case OP_lk:
3365    case OP_lku:
3366      /* Allow anything; assumes opcodes are ordered with Smem operands
3367	 versions first.  */
3368      return 1;
3369    case OP_k5:
3370    case OP_k3:
3371    case OP_k9:
3372      /* Just make sure it's an integer; check range later.  */
3373      return is_immediate (operand);
3374    case OP_T:
3375      return strcasecmp ("t", operand->buf) == 0 ||
3376	strcasecmp ("treg", operand->buf) == 0;
3377    case OP_TS:
3378      return strcasecmp ("ts", operand->buf) == 0;
3379    case OP_ASM:
3380      return strcasecmp ("asm", operand->buf) == 0;
3381    case OP_TRN:
3382      return strcasecmp ("trn", operand->buf) == 0;
3383    case OP_DP:
3384      return strcasecmp ("dp", operand->buf) == 0;
3385    case OP_ARP:
3386      return strcasecmp ("arp", operand->buf) == 0;
3387    default:
3388      return 0;
3389    }
3390}
3391
3392static int
3393operands_match (tic54x_insn *insn,
3394		struct opstruct *operands,
3395		int opcount,
3396		const enum optype *refoptype,
3397		int minops,
3398		int maxops)
3399{
3400  int op = 0, refop = 0;
3401
3402  if (opcount == 0 && minops == 0)
3403    return 1;
3404
3405  while (op <= maxops && refop <= maxops)
3406    {
3407      while (!is_type (&operands[op], OPTYPE (refoptype[refop])))
3408	{
3409	  /* Skip an optional template operand if it doesn't agree
3410	     with the current operand.  */
3411	  if (refoptype[refop] & OPT)
3412	    {
3413	      ++refop;
3414	      --maxops;
3415	      if (refop > maxops)
3416		return 0;
3417	    }
3418	  else
3419	    return 0;
3420	}
3421
3422      /* Save the actual operand type for later use.  */
3423      operands[op].type = OPTYPE (refoptype[refop]);
3424      ++refop;
3425      ++op;
3426      /* Have we matched them all yet?  */
3427      if (op == opcount)
3428	{
3429	  while (op < maxops)
3430	    {
3431	      /* If a later operand is *not* optional, no match.  */
3432	      if ((refoptype[refop] & OPT) == 0)
3433		return 0;
3434	      /* Flag any implicit default OP_DST operands so we know to add
3435		 them explicitly when encoding the operand later.  */
3436	      if (OPTYPE (refoptype[refop]) == OP_DST)
3437		insn->using_default_dst = 1;
3438	      ++refop;
3439	      ++op;
3440	    }
3441
3442	  return 1;
3443	}
3444    }
3445
3446  return 0;
3447}
3448
3449/* 16-bit direct memory address
3450   Explicit dmad operands are always in last word of insn (usually second
3451   word, but bumped to third if lk addressing is used)
3452
3453   We allow *(dmad) notation because the TI assembler allows it.
3454
3455   XPC_CODE:
3456   0 for 16-bit addresses
3457   1 for full 23-bit addresses
3458   2 for the upper 7 bits of a 23-bit address (LDX).  */
3459
3460static int
3461encode_dmad (tic54x_insn *insn, struct opstruct *operand, int xpc_code)
3462{
3463  int op = 1 + insn->is_lkaddr;
3464
3465  /* Only allow *(dmad) expressions; all others are invalid.  */
3466  if (is_indirect (operand) && operand->buf[strlen (operand->buf) - 1] != ')')
3467    {
3468      as_bad (_("Invalid dmad syntax '%s'"), operand->buf);
3469      return 0;
3470    }
3471
3472  insn->opcode[op].addr_expr = operand->exp;
3473
3474  if (insn->opcode[op].addr_expr.X_op == O_constant)
3475    {
3476      valueT value = insn->opcode[op].addr_expr.X_add_number;
3477
3478      if (xpc_code == 1)
3479	{
3480	  insn->opcode[0].word &= 0xFF80;
3481	  insn->opcode[0].word |= (value >> 16) & 0x7F;
3482	  insn->opcode[1].word = value & 0xFFFF;
3483	}
3484      else if (xpc_code == 2)
3485	insn->opcode[op].word = (value >> 16) & 0xFFFF;
3486      else
3487	insn->opcode[op].word = value;
3488    }
3489  else
3490    {
3491      /* Do the fixup later; just store the expression.  */
3492      insn->opcode[op].word = 0;
3493      insn->opcode[op].r_nchars = 2;
3494
3495      if (amode == c_mode)
3496	insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
3497      else if (xpc_code == 1)
3498	{
3499	  /* This relocation spans two words, so adjust accordingly.  */
3500	  insn->opcode[0].addr_expr = operand->exp;
3501	  insn->opcode[0].r_type = BFD_RELOC_TIC54X_23;
3502	  insn->opcode[0].r_nchars = 4;
3503	  insn->opcode[0].unresolved = 1;
3504	  /* It's really 2 words, but we want to stop encoding after the
3505	     first, since we must encode both words at once.  */
3506	  insn->words = 1;
3507	}
3508      else if (xpc_code == 2)
3509	insn->opcode[op].r_type = BFD_RELOC_TIC54X_MS7_OF_23;
3510      else
3511	insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
3512
3513      insn->opcode[op].unresolved = 1;
3514    }
3515
3516  return 1;
3517}
3518
3519/* 7-bit direct address encoding.  */
3520
3521static int
3522encode_address (tic54x_insn *insn, struct opstruct *operand)
3523{
3524  /* Assumes that dma addresses are *always* in word 0 of the opcode.  */
3525  insn->opcode[0].addr_expr = operand->exp;
3526
3527  if (operand->exp.X_op == O_constant)
3528    insn->opcode[0].word |= (operand->exp.X_add_number & 0x7F);
3529  else
3530    {
3531      if (operand->exp.X_op == O_register)
3532        as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand->buf);
3533      /* Do the fixup later; just store the expression.  */
3534      insn->opcode[0].r_nchars = 1;
3535      insn->opcode[0].r_type = BFD_RELOC_TIC54X_PARTLS7;
3536      insn->opcode[0].unresolved = 1;
3537    }
3538
3539  return 1;
3540}
3541
3542static int
3543encode_indirect (tic54x_insn *insn, struct opstruct *operand)
3544{
3545  int arf;
3546  int mod;
3547
3548  if (insn->is_lkaddr)
3549    {
3550      /* lk addresses always go in the second insn word.  */
3551      mod = ((TOUPPER (operand->buf[1]) == 'A') ? 12 :
3552	     (operand->buf[1] == '(') ? 15 :
3553	     (strchr (operand->buf, '%') != NULL) ? 14 : 13);
3554      arf = ((mod == 12) ? operand->buf[3] - '0' :
3555	     (mod == 15) ? 0 : operand->buf[4] - '0');
3556
3557      insn->opcode[1].addr_expr = operand->exp;
3558
3559      if (operand->exp.X_op == O_constant)
3560	insn->opcode[1].word = operand->exp.X_add_number;
3561      else
3562	{
3563	  insn->opcode[1].word = 0;
3564	  insn->opcode[1].r_nchars = 2;
3565	  insn->opcode[1].r_type = BFD_RELOC_TIC54X_16_OF_23;
3566	  insn->opcode[1].unresolved = 1;
3567	}
3568    }
3569  else if (strncasecmp (operand->buf, "*sp (", 4) == 0)
3570    {
3571      /* Stack offsets look the same as 7-bit direct addressing.  */
3572      return encode_address (insn, operand);
3573    }
3574  else
3575    {
3576      arf = (TOUPPER (operand->buf[1]) == 'A' ?
3577	     operand->buf[3] : operand->buf[4]) - '0';
3578
3579      if (operand->buf[1] == '+')
3580	{
3581	  mod = 3;		    /* *+ARx  */
3582	  if (insn->tm->flags & FL_SMR)
3583	    as_warn (_("Address mode *+ARx is write-only. "
3584		       "Results of reading are undefined."));
3585	}
3586      else if (operand->buf[4] == '\0')
3587	mod = 0;		    /* *ARx  */
3588      else if (operand->buf[5] == '\0')
3589	mod = (operand->buf[4] == '-' ? 1 : 2); /* *ARx+ / *ARx-  */
3590      else if (operand->buf[6] == '\0')
3591	{
3592	  if (operand->buf[5] == '0')
3593	    mod = (operand->buf[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0  */
3594	  else
3595	    mod = (operand->buf[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-%  */
3596	}
3597      else if (TOUPPER (operand->buf[6]) == 'B')
3598	mod = (operand->buf[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B  */
3599      else if (TOUPPER (operand->buf[6]) == '%')
3600	mod = (operand->buf[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0%  */
3601      else
3602	{
3603	  as_bad (_("Unrecognized indirect address format \"%s\""),
3604		  operand->buf);
3605	  return 0;
3606	}
3607    }
3608
3609  insn->opcode[0].word |= 0x80 | (mod << 3) | arf;
3610
3611  return 1;
3612}
3613
3614static int
3615encode_integer (tic54x_insn *insn,
3616		struct opstruct *operand,
3617		int which,
3618		int min,
3619		int max,
3620		unsigned short mask)
3621{
3622  long parse, integer;
3623
3624  insn->opcode[which].addr_expr = operand->exp;
3625
3626  if (operand->exp.X_op == O_constant)
3627    {
3628      parse = operand->exp.X_add_number;
3629      /* Hack -- fixup for 16-bit hex quantities that get converted positive
3630	 instead of negative.  */
3631      if ((parse & 0x8000) && min == -32768 && max == 32767)
3632	integer = (short) parse;
3633      else
3634	integer = parse;
3635
3636      if (integer >= min && integer <= max)
3637	{
3638	  insn->opcode[which].word |= (integer & mask);
3639	  return 1;
3640	}
3641      as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
3642	      operand->buf, min, max);
3643    }
3644  else
3645    {
3646      if (insn->opcode[which].addr_expr.X_op == O_constant)
3647	{
3648	  insn->opcode[which].word |=
3649	    insn->opcode[which].addr_expr.X_add_number & mask;
3650	}
3651      else
3652	{
3653	  /* Do the fixup later; just store the expression.  */
3654	  bfd_reloc_code_real_type rtype =
3655	    (mask == 0x1FF ? BFD_RELOC_TIC54X_PARTMS9 :
3656	     mask == 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23 :
3657	     mask == 0x7F ? BFD_RELOC_TIC54X_PARTLS7 : BFD_RELOC_8);
3658	  int size = (mask == 0x1FF || mask == 0xFFFF) ? 2 : 1;
3659
3660	  if (rtype == BFD_RELOC_8)
3661	    as_bad (_("Error in relocation handling"));
3662
3663	  insn->opcode[which].r_nchars = size;
3664	  insn->opcode[which].r_type = rtype;
3665	  insn->opcode[which].unresolved = 1;
3666	}
3667
3668      return 1;
3669    }
3670
3671  return 0;
3672}
3673
3674static int
3675encode_condition (tic54x_insn *insn, struct opstruct *operand)
3676{
3677  symbol *cc = (symbol *) hash_find (cc_hash, operand->buf);
3678  if (!cc)
3679    {
3680      as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
3681      return 0;
3682    }
3683#define CC_GROUP 0x40
3684#define CC_ACC   0x08
3685#define CATG_A1  0x07
3686#define CATG_B1  0x30
3687#define CATG_A2  0x30
3688#define CATG_B2  0x0C
3689#define CATG_C2  0x03
3690  /* Disallow group 1 conditions mixed with group 2 conditions
3691     if group 1, allow only one category A and one category B
3692     if group 2, allow only one each of category A, B, and C.  */
3693  if (((insn->opcode[0].word & 0xFF) != 0))
3694    {
3695      if ((insn->opcode[0].word & CC_GROUP) != (cc->value & CC_GROUP))
3696	{
3697	  as_bad (_("Condition \"%s\" does not match preceding group"),
3698		  operand->buf);
3699	  return 0;
3700	}
3701      if (insn->opcode[0].word & CC_GROUP)
3702	{
3703	  if ((insn->opcode[0].word & CC_ACC) != (cc->value & CC_ACC))
3704	    {
3705	      as_bad (_("Condition \"%s\" uses a different accumulator from "
3706			"a preceding condition"),
3707		      operand->buf);
3708	      return 0;
3709	    }
3710	  if ((insn->opcode[0].word & CATG_A1) && (cc->value & CATG_A1))
3711	    {
3712	      as_bad (_("Only one comparison conditional allowed"));
3713	      return 0;
3714	    }
3715	  if ((insn->opcode[0].word & CATG_B1) && (cc->value & CATG_B1))
3716	    {
3717	      as_bad (_("Only one overflow conditional allowed"));
3718	      return 0;
3719	    }
3720	}
3721      else if (   ((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2))
3722	       || ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2))
3723	       || ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
3724	{
3725	  as_bad (_("Duplicate %s conditional"), operand->buf);
3726	  return 0;
3727	}
3728    }
3729
3730  insn->opcode[0].word |= cc->value;
3731  return 1;
3732}
3733
3734static int
3735encode_cc3 (tic54x_insn *insn, struct opstruct *operand)
3736{
3737  symbol *cc3 = (symbol *) hash_find (cc3_hash, operand->buf);
3738  int value = cc3 ? cc3->value : operand->exp.X_add_number << 8;
3739
3740  if ((value & 0x0300) != value)
3741    {
3742      as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
3743      return 0;
3744    }
3745  insn->opcode[0].word |= value;
3746  return 1;
3747}
3748
3749static int
3750encode_arx (tic54x_insn *insn, struct opstruct *operand)
3751{
3752  int arf = strlen (operand->buf) >= 3 ? operand->buf[2] - '0' : -1;
3753
3754  if (strncasecmp ("ar", operand->buf, 2) || arf < 0 || arf > 7)
3755    {
3756      as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
3757      return 0;
3758    }
3759  insn->opcode[0].word |= arf;
3760  return 1;
3761}
3762
3763static int
3764encode_cc2 (tic54x_insn *insn, struct opstruct *operand)
3765{
3766  symbol *cc2 = (symbol *) hash_find (cc2_hash, operand->buf);
3767
3768  if (!cc2)
3769    {
3770      as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
3771      return 0;
3772    }
3773  insn->opcode[0].word |= cc2->value;
3774  return 1;
3775}
3776
3777static int
3778encode_operand (tic54x_insn *insn, enum optype type, struct opstruct *operand)
3779{
3780  int ext = (insn->tm->flags & FL_EXT) != 0;
3781
3782  if (type == OP_MMR && operand->exp.X_op != O_constant)
3783    {
3784      /* Disallow long-constant addressing for memory-mapped addressing.  */
3785      if (insn->is_lkaddr)
3786	{
3787	  as_bad (_("lk addressing modes are invalid for memory-mapped "
3788		    "register addressing"));
3789	  return 0;
3790	}
3791      type = OP_Smem;
3792      /* Warn about *+ARx when used with MMR operands.  */
3793      if (strncasecmp (operand->buf, "*+ar", 4) == 0)
3794	{
3795	  as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
3796		     "register addressing.  Resulting behavior is "
3797		     "undefined."));
3798	}
3799    }
3800
3801  switch (type)
3802    {
3803    case OP_None:
3804      return 1;
3805    case OP_dmad:
3806      /* 16-bit immediate value.  */
3807      return encode_dmad (insn, operand, 0);
3808    case OP_SRC:
3809      if (TOUPPER (*operand->buf) == 'B')
3810	{
3811	  insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 9);
3812	  if (insn->using_default_dst)
3813	    insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
3814	}
3815      return 1;
3816    case OP_RND:
3817      /* Make sure this agrees with the OP_DST operand.  */
3818      if (!((TOUPPER (operand->buf[0]) == 'B') ^
3819	    ((insn->opcode[0].word & (1 << 8)) != 0)))
3820	{
3821	  as_bad (_("Destination accumulator for each part of this parallel "
3822		    "instruction must be different"));
3823	  return 0;
3824	}
3825      return 1;
3826    case OP_SRC1:
3827    case OP_DST:
3828      if (TOUPPER (operand->buf[0]) == 'B')
3829	insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
3830      return 1;
3831    case OP_Xmem:
3832    case OP_Ymem:
3833      {
3834	int mod = (operand->buf[4] == '\0' ? 0 : /* *arx  */
3835		   operand->buf[4] == '-' ? 1 : /* *arx-  */
3836		   operand->buf[5] == '\0' ? 2 : 3); /* *arx+, *arx+0%  */
3837	int arf = operand->buf[3] - '0' - 2;
3838	int code = (mod << 2) | arf;
3839	insn->opcode[0].word |= (code << (type == OP_Xmem ? 4 : 0));
3840	return 1;
3841      }
3842    case OP_Lmem:
3843    case OP_Smem:
3844      if (!is_indirect (operand))
3845	return encode_address (insn, operand);
3846      /* Fall through.  */
3847    case OP_Sind:
3848      return encode_indirect (insn, operand);
3849    case OP_xpmad_ms7:
3850      return encode_dmad (insn, operand, 2);
3851    case OP_xpmad:
3852      return encode_dmad (insn, operand, 1);
3853    case OP_PA:
3854    case OP_pmad:
3855      return encode_dmad (insn, operand, 0);
3856    case OP_ARX:
3857      return encode_arx (insn, operand);
3858    case OP_MMRX:
3859    case OP_MMRY:
3860    case OP_MMR:
3861      {
3862	int value = operand->exp.X_add_number;
3863
3864	if (type == OP_MMR)
3865	  insn->opcode[0].word |= value;
3866	else
3867	  {
3868	    if (value < 16 || value > 24)
3869	      {
3870		as_bad (_("Memory mapped register \"%s\" out of range"),
3871			operand->buf);
3872		return 0;
3873	      }
3874	    if (type == OP_MMRX)
3875	      insn->opcode[0].word |= (value - 16) << 4;
3876	    else
3877	      insn->opcode[0].word |= (value - 16);
3878	  }
3879	return 1;
3880      }
3881    case OP_B:
3882    case OP_A:
3883      return 1;
3884    case OP_SHFT:
3885      return encode_integer (insn, operand, ext + insn->is_lkaddr,
3886			     0, 15, 0xF);
3887    case OP_SHIFT:
3888      return encode_integer (insn, operand, ext + insn->is_lkaddr,
3889			     -16, 15, 0x1F);
3890    case OP_lk:
3891      return encode_integer (insn, operand, 1 + insn->is_lkaddr,
3892			     -32768, 32767, 0xFFFF);
3893    case OP_CC:
3894      return encode_condition (insn, operand);
3895    case OP_CC2:
3896      return encode_cc2 (insn, operand);
3897    case OP_CC3:
3898      return encode_cc3 (insn, operand);
3899    case OP_BITC:
3900      return encode_integer (insn, operand, 0, 0, 15, 0xF);
3901    case OP_k8:
3902      return encode_integer (insn, operand, 0, -128, 127, 0xFF);
3903    case OP_123:
3904      {
3905	int value = operand->exp.X_add_number;
3906	int code;
3907	if (value < 1 || value > 3)
3908	  {
3909	    as_bad (_("Invalid operand (use 1, 2, or 3)"));
3910	    return 0;
3911	  }
3912	code = value == 1 ? 0 : value == 2 ? 0x2 : 0x1;
3913	insn->opcode[0].word |= (code << 8);
3914	return 1;
3915      }
3916    case OP_031:
3917      return encode_integer (insn, operand, 0, 0, 31, 0x1F);
3918    case OP_k8u:
3919      return encode_integer (insn, operand, 0, 0, 255, 0xFF);
3920    case OP_lku:
3921      return encode_integer (insn, operand, 1 + insn->is_lkaddr,
3922			     0, 65535, 0xFFFF);
3923    case OP_SBIT:
3924      {
3925	symbol *sbit = (symbol *) hash_find (sbit_hash, operand->buf);
3926	int value = is_absolute (operand) ?
3927	  operand->exp.X_add_number : (sbit ? sbit->value : -1);
3928	int reg = 0;
3929
3930	if (insn->opcount == 1)
3931	  {
3932	    if (!sbit)
3933	      {
3934		as_bad (_("A status register or status bit name is required"));
3935		return 0;
3936	      }
3937	    /* Guess the register based on the status bit; "ovb" is the last
3938	       status bit defined for st0.  */
3939	    if (sbit > (symbol *) hash_find (sbit_hash, "ovb"))
3940	      reg = 1;
3941	  }
3942	if (value == -1)
3943	  {
3944	    as_bad (_("Unrecognized status bit \"%s\""), operand->buf);
3945	    return 0;
3946	  }
3947	insn->opcode[0].word |= value;
3948	insn->opcode[0].word |= (reg << 9);
3949	return 1;
3950      }
3951    case OP_N:
3952      if (strcasecmp (operand->buf, "st0") == 0
3953	  || strcasecmp (operand->buf, "st1") == 0)
3954	{
3955	  insn->opcode[0].word |=
3956	    ((unsigned short) (operand->buf[2] - '0')) << 9;
3957	  return 1;
3958	}
3959      else if (operand->exp.X_op == O_constant
3960	       && (operand->exp.X_add_number == 0
3961		   || operand->exp.X_add_number == 1))
3962	{
3963	  insn->opcode[0].word |=
3964	    ((unsigned short) (operand->exp.X_add_number)) << 9;
3965	  return 1;
3966	}
3967      as_bad (_("Invalid status register \"%s\""), operand->buf);
3968      return 0;
3969    case OP_k5:
3970      return encode_integer (insn, operand, 0, -16, 15, 0x1F);
3971    case OP_k3:
3972      return encode_integer (insn, operand, 0, 0, 7, 0x7);
3973    case OP_k9:
3974      return encode_integer (insn, operand, 0, 0, 0x1FF, 0x1FF);
3975    case OP_12:
3976      if (operand->exp.X_add_number != 1
3977	  && operand->exp.X_add_number != 2)
3978	{
3979	  as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand->buf);
3980	  return 0;
3981	}
3982      insn->opcode[0].word |= (operand->exp.X_add_number - 1) << 9;
3983      return 1;
3984    case OP_16:
3985    case OP_T:
3986    case OP_TS:
3987    case OP_ASM:
3988    case OP_TRN:
3989    case OP_DP:
3990    case OP_ARP:
3991      /* No encoding necessary.  */
3992      return 1;
3993    default:
3994      return 0;
3995    }
3996
3997  return 1;
3998}
3999
4000static void
4001emit_insn (tic54x_insn *insn)
4002{
4003  int i;
4004  flagword oldflags = bfd_get_section_flags (stdoutput, now_seg);
4005  flagword flags = oldflags | SEC_CODE;
4006
4007  if (! bfd_set_section_flags (stdoutput, now_seg, flags))
4008        as_warn (_("error setting flags for \"%s\": %s"),
4009                 bfd_section_name (stdoutput, now_seg),
4010                 bfd_errmsg (bfd_get_error ()));
4011
4012  for (i = 0; i < insn->words; i++)
4013    {
4014      int size = (insn->opcode[i].unresolved
4015		  && insn->opcode[i].r_type == BFD_RELOC_TIC54X_23) ? 4 : 2;
4016      char *p = frag_more (size);
4017
4018      if (size == 2)
4019	md_number_to_chars (p, (valueT) insn->opcode[i].word, 2);
4020      else
4021	md_number_to_chars (p, (valueT) insn->opcode[i].word << 16, 4);
4022
4023      if (insn->opcode[i].unresolved)
4024	fix_new_exp (frag_now, p - frag_now->fr_literal,
4025		     insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr,
4026		     FALSE, insn->opcode[i].r_type);
4027    }
4028}
4029
4030/* Convert the operand strings into appropriate opcode values
4031   return the total number of words used by the instruction.  */
4032
4033static int
4034build_insn (tic54x_insn *insn)
4035{
4036  int i;
4037
4038  /* Only non-parallel instructions support lk addressing.  */
4039  if (!(insn->tm->flags & FL_PAR))
4040    {
4041      for (i = 0; i < insn->opcount; i++)
4042	{
4043	  if ((OPTYPE (insn->operands[i].type) == OP_Smem
4044	       || OPTYPE (insn->operands[i].type) == OP_Lmem
4045	       || OPTYPE (insn->operands[i].type) == OP_Sind)
4046	      && strchr (insn->operands[i].buf, '(')
4047	      /* Don't mistake stack-relative addressing for lk addressing.  */
4048	      && strncasecmp (insn->operands[i].buf, "*sp (", 4) != 0)
4049	    {
4050	      insn->is_lkaddr = 1;
4051	      insn->lkoperand = i;
4052	      break;
4053	    }
4054	}
4055    }
4056  insn->words = insn->tm->words + insn->is_lkaddr;
4057
4058  insn->opcode[0].word = insn->tm->opcode;
4059  if (insn->tm->flags & FL_EXT)
4060    insn->opcode[1 + insn->is_lkaddr].word = insn->tm->opcode2;
4061
4062  for (i = 0; i < insn->opcount; i++)
4063    {
4064      enum optype type = insn->operands[i].type;
4065
4066      if (!encode_operand (insn, type, &insn->operands[i]))
4067	return 0;
4068    }
4069  if (insn->tm->flags & FL_PAR)
4070    for (i = 0; i < insn->paropcount; i++)
4071      {
4072	enum optype partype = insn->paroperands[i].type;
4073
4074	if (!encode_operand (insn, partype, &insn->paroperands[i]))
4075	  return 0;
4076      }
4077
4078  emit_insn (insn);
4079
4080  return insn->words;
4081}
4082
4083static int
4084optimize_insn (tic54x_insn *insn)
4085{
4086  /* Optimize some instructions, helping out the brain-dead programmer.  */
4087#define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
4088  if (strcasecmp (insn->tm->name, "add") == 0)
4089    {
4090      if (insn->opcount > 1
4091	  && is_accumulator (&insn->operands[insn->opcount - 2])
4092	  && is_accumulator (&insn->operands[insn->opcount - 1])
4093	  && strcasecmp (insn->operands[insn->opcount - 2].buf,
4094			 insn->operands[insn->opcount - 1].buf) == 0)
4095	{
4096	  --insn->opcount;
4097	  insn->using_default_dst = 1;
4098	  return 1;
4099	}
4100
4101      /* Try to collapse if Xmem and shift count is zero.  */
4102      if ((OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
4103	   && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT
4104	   && is_zero (insn->operands[1]))
4105	  /* Or if Smem, shift is zero or absent, and SRC == DST.  */
4106	  || (OPTYPE (insn->tm->operand_types[0]) == OP_Smem
4107	      && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4108	      && is_type (&insn->operands[1], OP_SHIFT)
4109	      && is_zero (insn->operands[1]) && insn->opcount == 3))
4110	{
4111	  insn->operands[1] = insn->operands[2];
4112	  insn->opcount = 2;
4113	  return 1;
4114	}
4115    }
4116  else if (strcasecmp (insn->tm->name, "ld") == 0)
4117    {
4118      if (insn->opcount == 3 && insn->operands[0].type != OP_SRC)
4119	{
4120	  if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4121	       || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
4122	      && is_zero (insn->operands[1])
4123	      && (OPTYPE (insn->tm->operand_types[0]) != OP_lk
4124		  || (insn->operands[0].exp.X_op == O_constant
4125		      && insn->operands[0].exp.X_add_number <= 255
4126		      && insn->operands[0].exp.X_add_number >= 0)))
4127	    {
4128	      insn->operands[1] = insn->operands[2];
4129	      insn->opcount = 2;
4130	      return 1;
4131	    }
4132	}
4133    }
4134  else if (strcasecmp (insn->tm->name, "sth") == 0
4135	   || strcasecmp (insn->tm->name, "stl") == 0)
4136    {
4137      if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4138	   || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
4139	  && is_zero (insn->operands[1]))
4140	{
4141	  insn->operands[1] = insn->operands[2];
4142	  insn->opcount = 2;
4143	  return 1;
4144	}
4145    }
4146  else if (strcasecmp (insn->tm->name, "sub") == 0)
4147    {
4148      if (insn->opcount > 1
4149	  && is_accumulator (&insn->operands[insn->opcount - 2])
4150	  && is_accumulator (&insn->operands[insn->opcount - 1])
4151	  && strcasecmp (insn->operands[insn->opcount - 2].buf,
4152			 insn->operands[insn->opcount - 1].buf) == 0)
4153	{
4154	  --insn->opcount;
4155	  insn->using_default_dst = 1;
4156	  return 1;
4157	}
4158
4159      if (   ((OPTYPE (insn->tm->operand_types[0]) == OP_Smem
4160	    && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT)
4161	   || (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
4162	    && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT))
4163	  && is_zero (insn->operands[1])
4164	  && insn->opcount == 3)
4165	{
4166	  insn->operands[1] = insn->operands[2];
4167	  insn->opcount = 2;
4168	  return 1;
4169	}
4170    }
4171  return 0;
4172}
4173
4174/* Find a matching template if possible, and get the operand strings.  */
4175
4176static int
4177tic54x_parse_insn (tic54x_insn *insn, char *line)
4178{
4179  insn->tm = (insn_template *) hash_find (op_hash, insn->mnemonic);
4180  if (!insn->tm)
4181    {
4182      as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic);
4183      return 0;
4184    }
4185
4186  insn->opcount = get_operands (insn->operands, line);
4187  if (insn->opcount < 0)
4188    return 0;
4189
4190  /* Check each variation of operands for this mnemonic.  */
4191  while (insn->tm->name && strcasecmp (insn->tm->name, insn->mnemonic) == 0)
4192    {
4193      if (insn->opcount >= insn->tm->minops
4194	  && insn->opcount <= insn->tm->maxops
4195	  && operands_match (insn, &insn->operands[0], insn->opcount,
4196			     insn->tm->operand_types,
4197			     insn->tm->minops, insn->tm->maxops))
4198	{
4199	  /* SUCCESS! now try some optimizations.  */
4200	  if (optimize_insn (insn))
4201	    {
4202	      insn->tm = (insn_template *) hash_find (op_hash,
4203                                                      insn->mnemonic);
4204	      continue;
4205	    }
4206
4207	  return 1;
4208	}
4209      ++(insn->tm);
4210    }
4211  as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
4212	  line, insn->mnemonic);
4213  return 0;
4214}
4215
4216/* We set this in start_line_hook, 'cause if we do a line replacement, we
4217   won't be able to see the next line.  */
4218static int parallel_on_next_line_hint = 0;
4219
4220/* See if this is part of a parallel instruction
4221   Look for a subsequent line starting with "||".  */
4222
4223static int
4224next_line_shows_parallel (char *next_line)
4225{
4226  /* Look for the second half.  */
4227  while (ISSPACE (*next_line))
4228    ++next_line;
4229
4230  return (next_line[0] == PARALLEL_SEPARATOR
4231	  && next_line[1] == PARALLEL_SEPARATOR);
4232}
4233
4234static int
4235tic54x_parse_parallel_insn_firstline (tic54x_insn *insn, char *line)
4236{
4237  insn->tm = (insn_template *) hash_find (parop_hash, insn->mnemonic);
4238  if (!insn->tm)
4239    {
4240      as_bad (_("Unrecognized parallel instruction \"%s\""),
4241	      insn->mnemonic);
4242      return 0;
4243    }
4244
4245  while (insn->tm->name && strcasecmp (insn->tm->name,
4246                                       insn->mnemonic) == 0)
4247    {
4248      insn->opcount = get_operands (insn->operands, line);
4249      if (insn->opcount < 0)
4250	return 0;
4251      if (insn->opcount == 2
4252	  && operands_match (insn, &insn->operands[0], insn->opcount,
4253			     insn->tm->operand_types, 2, 2))
4254	{
4255	  return 1;
4256	}
4257      ++(insn->tm);
4258    }
4259  /* Didn't find a matching parallel; try for a normal insn.  */
4260  return 0;
4261}
4262
4263/* Parse the second line of a two-line parallel instruction.  */
4264
4265static int
4266tic54x_parse_parallel_insn_lastline (tic54x_insn *insn, char *line)
4267{
4268  int valid_mnemonic = 0;
4269
4270  insn->paropcount = get_operands (insn->paroperands, line);
4271  while (insn->tm->name && strcasecmp (insn->tm->name,
4272				       insn->mnemonic) == 0)
4273    {
4274      if (strcasecmp (insn->tm->parname, insn->parmnemonic) == 0)
4275	{
4276	  valid_mnemonic = 1;
4277
4278	  if (insn->paropcount >= insn->tm->minops
4279	      && insn->paropcount <= insn->tm->maxops
4280	      && operands_match (insn, insn->paroperands,
4281				 insn->paropcount,
4282				 insn->tm->paroperand_types,
4283				 insn->tm->minops, insn->tm->maxops))
4284	    return 1;
4285	}
4286      ++(insn->tm);
4287    }
4288  if (valid_mnemonic)
4289    as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
4290	    insn->parmnemonic);
4291  else
4292    as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
4293	    insn->mnemonic, insn->parmnemonic);
4294
4295  return 0;
4296}
4297
4298/* If quotes found, return copy of line up to closing quote;
4299   otherwise up until terminator.
4300   If it's a string, pass as-is; otherwise attempt substitution symbol
4301   replacement on the value.  */
4302
4303static char *
4304subsym_get_arg (char *line, char *terminators, char **str, int nosub)
4305{
4306  char *ptr = line;
4307  char *endp;
4308  int is_string = *line == '"';
4309  int is_char = ISDIGIT (*line);
4310
4311  if (is_char)
4312    {
4313      while (ISDIGIT (*ptr))
4314	++ptr;
4315      endp = ptr;
4316      *str = xmalloc (ptr - line + 1);
4317      strncpy (*str, line, ptr - line);
4318      (*str)[ptr - line] = 0;
4319    }
4320  else if (is_string)
4321    {
4322      char *savedp = input_line_pointer;
4323      int len;
4324
4325      input_line_pointer = ptr;
4326      *str = demand_copy_C_string (&len);
4327      endp = input_line_pointer;
4328      input_line_pointer = savedp;
4329
4330      /* Do forced substitutions if requested.  */
4331      if (!nosub && **str == ':')
4332	*str = subsym_substitute (*str, 1);
4333    }
4334  else
4335    {
4336      char *term = terminators;
4337      char *value = NULL;
4338
4339      while (*ptr && *ptr != *term)
4340	{
4341	  if (!*term)
4342	    {
4343	      term = terminators;
4344	      ++ptr;
4345	    }
4346	  else
4347	    ++term;
4348	}
4349      endp = ptr;
4350      *str = xmalloc (ptr - line + 1);
4351      strncpy (*str, line, ptr - line);
4352      (*str)[ptr - line] = 0;
4353      /* Do simple substitution, if available.  */
4354      if (!nosub && (value = subsym_lookup (*str, macro_level)) != NULL)
4355	*str = value;
4356    }
4357
4358  return endp;
4359}
4360
4361/* Replace the given substitution string.
4362   We start at the innermost macro level, so that existing locals remain local
4363   Note: we're treating macro args identically to .var's; I don't know if
4364   that's compatible w/TI's assembler.  */
4365
4366static void
4367subsym_create_or_replace (char *name, char *value)
4368{
4369  int i;
4370
4371  for (i = macro_level; i > 0; i--)
4372    {
4373      if (hash_find (subsym_hash[i], name))
4374	{
4375	  hash_replace (subsym_hash[i], name, value);
4376	  return;
4377	}
4378    }
4379  if (hash_find (subsym_hash[0], name))
4380    hash_replace (subsym_hash[0], name, value);
4381  else
4382    hash_insert (subsym_hash[0], name, value);
4383}
4384
4385/* Look up the substitution string replacement for the given symbol.
4386   Start with the innermost macro substitution table given and work
4387   outwards.  */
4388
4389static char *
4390subsym_lookup (char *name, int nest_level)
4391{
4392  char *value = hash_find (subsym_hash[nest_level], name);
4393
4394  if (value || nest_level == 0)
4395    return value;
4396
4397  return subsym_lookup (name, nest_level - 1);
4398}
4399
4400/* Do substitution-symbol replacement on the given line (recursively).
4401   return the argument if no substitution was done
4402
4403   Also look for built-in functions ($func (arg)) and local labels.
4404
4405   If FORCED is set, look for forced substitutions of the form ':SYMBOL:'.  */
4406
4407static char *
4408subsym_substitute (char *line, int forced)
4409{
4410  /* For each apparent symbol, see if it's a substitution symbol, and if so,
4411     replace it in the input.  */
4412  char *replacement; /* current replacement for LINE.  */
4413  char *head; /* Start of line.  */
4414  char *ptr; /* Current examination point.  */
4415  int changed = 0; /* Did we make a substitution?  */
4416  int eval_line = 0; /* Is this line a .eval/.asg statement?  */
4417  int eval_symbol = 0; /* Are we in the middle of the symbol for
4418                          .eval/.asg?  */
4419  char *eval_end = NULL;
4420  int recurse = 1;
4421  int line_conditional = 0;
4422  char *tmp;
4423
4424  /* Work with a copy of the input line.  */
4425  replacement = xmalloc (strlen (line) + 1);
4426  strcpy (replacement, line);
4427
4428  ptr = head = replacement;
4429
4430  /* Flag lines where we might need to replace a single '=' with two;
4431     GAS uses single '=' to assign macro args values, and possibly other
4432     places, so limit what we replace.  */
4433  if (strstr (line, ".if")
4434      || strstr (line, ".elseif")
4435      || strstr (line, ".break"))
4436    line_conditional = 1;
4437
4438  /* Watch out for .eval, so that we avoid doing substitution on the
4439     symbol being assigned a value.  */
4440  if (strstr (line, ".eval") || strstr (line, ".asg"))
4441    eval_line = 1;
4442
4443  /* If it's a macro definition, don't do substitution on the argument
4444     names.  */
4445  if (strstr (line, ".macro"))
4446    return line;
4447
4448  while (!is_end_of_line[(int) *ptr])
4449    {
4450      int current_char = *ptr;
4451
4452      /* Need to update this since LINE may have been modified.  */
4453      if (eval_line)
4454	eval_end = strrchr (ptr, ',');
4455
4456      /* Replace triple double quotes with bounding quote/escapes.  */
4457      if (current_char == '"' && ptr[1] == '"' && ptr[2] == '"')
4458	{
4459	  ptr[1] = '\\';
4460	  tmp = strstr (ptr + 2, "\"\"\"");
4461	  if (tmp)
4462	    tmp[0] = '\\';
4463	  changed = 1;
4464	}
4465
4466      /* Replace a single '=' with a '==';
4467	 for compatibility with older code only.  */
4468      if (line_conditional && current_char == '=')
4469	{
4470	  if (ptr[1] == '=')
4471	    {
4472	      ptr += 2;
4473	      continue;
4474	    }
4475	  *ptr++ = '\0';
4476	  tmp = xmalloc (strlen (head) + 2 + strlen (ptr) + 1);
4477	  sprintf (tmp, "%s==%s", head, ptr);
4478	  /* Continue examining after the '=='.  */
4479	  ptr = tmp + strlen (head) + 2;
4480	  free (replacement);
4481	  head = replacement = tmp;
4482	  changed = 1;
4483	}
4484
4485      /* Flag when we've reached the symbol part of .eval/.asg.  */
4486      if (eval_line && ptr >= eval_end)
4487	eval_symbol = 1;
4488
4489      /* For each apparent symbol, see if it's a substitution symbol, and if
4490	 so, replace it in the input.  */
4491      if ((forced && current_char == ':')
4492	  || (!forced && is_name_beginner (current_char)))
4493	{
4494	  char *name; /* Symbol to be replaced.  */
4495	  char *savedp = input_line_pointer;
4496	  int c;
4497	  char *value = NULL;
4498	  char *tail; /* Rest of line after symbol.  */
4499
4500	  /* Skip the colon.  */
4501	  if (forced)
4502	    ++ptr;
4503
4504	  name = input_line_pointer = ptr;
4505	  c = get_symbol_end ();
4506	  /* '?' is not normally part of a symbol, but it IS part of a local
4507	     label.  */
4508	  if (c == '?')
4509	    {
4510	      *input_line_pointer++ = c;
4511	      c = *input_line_pointer;
4512	      *input_line_pointer = '\0';
4513	    }
4514	  /* Avoid infinite recursion; if a symbol shows up a second time for
4515	     substitution, leave it as is.  */
4516	  if (hash_find (subsym_recurse_hash, name) == NULL)
4517	    value = subsym_lookup (name, macro_level);
4518	  else
4519	    as_warn (_("%s symbol recursion stopped at "
4520		       "second appearance of '%s'"),
4521		     forced ? "Forced substitution" : "Substitution", name);
4522	  ptr = tail = input_line_pointer;
4523	  input_line_pointer = savedp;
4524
4525	  /* Check for local labels; replace them with the appropriate
4526	     substitution.  */
4527	  if ((*name == '$' && ISDIGIT (name[1]) && name[2] == '\0')
4528	      || name[strlen (name) - 1] == '?')
4529	    {
4530	      /* Use an existing identifier for that label if, available, or
4531		 create a new, unique identifier.  */
4532	      value = hash_find (local_label_hash[macro_level], name);
4533	      if (value == NULL)
4534		{
4535		  char digit[11];
4536		  char *namecopy = strcpy (xmalloc (strlen (name) + 1), name);
4537
4538		  value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
4539				  name);
4540		  if (*value != '$')
4541		    value[strlen (value) - 1] = '\0';
4542		  sprintf (digit, ".%d", local_label_id++);
4543		  strcat (value, digit);
4544		  hash_insert (local_label_hash[macro_level], namecopy, value);
4545		}
4546	      /* Indicate where to continue looking for substitutions.  */
4547	      ptr = tail;
4548	    }
4549	  /* Check for built-in subsym and math functions.  */
4550	  else if (value != NULL && *name == '$')
4551	    {
4552	      subsym_proc_entry *entry = (subsym_proc_entry *) value;
4553	      math_proc_entry *math_entry = hash_find (math_hash, name);
4554	      char *arg1, *arg2 = NULL;
4555
4556	      *ptr = c;
4557	      if (entry == NULL)
4558		{
4559		  as_bad (_("Unrecognized substitution symbol function"));
4560		  break;
4561		}
4562	      else if (*ptr != '(')
4563		{
4564		  as_bad (_("Missing '(' after substitution symbol function"));
4565		  break;
4566		}
4567	      ++ptr;
4568	      if (math_entry != NULL)
4569		{
4570		  float farg1, farg2 = 0;
4571		  volatile float fresult;
4572
4573		  farg1 = (float) strtod (ptr, &ptr);
4574		  if (math_entry->nargs == 2)
4575		    {
4576		      if (*ptr++ != ',')
4577			{
4578			  as_bad (_("Expecting second argument"));
4579			  break;
4580			}
4581		      farg2 = (float) strtod (ptr, &ptr);
4582		    }
4583		  fresult = (*math_entry->proc) (farg1, farg2);
4584		  value = xmalloc (128);
4585		  if (math_entry->int_return)
4586		    sprintf (value, "%d", (int) fresult);
4587		  else
4588		    sprintf (value, "%f", fresult);
4589		  if (*ptr++ != ')')
4590		    {
4591		      as_bad (_("Extra junk in function call, expecting ')'"));
4592		      break;
4593		    }
4594		  /* Don't bother recursing; the replacement isn't a
4595                     symbol.  */
4596		  recurse = 0;
4597		}
4598	      else
4599		{
4600		  int val;
4601		  int arg_type[2] = { *ptr == '"' , 0 };
4602		  int ismember = !strcmp (entry->name, "$ismember");
4603
4604		  /* Parse one or two args, which must be a substitution
4605		     symbol, string or a character-string constant.  */
4606		  /* For all functions, a string or substitution symbol may be
4607		     used, with the following exceptions:
4608		     firstch/lastch: 2nd arg must be character constant
4609		     ismember: both args must be substitution symbols.  */
4610		  ptr = subsym_get_arg (ptr, ",)", &arg1, ismember);
4611		  if (!arg1)
4612		    break;
4613		  if (entry->nargs == 2)
4614		    {
4615		      if (*ptr++ != ',')
4616			{
4617			  as_bad (_("Function expects two arguments"));
4618			  break;
4619			}
4620		      /* Character constants are converted to numerics
4621			 by the preprocessor.  */
4622		      arg_type[1] = (ISDIGIT (*ptr)) ? 2 : (*ptr == '"');
4623		      ptr = subsym_get_arg (ptr, ")", &arg2, ismember);
4624		    }
4625		  /* Args checking.  */
4626		  if ((!strcmp (entry->name, "$firstch")
4627		       || !strcmp (entry->name, "$lastch"))
4628		      && arg_type[1] != 2)
4629		    {
4630		      as_bad (_("Expecting character constant argument"));
4631		      break;
4632		    }
4633		  if (ismember
4634		      && (arg_type[0] != 0 || arg_type[1] != 0))
4635		    {
4636		      as_bad (_("Both arguments must be substitution symbols"));
4637		      break;
4638		    }
4639		  if (*ptr++ != ')')
4640		    {
4641		      as_bad (_("Extra junk in function call, expecting ')'"));
4642		      break;
4643		    }
4644		  val = (*entry->proc) (arg1, arg2);
4645		  value = xmalloc (64);
4646		  sprintf (value, "%d", val);
4647		}
4648	      /* Fix things up to replace the entire expression, not just the
4649		 function name.  */
4650	      tail = ptr;
4651	      c = *tail;
4652	    }
4653
4654	  if (value != NULL && !eval_symbol)
4655	    {
4656	      /* Replace the symbol with its string replacement and
4657		 continue.  Recursively replace VALUE until either no
4658		 substitutions are performed, or a substitution that has been
4659		 previously made is encountered again.
4660
4661		 put the symbol into the recursion hash table so we only
4662		 try to replace a symbol once.  */
4663	      if (recurse)
4664		{
4665		  hash_insert (subsym_recurse_hash, name, name);
4666		  value = subsym_substitute (value, macro_level > 0);
4667		  hash_delete (subsym_recurse_hash, name, FALSE);
4668		}
4669
4670	      /* Temporarily zero-terminate where the symbol started.  */
4671	      *name = 0;
4672	      if (forced)
4673		{
4674		  if (c == '(')
4675		    {
4676		      /* Subscripted substitution symbol -- use just the
4677			 indicated portion of the string; the description
4678			 kinda indicates that forced substitution is not
4679			 supposed to be recursive, but I'm not sure.  */
4680		      unsigned beg, len = 1; /* default to a single char */
4681		      char *newval = strcpy (xmalloc (strlen (value) + 1),
4682					     value);
4683
4684		      savedp = input_line_pointer;
4685		      input_line_pointer = tail + 1;
4686		      beg = get_absolute_expression ();
4687		      if (beg < 1)
4688			{
4689			  as_bad (_("Invalid subscript (use 1 to %d)"),
4690				  (int) strlen (value));
4691			  break;
4692			}
4693		      if (*input_line_pointer == ',')
4694			{
4695			  ++input_line_pointer;
4696			  len = get_absolute_expression ();
4697			  if (beg + len > strlen (value))
4698			    {
4699			      as_bad (_("Invalid length (use 0 to %d"),
4700				      (int) strlen (value) - beg);
4701			      break;
4702			    }
4703			}
4704		      newval += beg - 1;
4705		      newval[len] = 0;
4706		      tail = input_line_pointer;
4707		      if (*tail++ != ')')
4708			{
4709			  as_bad (_("Missing ')' in subscripted substitution "
4710				    "symbol expression"));
4711			  break;
4712			}
4713		      c = *tail;
4714		      input_line_pointer = savedp;
4715
4716		      value = newval;
4717		    }
4718		  name[-1] = 0;
4719		}
4720	      tmp = xmalloc (strlen (head) + strlen (value) +
4721			     strlen (tail + 1) + 2);
4722	      strcpy (tmp, head);
4723	      strcat (tmp, value);
4724	      /* Make sure forced substitutions are properly terminated.  */
4725	      if (forced)
4726		{
4727		  if (c != ':')
4728		    {
4729		      as_bad (_("Missing forced substitution terminator ':'"));
4730		      break;
4731		    }
4732		  ++tail;
4733		}
4734	      else
4735		/* Restore the character after the symbol end.  */
4736		*tail = c;
4737	      strcat (tmp, tail);
4738	      /* Continue examining after the replacement value.  */
4739	      ptr = tmp + strlen (head) + strlen (value);
4740	      free (replacement);
4741	      head = replacement = tmp;
4742	      changed = 1;
4743	    }
4744	  else
4745	    *ptr = c;
4746	}
4747      else
4748	{
4749	  ++ptr;
4750	}
4751    }
4752
4753  if (changed)
4754    return replacement;
4755  else
4756    return line;
4757}
4758
4759/* We use this to handle substitution symbols
4760   hijack input_line_pointer, replacing it with our substituted string.
4761
4762   .sslist should enable listing the line after replacements are made...
4763
4764   returns the new buffer limit.  */
4765
4766void
4767tic54x_start_line_hook (void)
4768{
4769  char *line, *endp;
4770  char *replacement = NULL;
4771
4772  /* Work with a copy of the input line, including EOL char.  */
4773  endp = input_line_pointer;
4774  while (!is_end_of_line[(int) *endp++])
4775    ;
4776  line = xmalloc (endp - input_line_pointer + 1);
4777  strncpy (line, input_line_pointer, endp - input_line_pointer + 1);
4778  line[endp - input_line_pointer] = 0;
4779
4780  /* Scan ahead for parallel insns.  */
4781  parallel_on_next_line_hint = next_line_shows_parallel (endp + 1);
4782
4783  /* If within a macro, first process forced replacements.  */
4784  if (macro_level > 0)
4785    replacement = subsym_substitute (line, 1);
4786  else
4787    replacement = line;
4788  replacement = subsym_substitute (replacement, 0);
4789
4790  if (replacement != line)
4791    {
4792      char *tmp = replacement;
4793      char *comment = strchr (replacement, ';');
4794      char endc = replacement[strlen (replacement) - 1];
4795
4796      /* Clean up the replacement; we'd prefer to have this done by the
4797	 standard preprocessing equipment (maybe do_scrub_chars?)
4798	 but for now, do a quick-and-dirty.  */
4799      if (comment != NULL)
4800	{
4801	  comment[0] = endc;
4802	  comment[1] = 0;
4803	  --comment;
4804	}
4805      else
4806	comment = replacement + strlen (replacement) - 1;
4807
4808      /* Trim trailing whitespace.  */
4809      while (ISSPACE (*comment))
4810	{
4811	  comment[0] = endc;
4812	  comment[1] = 0;
4813	  --comment;
4814	}
4815
4816      /* Compact leading whitespace.  */
4817      while (ISSPACE (tmp[0]) && ISSPACE (tmp[1]))
4818	++tmp;
4819
4820      input_line_pointer = endp;
4821      input_scrub_insert_line (tmp);
4822      free (replacement);
4823      free (line);
4824      /* Keep track of whether we've done a substitution.  */
4825      substitution_line = 1;
4826    }
4827  else
4828    {
4829      /* No change.  */
4830      free (line);
4831      substitution_line = 0;
4832    }
4833}
4834
4835/* This is the guts of the machine-dependent assembler.  STR points to a
4836   machine dependent instruction.  This function is supposed to emit
4837   the frags/bytes it assembles to.  */
4838void
4839md_assemble (char *line)
4840{
4841  static int repeat_slot = 0;
4842  static int delay_slots = 0; /* How many delay slots left to fill?  */
4843  static int is_parallel = 0;
4844  static tic54x_insn insn;
4845  char *lptr;
4846  char *savedp = input_line_pointer;
4847  int c;
4848
4849  input_line_pointer = line;
4850  c = get_symbol_end ();
4851
4852  if (cpu == VNONE)
4853    cpu = V542;
4854  if (address_mode_needs_set)
4855    {
4856      set_address_mode (amode);
4857      address_mode_needs_set = 0;
4858    }
4859  if (cpu_needs_set)
4860    {
4861      set_cpu (cpu);
4862      cpu_needs_set = 0;
4863    }
4864  assembly_begun = 1;
4865
4866  if (is_parallel)
4867    {
4868      is_parallel = 0;
4869
4870      strcpy (insn.parmnemonic, line);
4871      lptr = input_line_pointer;
4872      *lptr = c;
4873      input_line_pointer = savedp;
4874
4875      if (tic54x_parse_parallel_insn_lastline (&insn, lptr))
4876	{
4877	  int words = build_insn (&insn);
4878
4879	  if (delay_slots != 0)
4880	    {
4881	      if (words > delay_slots)
4882		{
4883		  as_bad (_("Instruction does not fit in available delay "
4884			    "slots (%d-word insn, %d slots left)"),
4885			  words, delay_slots);
4886		  delay_slots = 0;
4887		  return;
4888		}
4889	      delay_slots -= words;
4890	    }
4891	}
4892      return;
4893    }
4894
4895  memset (&insn, 0, sizeof (insn));
4896  strcpy (insn.mnemonic, line);
4897  lptr = input_line_pointer;
4898  *lptr = c;
4899  input_line_pointer = savedp;
4900
4901  /* See if this line is part of a parallel instruction; if so, either this
4902     line or the next line will have the "||" specifier preceding the
4903     mnemonic, and we look for it in the parallel insn hash table.  */
4904  if (strstr (line, "||") != NULL || parallel_on_next_line_hint)
4905    {
4906      char *tmp = strstr (line, "||");
4907      if (tmp != NULL)
4908	*tmp = '\0';
4909
4910      if (tic54x_parse_parallel_insn_firstline (&insn, lptr))
4911	{
4912	  is_parallel = 1;
4913	  /* If the parallel part is on the same line, process it now,
4914	     otherwise let the assembler pick up the next line for us.  */
4915	  if (tmp != NULL)
4916	    {
4917	      while (ISSPACE (tmp[2]))
4918		++tmp;
4919	      md_assemble (tmp + 2);
4920	    }
4921	}
4922      else
4923	{
4924	  as_bad (_("Unrecognized parallel instruction '%s'"), line);
4925	}
4926      return;
4927    }
4928
4929  if (tic54x_parse_insn (&insn, lptr))
4930    {
4931      int words;
4932
4933      if ((insn.tm->flags & FL_LP)
4934	  && cpu != V545LP && cpu != V546LP)
4935	{
4936	  as_bad (_("Instruction '%s' requires an LP cpu version"),
4937		  insn.tm->name);
4938	  return;
4939	}
4940      if ((insn.tm->flags & FL_FAR)
4941	  && amode != far_mode)
4942	{
4943	  as_bad (_("Instruction '%s' requires far mode addressing"),
4944		  insn.tm->name);
4945	  return;
4946	}
4947
4948      words = build_insn (&insn);
4949
4950      /* Is this instruction in a delay slot?  */
4951      if (delay_slots)
4952	{
4953	  if (words > delay_slots)
4954	    {
4955	      as_warn (_("Instruction does not fit in available delay "
4956			 "slots (%d-word insn, %d slots left). "
4957			 "Resulting behavior is undefined."),
4958		       words, delay_slots);
4959	      delay_slots = 0;
4960	      return;
4961	    }
4962	  /* Branches in delay slots are not allowed.  */
4963	  if (insn.tm->flags & FL_BMASK)
4964	    {
4965	      as_warn (_("Instructions which cause PC discontinuity are not "
4966			 "allowed in a delay slot. "
4967			 "Resulting behavior is undefined."));
4968	    }
4969	  delay_slots -= words;
4970	}
4971
4972      /* Is this instruction the target of a repeat?  */
4973      if (repeat_slot)
4974	{
4975	  if (insn.tm->flags & FL_NR)
4976	    as_warn (_("'%s' is not repeatable. "
4977		       "Resulting behavior is undefined."),
4978		     insn.tm->name);
4979	  else if (insn.is_lkaddr)
4980	    as_warn (_("Instructions using long offset modifiers or absolute "
4981		       "addresses are not repeatable. "
4982		       "Resulting behavior is undefined."));
4983	  repeat_slot = 0;
4984	}
4985
4986      /* Make sure we check the target of a repeat instruction.  */
4987      if (insn.tm->flags & B_REPEAT)
4988	{
4989	  repeat_slot = 1;
4990	  /* FIXME -- warn if repeat_slot == 1 at EOF.  */
4991	}
4992      /* Make sure we check our delay slots for validity.  */
4993      if (insn.tm->flags & FL_DELAY)
4994	{
4995	  delay_slots = 2;
4996	  /* FIXME -- warn if delay_slots != 0 at EOF.  */
4997	}
4998    }
4999}
5000
5001/* Do a final adjustment on the symbol table; in this case, make sure we have
5002   a ".file" symbol.  */
5003
5004void
5005tic54x_adjust_symtab (void)
5006{
5007  if (symbol_rootP == NULL
5008      || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
5009    {
5010      char *filename;
5011      unsigned lineno;
5012      as_where (&filename, &lineno);
5013      c_dot_file_symbol (filename, 0);
5014    }
5015}
5016
5017/* In order to get gas to ignore any | chars at the start of a line,
5018   this function returns true if a | is found in a line.
5019   This lets us process parallel instructions, which span two lines.  */
5020
5021int
5022tic54x_unrecognized_line (int c)
5023{
5024  return c == PARALLEL_SEPARATOR;
5025}
5026
5027/* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
5028   Encode their names so that only we see them and can map them to the
5029   appropriate places.
5030   FIXME -- obviously this isn't done yet.  These locals still show up in the
5031   symbol table.  */
5032void
5033tic54x_define_label (symbolS *sym)
5034{
5035  /* Just in case we need this later; note that this is not necessarily the
5036     same thing as line_label...
5037     When aligning or assigning labels to fields, sometimes the label is
5038     assigned other than the address at which the label appears.
5039     FIXME -- is this really needed? I think all the proper label assignment
5040     is done in tic54x_cons.  */
5041  last_label_seen = sym;
5042}
5043
5044/* Try to parse something that normal parsing failed at.  */
5045
5046symbolS *
5047tic54x_undefined_symbol (char *name)
5048{
5049  symbol *sym;
5050
5051  /* Not sure how to handle predefined symbols.  */
5052  if ((sym = (symbol *) hash_find (cc_hash, name)) != NULL ||
5053      (sym = (symbol *) hash_find (cc2_hash, name)) != NULL ||
5054      (sym = (symbol *) hash_find (cc3_hash, name)) != NULL ||
5055      (sym = (symbol *) hash_find (misc_symbol_hash, name)) != NULL ||
5056      (sym = (symbol *) hash_find (sbit_hash, name)) != NULL)
5057    {
5058      return symbol_new (name, reg_section,
5059			 (valueT) sym->value,
5060			 &zero_address_frag);
5061    }
5062
5063  if ((sym = (symbol *) hash_find (reg_hash, name)) != NULL ||
5064      (sym = (symbol *) hash_find (mmreg_hash, name)) != NULL ||
5065      !strcasecmp (name, "a") || !strcasecmp (name, "b"))
5066    {
5067      return symbol_new (name, reg_section,
5068			 (valueT) sym ? sym->value : 0,
5069			 &zero_address_frag);
5070    }
5071
5072  return NULL;
5073}
5074
5075/* Parse a name in an expression before the expression parser takes a stab at
5076   it.  */
5077
5078int
5079tic54x_parse_name (char *name ATTRIBUTE_UNUSED,
5080		   expressionS *expn ATTRIBUTE_UNUSED)
5081{
5082  return 0;
5083}
5084
5085char *
5086md_atof (int type, char *literalP, int *sizeP)
5087{
5088  /* Target data is little-endian, but floats are stored
5089     big-"word"ian.  ugh.  */
5090  return ieee_md_atof (type, literalP, sizeP, TRUE);
5091}
5092
5093arelent *
5094tc_gen_reloc (asection *section, fixS *fixP)
5095{
5096  arelent *rel;
5097  bfd_reloc_code_real_type code = fixP->fx_r_type;
5098  asymbol *sym = symbol_get_bfdsym (fixP->fx_addsy);
5099
5100  rel = (arelent *) xmalloc (sizeof (arelent));
5101  rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5102  *rel->sym_ptr_ptr = sym;
5103  /* We assume that all rel->address are host byte offsets.  */
5104  rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
5105  rel->address /= OCTETS_PER_BYTE;
5106  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
5107  if (!strcmp (sym->name, section->name))
5108    rel->howto += HOWTO_BANK;
5109
5110  if (!rel->howto)
5111    {
5112      const char *name = S_GET_NAME (fixP->fx_addsy);
5113      if (name == NULL)
5114	name = "<unknown>";
5115      as_fatal ("Cannot generate relocation type for symbol %s, code %s",
5116		name, bfd_get_reloc_code_name (code));
5117      return NULL;
5118    }
5119  return rel;
5120}
5121
5122/* Handle cons expressions.  */
5123
5124void
5125tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn)
5126{
5127  bfd_reloc_code_real_type r;
5128
5129  switch (octets)
5130    {
5131    default:
5132      as_bad (_("Unsupported relocation size %d"), octets);
5133      r = BFD_RELOC_TIC54X_16_OF_23;
5134      break;
5135    case 2:
5136      r = BFD_RELOC_TIC54X_16_OF_23;
5137      break;
5138    case 4:
5139      /* TI assembler always uses this, regardless of addressing mode.  */
5140      if (emitting_long)
5141	r = BFD_RELOC_TIC54X_23;
5142      else
5143	/* We never want to directly generate this; this is provided for
5144	   stabs support only.  */
5145	r = BFD_RELOC_32;
5146      break;
5147    }
5148  fix_new_exp (frag, where, octets, expn, 0, r);
5149}
5150
5151/* Attempt to simplify or even eliminate a fixup.
5152   To indicate that a fixup has been eliminated, set fixP->fx_done.
5153
5154   If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry.   */
5155
5156void
5157md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
5158{
5159  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5160  valueT val = * valP;
5161
5162  switch (fixP->fx_r_type)
5163    {
5164    default:
5165      as_fatal ("Bad relocation type: 0x%02x", fixP->fx_r_type);
5166      return;
5167    case BFD_RELOC_TIC54X_MS7_OF_23:
5168      val = (val >> 16) & 0x7F;
5169      /* Fall through.  */
5170    case BFD_RELOC_TIC54X_16_OF_23:
5171    case BFD_RELOC_16:
5172      bfd_put_16 (stdoutput, val, buf);
5173      /* Indicate what we're actually writing, so that we don't get warnings
5174	 about exceeding available space.  */
5175      *valP = val & 0xFFFF;
5176      break;
5177    case BFD_RELOC_TIC54X_PARTLS7:
5178      bfd_put_16 (stdoutput,
5179		  (bfd_get_16 (stdoutput, buf) & 0xFF80) | (val & 0x7F),
5180		  buf);
5181      /* Indicate what we're actually writing, so that we don't get warnings
5182	 about exceeding available space.  */
5183      *valP = val & 0x7F;
5184      break;
5185    case BFD_RELOC_TIC54X_PARTMS9:
5186      /* TI assembler doesn't shift its encoding for relocatable files, and is
5187	 thus incompatible with this implementation's relocatable files.  */
5188      bfd_put_16 (stdoutput,
5189		  (bfd_get_16 (stdoutput, buf) & 0xFE00) | (val >> 7),
5190		  buf);
5191      break;
5192    case BFD_RELOC_32:
5193    case BFD_RELOC_TIC54X_23:
5194      bfd_put_32 (stdoutput,
5195		  (bfd_get_32 (stdoutput, buf) & 0xFF800000) | val,
5196		  buf);
5197      break;
5198    }
5199
5200  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
5201    fixP->fx_done = 1;
5202}
5203
5204/* This is our chance to record section alignment
5205   don't need to do anything here, since BFD does the proper encoding.  */
5206
5207valueT
5208md_section_align (segT segment ATTRIBUTE_UNUSED, valueT section_size)
5209{
5210  return section_size;
5211}
5212
5213long
5214md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
5215{
5216  return 0;
5217}
5218
5219/* Mostly little-endian, but longwords (4 octets) get MS word stored
5220   first.  */
5221
5222void
5223tic54x_number_to_chars (char *buf, valueT val, int n)
5224{
5225  if (n != 4)
5226    number_to_chars_littleendian (buf, val, n);
5227  else
5228    {
5229      number_to_chars_littleendian (buf    , val >> 16   , 2);
5230      number_to_chars_littleendian (buf + 2, val & 0xFFFF, 2);
5231    }
5232}
5233
5234int
5235tic54x_estimate_size_before_relax (fragS *frag ATTRIBUTE_UNUSED,
5236				   segT seg ATTRIBUTE_UNUSED)
5237{
5238  return 0;
5239}
5240
5241/* We use this to handle bit allocations which we couldn't handle before due
5242   to symbols being in different frags.  return number of octets added.  */
5243
5244int
5245tic54x_relax_frag (fragS *frag, long stretch ATTRIBUTE_UNUSED)
5246{
5247  symbolS *sym = frag->fr_symbol;
5248  int growth = 0;
5249  int i;
5250
5251  if (sym != NULL)
5252    {
5253      struct bit_info *bi = (struct bit_info *) frag->fr_opcode;
5254      int bit_offset = frag_bit_offset (frag_prev (frag, bi->seg), bi->seg);
5255      int size = S_GET_VALUE (sym);
5256      fragS *prev_frag = bit_offset_frag (frag_prev (frag, bi->seg), bi->seg);
5257      int available = 16 - bit_offset;
5258
5259      if (symbol_get_frag (sym) != &zero_address_frag
5260	  || S_IS_COMMON (sym)
5261	  || !S_IS_DEFINED (sym))
5262	as_bad_where (frag->fr_file, frag->fr_line,
5263		      _("non-absolute value used with .space/.bes"));
5264
5265      if (size < 0)
5266	{
5267	  as_warn (_("negative value ignored in %s"),
5268		   bi->type == TYPE_SPACE ? ".space" :
5269		   bi->type == TYPE_BES ? ".bes" : ".field");
5270	  growth = 0;
5271	  frag->tc_frag_data = frag->fr_fix = 0;
5272	  return 0;
5273	}
5274
5275      if (bi->type == TYPE_FIELD)
5276	{
5277	  /* Bit fields of 16 or larger will have already been handled.  */
5278	  if (bit_offset != 0 && available >= size)
5279	    {
5280	      char *p = prev_frag->fr_literal;
5281
5282	      valueT value = bi->value;
5283	      value <<= available - size;
5284	      value |= ((unsigned short) p[1] << 8) | p[0];
5285	      md_number_to_chars (p, value, 2);
5286	      if ((prev_frag->tc_frag_data += size) == 16)
5287		prev_frag->tc_frag_data = 0;
5288	      if (bi->sym)
5289		symbol_set_frag (bi->sym, prev_frag);
5290	      /* This frag is no longer used.  */
5291	      growth = -frag->fr_fix;
5292	      frag->fr_fix = 0;
5293	      frag->tc_frag_data = 0;
5294	    }
5295	  else
5296	    {
5297	      char *p = frag->fr_literal;
5298
5299	      valueT value = bi->value << (16 - size);
5300	      md_number_to_chars (p, value, 2);
5301	      if ((frag->tc_frag_data = size) == 16)
5302		frag->tc_frag_data = 0;
5303	      growth = 0;
5304	    }
5305	}
5306      else
5307	{
5308	  if (bit_offset != 0 && bit_offset < 16)
5309	    {
5310	      if (available >= size)
5311		{
5312		  if ((prev_frag->tc_frag_data += size) == 16)
5313		    prev_frag->tc_frag_data = 0;
5314		  if (bi->sym)
5315		    symbol_set_frag (bi->sym, prev_frag);
5316		  /* This frag is no longer used.  */
5317		  growth = -frag->fr_fix;
5318		  frag->fr_fix = 0;
5319		  frag->tc_frag_data = 0;
5320		  goto getout;
5321		}
5322	      if (bi->type == TYPE_SPACE && bi->sym)
5323		symbol_set_frag (bi->sym, prev_frag);
5324	      size -= available;
5325	    }
5326	  growth = (size + 15) / 16 * OCTETS_PER_BYTE - frag->fr_fix;
5327	  for (i = 0; i < growth; i++)
5328	    frag->fr_literal[i] = 0;
5329	  frag->fr_fix = growth;
5330	  frag->tc_frag_data = size % 16;
5331	  /* Make sure any BES label points to the LAST word allocated.  */
5332	  if (bi->type == TYPE_BES && bi->sym)
5333	    S_SET_VALUE (bi->sym, frag->fr_fix / OCTETS_PER_BYTE - 1);
5334	}
5335    getout:
5336      frag->fr_symbol = 0;
5337      frag->fr_opcode = 0;
5338      free ((void *) bi);
5339    }
5340  return growth;
5341}
5342
5343void
5344tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
5345		     segT seg ATTRIBUTE_UNUSED,
5346		     fragS *frag)
5347{
5348  /* Offset is in bytes.  */
5349  frag->fr_offset = (frag->fr_next->fr_address
5350		     - frag->fr_address
5351		     - frag->fr_fix) / frag->fr_var;
5352  if (frag->fr_offset < 0)
5353    {
5354      as_bad_where (frag->fr_file, frag->fr_line,
5355		    _("attempt to .space/.bes backwards? (%ld)"),
5356		    (long) frag->fr_offset);
5357    }
5358  frag->fr_type = rs_space;
5359}
5360
5361/* We need to avoid having labels defined for certain directives/pseudo-ops
5362   since once the label is defined, it's in the symbol table for good.  TI
5363   syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
5364   I guess, except I've never seen a definition of MRI syntax).
5365
5366   C is the character that used to be at *REST, which points to the end of the
5367   label.
5368
5369   Don't allow labels to start with '.'  */
5370
5371int
5372tic54x_start_label (int c, char *rest)
5373{
5374  /* If within .struct/.union, no auto line labels, please.  */
5375  if (current_stag != NULL)
5376    return 0;
5377
5378  /* Disallow labels starting with "."  */
5379  if (c != ':')
5380    {
5381      char *label = rest;
5382
5383      while (!is_end_of_line[(int) label[-1]])
5384	--label;
5385      if (*label == '.')
5386	{
5387	  as_bad (_("Invalid label '%s'"), label);
5388	  return 0;
5389	}
5390    }
5391
5392  if (is_end_of_line[(int) c])
5393    return 1;
5394
5395  if (ISSPACE (c))
5396    while (ISSPACE (c = *++rest))
5397      ;
5398  if (c == '.')
5399    {
5400      /* Don't let colon () define a label for any of these...  */
5401      return (strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
5402	&& (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
5403	&& (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
5404	&& (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
5405	&& (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
5406	&& (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4]));
5407    }
5408
5409  return 1;
5410}
5411