Various fixes for the Z80 support.
[deliverable/binutils-gdb.git] / gas / config / tc-tic54x.c
index b6376f1da83c667b5ffdae4bda776a396083c6b2..736192a61712630d934dd4b0484fe104eb34212b 100644 (file)
@@ -1,12 +1,12 @@
 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
-   Copyright (C) 1999, 2000 Free Software Foundation.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
    Contributed by Timothy Wall (twall@cygnus.com)
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
@@ -16,8 +16,8 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 /* Texas Instruments TMS320C54X machine specific gas.
    Written by Timothy Wall (twall@alum.mit.edu).
    We don't convert '' to '\0'
    We don't allow strings with .byte/.half/.short/.long
    Probably details of the subsym stuff are different
-   TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.  */
+   TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
+
+   COFF1 limits section names to 8 characters.
+   Some of the default behavior changed from COFF1 to COFF2.  */
 
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
 #include "as.h"
+#include <limits.h>
+#include "safe-ctype.h"
 #include "sb.h"
 #include "macro.h"
 #include "subsegs.h"
-#include "struc-symbol.h"
 #include "opcode/tic54x.h"
 #include "obj-coff.h"
 #include <math.h>
 
+
+static struct stag
+{
+  symbolS *sym;                        /* Symbol for this stag; value is offset.  */
+  const char *name;            /* Shortcut to symbol name.  */
+  bfd_vma size;                        /* Size of struct/union.  */
+  int current_bitfield_offset;  /* Temporary for tracking fields.  */
+  int is_union;
+  struct stag_field            /* List of fields.  */
+  {
+    const char *name;
+    bfd_vma offset;            /* Of start of this field.  */
+    int bitfield_offset;       /* Of start of this field.  */
+    struct stag *stag;         /* If field is struct/union.  */
+    struct stag_field *next;
+  } *field;
+  /* For nesting; used only in stag construction.  */
+  struct stag *inner;          /* Enclosed .struct.  */
+  struct stag *outer;          /* Enclosing .struct.  */
+} *current_stag = NULL;
+
 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm.  */
 
-const char comment_chars[] = ";";
-const char line_comment_chars[] = ";*#"; /* at column zero only */
-const char line_separator_chars[] = ""; /* not permitted */
+typedef struct _tic54x_insn
+{
+  const insn_template *tm;     /* Opcode template.  */
 
-/* Characters which indicate that this is a floating point constant.  */
-const char FLT_CHARS[] = "fF";
-/* Characters that can be used to separate mantissa from exp in FP
-   nums.  */
-const char EXP_CHARS[] = "eE";
+  char mnemonic[MAX_LINE];     /* Opcode name/mnemonic.  */
+  char parmnemonic[MAX_LINE];   /* 2nd mnemonic of parallel insn.  */
 
-/* Only word (et al.), align, or conditionals are allowed within
-   .struct/.union.  */
-#define ILLEGAL_WITHIN_STRUCT() \
-do if (current_stag != NULL){ \
-as_bad (_("pseudo-op illegal within .struct/.union"));return; } while (0)
+  int opcount;
+  struct opstruct
+  {
+    char buf[MAX_LINE];
+    enum optype type;
+    expressionS exp;
+  } operands[MAX_OPERANDS];
 
-void
-md_show_usage (stream)
-     FILE *stream;
-{
-  fprintf (stream, _("C54x-specific command line  options:\n"));
-  fprintf (stream, _("-mfar-mode | -mf          Use extended addressing\n"));
-  fprintf (stream, _("-mcpu=<CPU version>       Specify the CPU version\n"));
-#if 0
-  fprintf (stream, _("-mcoff-version={0|1|2}    Select COFF version\n"));
-#endif
-  fprintf (stream, _("-merrors-to-file <filename>\n"));
-  fprintf (stream, _("-me <filename>            Redirect errors to a file\n"));
-}
+  int paropcount;
+  struct opstruct paroperands[MAX_OPERANDS];
 
-const char *md_shortopts = "";
+  int is_lkaddr;
+  int lkoperand;
+  int words;                   /* Size of insn in 16-bit words.  */
+  int using_default_dst;       /* Do we need to explicitly set an
+                                  omitted OP_DST operand?  */
+  struct
+  {
+    unsigned short word;            /* Final encoded opcode data.  */
+    int unresolved;
+    int r_nchars;                   /* Relocation size.  */
+    bfd_reloc_code_real_type r_type; /* Relocation type.  */
+    expressionS addr_expr;          /* Storage for unresolved expressions.  */
+  } opcode[3];
+} tic54x_insn;
 
 enum cpu_version
 {
@@ -95,24 +118,41 @@ enum cpu_version
 
 enum address_mode
 {
-  c_mode,   /* 16-bit addresses */
-  far_mode  /* >16-bit addresses */
+  c_mode,   /* 16-bit addresses */
+  far_mode  /* >16-bit addresses */
 };
 
+static segT stag_saved_seg;
+static subsegT stag_saved_subseg;
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = ";*#"; /* At column zero only.  */
+const char line_separator_chars[] = ""; /* Not permitted.  */
+
+int emitting_long = 0;
+
+/* Characters which indicate that this is a floating point constant.  */
+const char FLT_CHARS[] = "fF";
+
+/* Characters that can be used to separate mantissa from exp in FP
+   nums.  */
+const char EXP_CHARS[] = "eE";
+
+const char *md_shortopts = "";
+
 #define OPTION_ADDRESS_MODE     (OPTION_MD_BASE)
-#define OPTION_CPU_VERSION      (OPTION_ADDRESS_MODE+1)
-#define OPTION_COFF_VERSION     (OPTION_CPU_VERSION+1)
-#define OPTION_STDERR_TO_FILE   (OPTION_COFF_VERSION+1)
+#define OPTION_CPU_VERSION      (OPTION_ADDRESS_MODE + 1)
+#define OPTION_COFF_VERSION     (OPTION_CPU_VERSION + 1)
+#define OPTION_STDERR_TO_FILE   (OPTION_COFF_VERSION + 1)
 
-struct option md_longopts[] = 
+struct option md_longopts[] =
 {
-  { "mfar-mode",       no_argument,         NULL, OPTION_ADDRESS_MODE },
-  { "mf",              no_argument,         NULL, OPTION_ADDRESS_MODE },
-  { "mcpu",            required_argument,   NULL, OPTION_CPU_VERSION },
-  /*  { "mcoff-version",   required_argument,   NULL, OPTION_COFF_VERSION },*/
+  { "mfar-mode",       no_argument,        NULL, OPTION_ADDRESS_MODE },
+  { "mf",             no_argument,         NULL, OPTION_ADDRESS_MODE },
+  { "mcpu",           required_argument,   NULL, OPTION_CPU_VERSION },
   { "merrors-to-file", required_argument,   NULL, OPTION_STDERR_TO_FILE },
-  { "me",              required_argument,   NULL, OPTION_STDERR_TO_FILE },
-  { NULL, no_argument, NULL, 0},
+  { "me",             required_argument,   NULL, OPTION_STDERR_TO_FILE },
+  { NULL,              no_argument,         NULL, 0},
 };
 
 size_t md_longopts_size = sizeof (md_longopts);
@@ -120,7 +160,7 @@ size_t md_longopts_size = sizeof (md_longopts);
 static int assembly_begun = 0;
 /* Addressing mode is not entirely implemented; the latest rev of the Other
    assembler doesn't seem to make any distinction whatsoever; all relocations
-   are stored as extended relocatiosn.  Older versions used REL16 vs RELEXT16,
+   are stored as extended relocations.  Older versions used REL16 vs RELEXT16,
    but now it seems all relocations are RELEXT16.  We use all RELEXT16.
 
    The cpu version is kind of a waste of time as well.  There is one
@@ -131,19 +171,24 @@ static enum cpu_version cpu = VNONE;
 
 /* Include string substitutions in listing?  */
 static int listing_sslist = 0;
+
 /* Did we do subsym substitutions on the line?  */
 static int substitution_line = 0;
+
 /* Last label seen.  */
 static symbolS *last_label_seen = NULL;
+
 /* This ensures that all new labels are unique.  */
 static int local_label_id;
 
-static struct hash_control *subsym_recurse_hash; /* prevent infinite recurse */
-static struct hash_control *math_hash; /* built-in math functions */
+static struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse.  */
+static struct hash_control *math_hash; /* Built-in math functions.  */
 /* Allow maximum levels of macro nesting; level 0 is the main substitution
    symbol table.  The other assembler only does 32 levels, so there!  */
-static struct hash_control *subsym_hash[100];
-/* Keep track of local labels so we can substitute them before GAS sees them 
+#define MAX_SUBSYM_HASH 100
+static struct hash_control *subsym_hash[MAX_SUBSYM_HASH];
+
+/* Keep track of local labels so we can substitute them before GAS sees them
    since macros use their own 'namespace' for local labels, use a separate hash
 
    We do our own local label handling 'cuz it's subtly different from the
@@ -165,77 +210,49 @@ static struct hash_control *cc3_hash;
 static struct hash_control *sbit_hash;
 static struct hash_control *misc_symbol_hash;
 
-static char *subsym_substitute PARAMS ((char *line, int forced));
-static char *subsym_lookup PARAMS ((char *name, int nest_level));
-static void subsym_create_or_replace PARAMS ((char *name, char *value));
-static float math_ceil PARAMS ((float, float));
-static float math_cvi PARAMS ((float, float));
-static float math_floor PARAMS ((float, float));
-static float math_fmod PARAMS ((float, float));
-static float math_int PARAMS ((float, float));
-static float math_round PARAMS ((float, float));
-static float math_sgn PARAMS ((float, float));
-static float math_trunc PARAMS ((float, float));
-static float math_acos PARAMS ((float, float));
-static float math_asin PARAMS ((float, float));
-static float math_atan PARAMS ((float, float));
-static float math_atan2 PARAMS ((float, float));
-static float math_cosh PARAMS ((float, float));
-static float math_cos PARAMS ((float, float));
-static float math_cvf PARAMS ((float, float));
-static float math_exp PARAMS ((float, float));
-static float math_fabs PARAMS ((float, float));
-static float math_ldexp PARAMS ((float, float));
-static float math_log10 PARAMS ((float, float));
-static float math_log PARAMS ((float, float));
-static float math_max PARAMS ((float, float));
-static float math_pow PARAMS ((float, float));
-static float math_sin PARAMS ((float, float));
-static float math_sinh PARAMS ((float, float));
-static float math_sqrt PARAMS ((float, float));
-static float math_tan PARAMS ((float, float));
-static float math_tanh PARAMS ((float, float));
+/* Only word (et al.), align, or conditionals are allowed within
+   .struct/.union.  */
+#define ILLEGAL_WITHIN_STRUCT()                                        \
+  do                                                           \
+    if (current_stag != NULL)                                  \
+      {                                                        \
+       as_bad (_("pseudo-op illegal within .struct/.union"));  \
+       return;                                                 \
+      }                                                                \
+  while (0)
 
-static struct stag
+
+static void subsym_create_or_replace (char *, char *);
+static char *subsym_lookup (char *, int);
+static char *subsym_substitute (char *, int);
+
+
+void
+md_show_usage (FILE *stream)
 {
-  symbolS *sym;                     /* symbol for this stag; value is offset */
-  const char *name;                 /* shortcut to symbol name */
-  bfd_vma size;                     /* size of struct/union */
-  int current_bitfield_offset;      /* temporary for tracking fields */
-  int is_union;
-  struct stag_field                 /* list of fields */
-  {
-    const char *name;
-    bfd_vma offset;                 /* of start of this field */
-    int bitfield_offset;            /* of start of this field */
-    struct stag *stag;              /* if field is struct/union */
-    struct stag_field *next;
-  } *field;
-  /* for nesting; used only in stag construction */
-  struct stag *inner;               /* enclosed .struct */
-  struct stag *outer;               /* enclosing .struct */
-} *current_stag = NULL;
+  fprintf (stream, _("C54x-specific command line options:\n"));
+  fprintf (stream, _("-mfar-mode | -mf          Use extended addressing\n"));
+  fprintf (stream, _("-mcpu=<CPU version>       Specify the CPU version\n"));
+  fprintf (stream, _("-merrors-to-file <filename>\n"));
+  fprintf (stream, _("-me <filename>            Redirect errors to a file\n"));
+}
 
-static segT stag_saved_seg;
-static subsegT stag_saved_subseg;
+/* Output a single character (upper octet is zero).  */
 
-/* Output a single character (upper octect is zero).  */
 static void
-tic54x_emit_char (c)
-     char c;
+tic54x_emit_char (char c)
 {
-  expressionS exp;
+  expressionS expn;
 
-  exp.X_op = O_constant;
-  exp.X_add_number = c;
-  emit_expr (&exp, 2);
+  expn.X_op = O_constant;
+  expn.X_add_number = c;
+  emit_expr (&expn, 2);
 }
 
 /* Walk backwards in the frag chain.  */
+
 static fragS *
-frag_prev (frag, seg)
-     fragS *frag;
-     segT seg;
+frag_prev (fragS *frag, segT seg)
 {
   segment_info_type *seginfo = seg_info (seg);
   fragS *fragp;
@@ -243,14 +260,12 @@ frag_prev (frag, seg)
   for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
     if (fragp->fr_next == frag)
       return fragp;
-  
+
   return NULL;
 }
 
 static fragS *
-bit_offset_frag (frag, seg)
-     fragS *frag;
-     segT seg;
+bit_offset_frag (fragS *frag, segT seg)
 {
   while (frag != NULL)
     {
@@ -266,13 +281,12 @@ bit_offset_frag (frag, seg)
 
 /* Return the number of bits allocated in the most recent word, or zero if
    none. .field/.space/.bes may leave words partially allocated.  */
+
 static int
-frag_bit_offset (frag, seg)
-     fragS *frag;
-     segT seg;
+frag_bit_offset (fragS *frag, segT seg)
 {
   frag = bit_offset_frag (frag, seg);
-  
+
   if (frag)
     return frag->fr_opcode != NULL ? -1 : frag->tc_frag_data;
 
@@ -281,33 +295,33 @@ frag_bit_offset (frag, seg)
 
 /* Read an expression from a C string; returns a pointer past the end of the
    expression.  */
+
 static char *
-parse_expression (char *str, expressionS * exp)
+parse_expression (char *str, expressionS *expn)
 {
   char *s;
   char *tmp;
 
   tmp = input_line_pointer;    /* Save line pointer.  */
   input_line_pointer = str;
-  expression (exp);
+  expression (expn);
   s = input_line_pointer;
   input_line_pointer = tmp;    /* Restore line pointer.  */
   return s;                    /* Return pointer to where parsing stopped.  */
 }
 
-/* .asg "character-string"|character-string, symbol 
-   
+/* .asg "character-string"|character-string, symbol
+
    .eval is the only pseudo-op allowed to perform arithmetic on substitution
    symbols.  all other use of symbols defined with .asg are currently
    unsupported.  */
+
 static void
-tic54x_asg (x)
-     int x ATTRIBUTE_UNUSED;
+tic54x_asg (int x ATTRIBUTE_UNUSED)
 {
   int c;
   char *name;
   char *str;
-  char *tmp;
   int quoted = *input_line_pointer == '"';
 
   ILLEGAL_WITHIN_STRUCT ();
@@ -323,7 +337,7 @@ tic54x_asg (x)
       str = input_line_pointer;
       while ((c = *input_line_pointer) != ',')
        {
-         if (is_end_of_line[(int) *input_line_pointer])
+         if (is_end_of_line[(unsigned char) c])
            break;
          ++input_line_pointer;
        }
@@ -336,34 +350,30 @@ tic54x_asg (x)
       return;
     }
 
-  name = ++input_line_pointer;
-  c = get_symbol_end ();       /* Get terminator.  */
-  if (!isalpha (*name))
+  ++input_line_pointer;
+  c = get_symbol_name (&name); /* Get terminator.  */
+  if (!ISALPHA (*name))
     {
-      as_bad ("symbols assigned with .asg must begin with a letter");
+      as_bad (_("symbols assigned with .asg must begin with a letter"));
       ignore_rest_of_line ();
       return;
     }
 
-  tmp = xmalloc (strlen (str) + 1);
-  strcpy (tmp, str);
-  str = tmp;
-  tmp = xmalloc (strlen (name) + 1);
-  strcpy (tmp, name);
-  name = tmp;
+  str = xstrdup (str);
+  name = xstrdup (name);
   subsym_create_or_replace (name, str);
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
   demand_empty_rest_of_line ();
 }
 
-/* .eval expression, symbol 
+/* .eval expression, symbol
    There's something screwy about this.  The other assembler sometimes does and
-   sometimes doesn't substitute symbols defined with .eval.  
+   sometimes doesn't substitute symbols defined with .eval.
    We'll put the symbols into the subsym table as well as the normal symbol
    table, since that's what works best.  */
+
 static void
-tic54x_eval (x)
-     int x ATTRIBUTE_UNUSED;
+tic54x_eval (int x ATTRIBUTE_UNUSED)
 {
   char c;
   int value;
@@ -396,13 +406,11 @@ tic54x_eval (x)
       ignore_rest_of_line ();
       return;
     }
-  name = input_line_pointer;
-  c = get_symbol_end ();       /* Get terminator.  */
-  tmp = xmalloc (strlen (name) + 1);
-  name = strcpy (tmp, name);
-  *input_line_pointer = c;
+  c = get_symbol_name (&name); /* Get terminator.  */
+  name = xstrdup (name);
+  (void) restore_line_pointer (c);
 
-  if (!isalpha (*name))
+  if (!ISALPHA (*name))
     {
       as_bad (_("symbols assigned with .eval must begin with a letter"));
       ignore_rest_of_line ();
@@ -417,14 +425,13 @@ tic54x_eval (x)
      But since there's not written rule as to when, don't even bother trying
      to match their behavior.  */
   sprintf (valuestr, "%d", value);
-  tmp = xmalloc (strlen (valuestr) + 1);
-  strcpy (tmp, valuestr);
+  tmp = xstrdup (valuestr);
   subsym_create_or_replace (name, tmp);
 
   demand_empty_rest_of_line ();
 }
 
-/* .bss symbol, size [, [blocking flag] [, alignment flag] 
+/* .bss symbol, size [, [blocking flag] [, alignment flag]
 
    alignment is to a longword boundary; blocking is to 128-word boundary.
 
@@ -435,11 +442,11 @@ tic54x_eval (x)
       otherwise, check to see if the current SPC plus the space to be
       allocated crosses the page boundary (128 words).
       if there's not enough space, create a hole and align with the next page
-      boundary. 
+      boundary.
       (not yet implemented).  */
+
 static void
-tic54x_bss (x)
-     int x ATTRIBUTE_UNUSED;
+tic54x_bss (int x ATTRIBUTE_UNUSED)
 {
   char c;
   char *name;
@@ -456,11 +463,12 @@ tic54x_bss (x)
   current_seg = now_seg;       /* Save current seg.  */
   current_subseg = now_subseg; /* Save current subseg.  */
 
-  name = input_line_pointer;
-  c = get_symbol_end ();       /* Get terminator.  */
+  c = get_symbol_name (&name); /* Get terminator.  */
+  if (c == '"')
+    c = * ++ input_line_pointer;
   if (c != ',')
     {
-      as_bad (".bss size argument missing\n");
+      as_bad (_(".bss size argument missing\n"));
       ignore_rest_of_line ();
       return;
     }
@@ -469,14 +477,14 @@ tic54x_bss (x)
   words = get_absolute_expression ();
   if (words < 0)
     {
-      as_bad (".bss size %d < 0!", words);
+      as_bad (_(".bss size %d < 0!"), words);
       ignore_rest_of_line ();
       return;
     }
 
   if (*input_line_pointer == ',')
     {
-      /* the blocking flag may be missing */
+      /* The blocking flag may be missing.  */
       ++input_line_pointer;
       if (*input_line_pointer != ',')
        block = get_absolute_expression ();
@@ -498,12 +506,12 @@ tic54x_bss (x)
   symbolP = symbol_find_or_make (name);
 
   if (S_GET_SEGMENT (symbolP) == bss_section)
-    symbolP->sy_frag->fr_symbol = (symbolS *) NULL;
+    symbol_get_frag (symbolP)->fr_symbol = (symbolS *) NULL;
 
   symbol_set_frag (symbolP, frag_now);
   p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
-               (offsetT) (words << 1), (char *) 0);
-  *p = 0;                      /* fill char.  */
+               (offsetT) (words * OCTETS_PER_BYTE), (char *) 0);
+  *p = 0;                      /* Fill char.  */
 
   S_SET_SEGMENT (symbolP, bss_section);
 
@@ -521,102 +529,98 @@ tic54x_bss (x)
     }
 
   if (block)
-      bss_section->flags |= SEC_BLOCK;
+    bss_section->flags |= SEC_TIC54X_BLOCK;
 
-  subseg_set (current_seg, current_subseg);    /* restore current seg.  */
+  subseg_set (current_seg, current_subseg);    /* Restore current seg.  */
   demand_empty_rest_of_line ();
 }
 
 static void
-stag_add_field_symbols (stag, path, base_offset, rootsym, root_stag_name)
-     struct stag *stag;
-     const char *path;
-     bfd_vma base_offset;
-     symbolS *rootsym;
-     const char *root_stag_name;
-{
-  char prefix[strlen (path) + 2];
+stag_add_field_symbols (struct stag *stag,
+                       const char *path,
+                       bfd_vma base_offset,
+                       symbolS *rootsym,
+                       const char *root_stag_name)
+{
+  char * prefix;
   struct stag_field *field = stag->field;
-  
-  /* Construct a symbol for every field contained within this structure 
+
+  /* Construct a symbol for every field contained within this structure
      including fields within structure fields.  */
-  strcpy (prefix, path);
-  if (*path)
-    strcat (prefix, ".");
+  prefix = concat (path, *path ? "." : "", NULL);
 
   while (field != NULL)
     {
-      int len = strlen (prefix) + strlen (field->name) + 2;
-      char *name = xmalloc (len);
-      strcpy (name, prefix);
-      strcat (name, field->name);
+      char *name = concat (prefix, field->name, NULL);
 
       if (rootsym == NULL)
-        {
-          symbolS *sym;
-          sym = symbol_new (name, absolute_section, 
-                            (field->stag ? field->offset :
-                             (valueT)(base_offset + field->offset)), 
-                            &zero_address_frag);
-          SF_SET_LOCAL (sym);
-          symbol_table_insert (sym);
-        }
+       {
+         symbolS *sym;
+         sym = symbol_new (name, absolute_section,
+                           (field->stag ? field->offset :
+                            (valueT) (base_offset + field->offset)),
+                           &zero_address_frag);
+         SF_SET_LOCAL (sym);
+         symbol_table_insert (sym);
+       }
       else
-        {
-          char *replacement = xmalloc (strlen (name) + strlen (stag->name) + 2);
-          strcpy (replacement, S_GET_NAME (rootsym));
-          strcat (replacement, "+");
-          strcat (replacement, root_stag_name);
-          strcat (replacement, name + strlen (S_GET_NAME (rootsym)));
-          hash_insert (subsym_hash[0], name, replacement);
-        }
+       {
+         char *replacement;
+
+         replacement = concat (S_GET_NAME (rootsym), "+", root_stag_name,
+                               name + strlen (S_GET_NAME (rootsym)), NULL);
+         hash_insert (subsym_hash[0], name, replacement);
+       }
 
       /* Recurse if the field is a structure.
-         Note the field offset is relative to the outermost struct.  */
+        Note the field offset is relative to the outermost struct.  */
       if (field->stag != NULL)
-        stag_add_field_symbols (field->stag, name, 
-                                field->offset, 
-                                rootsym, root_stag_name);
+       stag_add_field_symbols (field->stag, name,
+                               field->offset,
+                               rootsym, root_stag_name);
       field = field->next;
+      free (name);
     }
+  free (prefix);
 }
 
 /* Keep track of stag fields so that when structures are nested we can add the
    complete dereferencing symbols to the symbol table.  */
+
 static void
-stag_add_field (parent, name, offset, stag)
-     struct stag *parent;
-     const char *name;
-     bfd_vma offset;
-     struct stag *stag;
+stag_add_field (struct stag *parent,
+               const char *name,
+               bfd_vma offset,
+               struct stag *stag)
 {
-  struct stag_field *sfield = xmalloc (sizeof (struct stag_field));
+  struct stag_field *sfield = XCNEW (struct stag_field);
 
-  memset (sfield, 0, sizeof (*sfield));
-  sfield->name = strcpy (xmalloc (strlen (name)+1), name);
+  sfield->name = xstrdup (name);
   sfield->offset = offset;
   sfield->bitfield_offset = parent->current_bitfield_offset;
   sfield->stag = stag;
   if (parent->field == NULL)
     parent->field = sfield;
-  else {
-    struct stag_field *sf = parent->field;
-    while (sf->next != NULL)
-      sf = sf->next;
-    sf->next = sfield;
-  }
+  else
+    {
+      struct stag_field *sf = parent->field;
+      while (sf->next != NULL)
+       sf = sf->next;
+      sf->next = sfield;
+    }
   /* Only create a symbol for this field if the parent has no name.  */
   if (!strncmp (".fake", parent->name, 5))
     {
-      symbolS *sym = symbol_new (name, absolute_section, 
-                                 (valueT)offset, &zero_address_frag);
+      symbolS *sym = symbol_new (name, absolute_section,
+                                (valueT) offset, &zero_address_frag);
       SF_SET_LOCAL (sym);
       symbol_table_insert (sym);
     }
 }
 
 /* [STAG] .struct       [OFFSET]
-   start defining structure offsets (symbols in absolute section).  */
+   Start defining structure offsets (symbols in absolute section).  */
+
 static void
 tic54x_struct (int arg)
 {
@@ -642,27 +646,25 @@ tic54x_struct (int arg)
     {
       /* Offset is ignored in inner structs.  */
       SKIP_WHITESPACE ();
-      if (!is_end_of_line[(int)*input_line_pointer])
-        start_offset = get_absolute_expression ();
+      if (!is_end_of_line[(unsigned char) *input_line_pointer])
+       start_offset = get_absolute_expression ();
       else
-        start_offset = 0;
+       start_offset = 0;
     }
 
   if (current_stag)
     {
       /* Nesting, link to outer one.  */
-      current_stag->inner = (struct stag *)xmalloc (sizeof (struct stag));
-      memset (current_stag->inner, 0, sizeof (struct stag));
+      current_stag->inner = XCNEW (struct stag);
       current_stag->inner->outer = current_stag;
       current_stag = current_stag->inner;
       if (start_offset)
-        as_warn (_("Offset on nested structures is ignored"));
+       as_warn (_("Offset on nested structures is ignored"));
       start_offset = abs_section_offset;
     }
-  else 
+  else
     {
-      current_stag = (struct stag *)xmalloc (sizeof (struct stag));
-      memset (current_stag, 0, sizeof (struct stag));
+      current_stag = XCNEW (struct stag);
       abs_section_offset = start_offset;
     }
   current_stag->is_union = is_union;
@@ -673,16 +675,17 @@ tic54x_struct (int arg)
       char fake[] = ".fake_stagNNNNNNN";
       sprintf (fake, ".fake_stag%d", struct_count++);
       current_stag->sym = symbol_new (fake, absolute_section,
-                                      (valueT)abs_section_offset,
-                                      &zero_address_frag);
+                                     (valueT) abs_section_offset,
+                                     &zero_address_frag);
     }
   else
     {
-      char label[strlen (S_GET_NAME (line_label)) + 1];
-      strcpy (label, S_GET_NAME (line_label));
-      current_stag->sym = symbol_new (label, absolute_section,
-                                      (valueT)abs_section_offset,
-                                      &zero_address_frag);
+      char * label = xstrdup (S_GET_NAME (line_label));
+      current_stag->sym = symbol_new (label,
+                                     absolute_section,
+                                     (valueT) abs_section_offset,
+                                     &zero_address_frag);
+      free (label);
     }
   current_stag->name = S_GET_NAME (current_stag->sym);
   SF_SET_LOCAL (current_stag->sym);
@@ -693,21 +696,22 @@ tic54x_struct (int arg)
   line_label = NULL;
 }
 
-/* [LABEL] .endstruct 
+/* [LABEL] .endstruct
    finish defining structure offsets; optional LABEL's value will be the size
    of the structure.  */
+
 static void
 tic54x_endstruct (int is_union)
 {
   int size;
-  const char *path = 
+  const char *path =
     !strncmp (current_stag->name, ".fake", 5) ? "" : current_stag->name;
-  
+
   if (!current_stag || current_stag->is_union != is_union)
     {
-      as_bad (_(".end%s without preceding .%s"), 
-              is_union ? "union" : "struct",
-              is_union ? "union" : "struct");
+      as_bad (_(".end%s without preceding .%s"),
+             is_union ? "union" : "struct",
+             is_union ? "union" : "struct");
       ignore_rest_of_line ();
       return;
     }
@@ -737,9 +741,9 @@ tic54x_endstruct (int is_union)
   if (current_stag->outer == NULL)
     {
       hash_insert (stag_hash, current_stag->name, current_stag);
-      stag_add_field_symbols (current_stag, path, 
-                              S_GET_VALUE (current_stag->sym),
-                              NULL, NULL);
+      stag_add_field_symbols (current_stag, path,
+                             S_GET_VALUE (current_stag->sym),
+                             NULL, NULL);
     }
   current_stag = current_stag->outer;
 
@@ -748,8 +752,8 @@ tic54x_endstruct (int is_union)
   if (current_stag != NULL)
     {
       stag_add_field (current_stag, current_stag->inner->name,
-                      S_GET_VALUE (current_stag->inner->sym), 
-                      current_stag->inner);
+                     S_GET_VALUE (current_stag->inner->sym),
+                     current_stag->inner);
     }
   else
     subseg_set (stag_saved_seg, stag_saved_subseg);
@@ -757,23 +761,23 @@ tic54x_endstruct (int is_union)
 
 /* [LABEL]      .tag    STAG
    Reference a structure within a structure, as a sized field with an optional
-   label. 
+   label.
    If used outside of a .struct/.endstruct, overlays the given structure
    format on the existing allocated space.  */
+
 static void
-tic54x_tag (ignore)
-  int ignore ATTRIBUTE_UNUSED;
+tic54x_tag (int ignore ATTRIBUTE_UNUSED)
 {
-  char *name = input_line_pointer;
-  int c = get_symbol_end ();
-  struct stag *stag = (struct stag *)hash_find (stag_hash, name);
+  char *name;
+  int c = get_symbol_name (&name);
+  struct stag *stag = (struct stag *) hash_find (stag_hash, name);
 
   if (!stag)
     {
       if (*name)
-        as_bad (_("Unrecognized struct/union tag '%s'"), name);
+       as_bad (_("Unrecognized struct/union tag '%s'"), name);
       else
-        as_bad (_(".tag requires a structure tag"));
+       as_bad (_(".tag requires a structure tag"));
       ignore_rest_of_line ();
       return;
     }
@@ -785,31 +789,35 @@ tic54x_tag (ignore)
     }
   else
     {
-      char label[strlen (S_GET_NAME (line_label))+1];
-      strcpy (label,  S_GET_NAME (line_label));
+      char * label;
+
+      label = xstrdup (S_GET_NAME (line_label));
       if (current_stag != NULL)
-        stag_add_field (current_stag, label, 
-                        abs_section_offset - S_GET_VALUE (current_stag->sym), 
-                        stag);
+       stag_add_field (current_stag, label,
+                       abs_section_offset - S_GET_VALUE (current_stag->sym),
+                       stag);
       else
-        {
-          symbolS *sym = symbol_find (label);
-          if (!sym)
-            {
-              as_bad (_(".tag target '%s' undefined"), label);
-              ignore_rest_of_line ();
-              return;
-            }
-          stag_add_field_symbols (stag, S_GET_NAME (sym), 
-                                  S_GET_VALUE (stag->sym), sym, stag->name);
-        }
-    }
-    
+       {
+         symbolS *sym = symbol_find (label);
+
+         if (!sym)
+           {
+             as_bad (_(".tag target '%s' undefined"), label);
+             ignore_rest_of_line ();
+             free (label);
+             return;
+           }
+         stag_add_field_symbols (stag, S_GET_NAME (sym),
+                                 S_GET_VALUE (stag->sym), sym, stag->name);
+       }
+      free (label);
+    }
+
   /* Bump by the struct size, but only if we're within a .struct section.  */
   if (current_stag != NULL && !current_stag->is_union)
     abs_section_offset += stag->size;
 
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
   demand_empty_rest_of_line ();
   line_label = NULL;
 }
@@ -817,6 +825,7 @@ tic54x_tag (ignore)
 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
    .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
    and .word.  */
+
 static void
 tic54x_struct_field (int type)
 {
@@ -827,7 +836,7 @@ tic54x_struct_field (int type)
   int longword_align = 0;
 
   SKIP_WHITESPACE ();
-  if (!is_end_of_line[(int)*input_line_pointer])
+  if (!is_end_of_line[(unsigned char) *input_line_pointer])
     count = get_absolute_expression ();
 
   switch (type)
@@ -844,7 +853,7 @@ tic54x_struct_field (int type)
     case 'S':
     case 'w':
     case 'W':
-    case '*': /* string */
+    case '*': /* String.  */
       size = 1;
       break;
     case 'f':
@@ -853,36 +862,36 @@ tic54x_struct_field (int type)
       longword_align = 1;
       size = 2;
       break;
-    case '.': /* bitfield */
+    case '.': /* Bitfield.  */
       size = 0;
       if (count < 1 || count > 32)
-        {
-          as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count);
-          ignore_rest_of_line ();
-          return;
-        }
+       {
+         as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count);
+         ignore_rest_of_line ();
+         return;
+       }
       if (current_stag->current_bitfield_offset + count > 16)
-        {
-          /* Set the appropriate size and new field offset.  */
-          if (count == 32)
-            {
-              size = 2; count = 1;
-            }
-          else if (count > 16)
-            {
-              size = 1; count = 1;
-              new_bitfield_offset = count - 16;
-            }
-          else
-            {
-              new_bitfield_offset = count;
-            }
-        }
+       {
+         /* Set the appropriate size and new field offset.  */
+         if (count == 32)
+           {
+             size = 2;
+             count = 1;
+           }
+         else if (count > 16)
+           {
+             size = 1;
+             count = 1;
+             new_bitfield_offset = count - 16;
+           }
+         else
+           new_bitfield_offset = count;
+       }
       else
-        {
-          field_align = 0;
-          new_bitfield_offset = current_stag->current_bitfield_offset + count;
-        }
+       {
+         field_align = 0;
+         new_bitfield_offset = current_stag->current_bitfield_offset + count;
+       }
       break;
     default:
       as_bad (_("Unrecognized field type '%c'"), type);
@@ -904,40 +913,43 @@ tic54x_struct_field (int type)
     {
       static int fieldno = 0;
       char fake[] = ".fake_fieldNNNNN";
+
       sprintf (fake, ".fake_field%d", fieldno++);
-      stag_add_field (current_stag, fake, 
-                      abs_section_offset - S_GET_VALUE (current_stag->sym), 
-                      NULL);
+      stag_add_field (current_stag, fake,
+                     abs_section_offset - S_GET_VALUE (current_stag->sym),
+                     NULL);
     }
   else
     {
-      char label[strlen (S_GET_NAME (line_label) + 1)];
-      strcpy (label, S_GET_NAME (line_label));
-      stag_add_field (current_stag, label, 
-                      abs_section_offset - S_GET_VALUE (current_stag->sym), 
-                      NULL);
+      char * label;
+
+      label = xstrdup (S_GET_NAME (line_label));
+      stag_add_field (current_stag, label,
+                     abs_section_offset - S_GET_VALUE (current_stag->sym),
+                     NULL);
+      free (label);
     }
 
   if (current_stag->is_union)
     {
       /* Note we treat the element as if it were an array of COUNT.  */
-      if (current_stag->size < (unsigned)size * count)
-        current_stag->size = size * count;
+      if (current_stag->size < (unsigned) size * count)
+       current_stag->size = size * count;
     }
   else
     {
-      abs_section_offset += (unsigned)size * count;
+      abs_section_offset += (unsigned) size * count;
       current_stag->current_bitfield_offset = new_bitfield_offset;
     }
   line_label = NULL;
 }
 
 /* Handle .byte, .word. .int, .long and all variants.  */
-int emitting_long = 0;
-static void 
+
+static void
 tic54x_cons (int type)
 {
-  register unsigned int c;
+  unsigned int c;
   int octets;
 
   /* If we're within a .struct construct, don't actually allocate space.  */
@@ -959,10 +971,10 @@ tic54x_cons (int type)
       frag_align (2, 0, 2);
       /* If there's a label, assign it to the first allocated word.  */
       if (line_label != NULL)
-        {
-          symbol_set_frag (line_label, frag_now);
-          S_SET_VALUE (line_label, frag_now_fix ());
-        }
+       {
+         symbol_set_frag (line_label, frag_now);
+         S_SET_VALUE (line_label, frag_now_fix ());
+       }
     }
 
   switch (type)
@@ -994,57 +1006,57 @@ tic54x_cons (int type)
        }
       else
        {
-         expressionS exp;
+         expressionS expn;
 
-         input_line_pointer = parse_expression (input_line_pointer, &exp);
-         if (exp.X_op == O_constant)
+         input_line_pointer = parse_expression (input_line_pointer, &expn);
+         if (expn.X_op == O_constant)
            {
-              offsetT value = exp.X_add_number;
-              /* Truncate overflows.  */
+             offsetT value = expn.X_add_number;
+             /* Truncate overflows.  */
              switch (octets)
                {
                case 1:
-                  if ((value > 0 && value > 0xFF)
-                      || (value < 0 && value < - 0x100))
-                    as_warn ("Overflow in expression, truncated to 8 bits");
+                 if ((value > 0 && value > 0xFF)
+                     || (value < 0 && value < - 0x100))
+                   as_warn (_("Overflow in expression, truncated to 8 bits"));
                  break;
                case 2:
-                  if ((value > 0 && value > 0xFFFF)
-                      || (value < 0 && value < - 0x10000))
-                    as_warn ("Overflow in expression, truncated to 16 bits");
+                 if ((value > 0 && value > 0xFFFF)
+                     || (value < 0 && value < - 0x10000))
+                   as_warn (_("Overflow in expression, truncated to 16 bits"));
                  break;
                }
            }
-          if (exp.X_op != O_constant && octets < 2)
-            {
-              /* Disallow .byte with a non constant expression that will
-                 require relocation.  */ 
-              as_bad (_("Relocatable values require at least WORD storage"));
-              ignore_rest_of_line ();
-              return;
-            }
-
-          if (exp.X_op != O_constant 
-              && amode == c_mode
-              && octets == 4)
-            {
-              /* FIXME -- at one point TI tools used to output REL16
-                 relocations, but I don't think the latest tools do at all 
-                 The current tools output extended relocations regardless of
-                 the addresing mode (I actually think that ".c_mode" is
-                 totally ignored in the latest tools).  */
-              amode = far_mode;
-              emitting_long = 1;
-              emit_expr (&exp, 4);
-              emitting_long = 0;
-              amode = c_mode;
-            }
-          else
-            {
-              emitting_long = octets == 4;
-              emit_expr (&exp, (octets == 1) ? 2 : octets);
-              emitting_long = 0;
-            }
+         if (expn.X_op != O_constant && octets < 2)
+           {
+             /* Disallow .byte with a non constant expression that will
+                require relocation.  */
+             as_bad (_("Relocatable values require at least WORD storage"));
+             ignore_rest_of_line ();
+             return;
+           }
+
+         if (expn.X_op != O_constant
+             && amode == c_mode
+             && octets == 4)
+           {
+             /* FIXME -- at one point TI tools used to output REL16
+                relocations, but I don't think the latest tools do at all
+                The current tools output extended relocations regardless of
+                the addressing mode (I actually think that ".c_mode" is
+                totally ignored in the latest tools).  */
+             amode = far_mode;
+             emitting_long = 1;
+             emit_expr (&expn, 4);
+             emitting_long = 0;
+             amode = c_mode;
+           }
+         else
+           {
+             emitting_long = octets == 4;
+             emit_expr (&expn, (octets == 1) ? 2 : octets);
+             emitting_long = 0;
+           }
        }
     }
   while (*input_line_pointer++ == ',');
@@ -1057,7 +1069,7 @@ tic54x_cons (int type)
    .def    <symbol>[,...,<symbolN>]
    .ref    <symbol>[,...,<symbolN>]
 
-   These all identify global symbols. 
+   These all identify global symbols.
 
    .def means the symbol is defined in the current module and can be accessed
    by other files.  The symbol should be placed in the symbol table.
@@ -1067,35 +1079,34 @@ tic54x_cons (int type)
 
    .global should act as a .ref or .def, as needed.
 
-   global, def and ref all have symbol storage classes of C_EXT.  
+   global, def and ref all have symbol storage classes of C_EXT.
 
    I can't identify any difference in how the "other" c54x assembler treats
    these, so we ignore the type here.  */
+
 void
-tic54x_global (type)
-     int type;
+tic54x_global (int type)
 {
   char *name;
   int c;
   symbolS *symbolP;
 
   if (type == 'r')
-      as_warn (_("Use of .def/.ref is deprecated.  Use .global instead"));
+    as_warn (_("Use of .def/.ref is deprecated.  Use .global instead"));
 
   ILLEGAL_WITHIN_STRUCT ();
 
   do
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       symbolP = symbol_find_or_make (name);
+      c = restore_line_pointer (c);
 
-      *input_line_pointer = c;
       S_SET_STORAGE_CLASS (symbolP, C_EXT);
       if (c == ',')
        {
          input_line_pointer++;
-         if (is_end_of_line[(int)*input_line_pointer])
+         if (is_end_of_line[(unsigned char) *input_line_pointer])
            c = *input_line_pointer;
        }
     }
@@ -1105,19 +1116,18 @@ tic54x_global (type)
 }
 
 /* Remove the symbol from the local label hash lookup.  */
+
 static void
-tic54x_remove_local_label (key, value)
-  const char *key;
-  PTR value ATTRIBUTE_UNUSED;
+tic54x_remove_local_label (const char *key, void *value ATTRIBUTE_UNUSED)
 {
-  PTR *elem = hash_delete (local_label_hash[macro_level], key);
+  void *elem = hash_delete (local_label_hash[macro_level], key, FALSE);
   free (elem);
 }
 
 /* Reset all local labels.  */
-static void 
-tic54x_clear_local_labels (ignored)
-  int ignored ATTRIBUTE_UNUSED;
+
+static void
+tic54x_clear_local_labels (int ignored ATTRIBUTE_UNUSED)
 {
   hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label);
 }
@@ -1127,11 +1137,14 @@ tic54x_clear_local_labels (ignored)
    .sect "section name"
 
    Initialized section
-   make sure local labels get cleared when changing sections 
+   make sure local labels get cleared when changing sections
 
    ARG is 't' for text, 'd' for data, or '*' for a named section
 
-   For compatibility, '*' sections have SEC_DATA set instead of SEC_CODE.  */
+   For compatibility, '*' sections are SEC_CODE if instructions are
+   encountered, or SEC_DATA if not.
+*/
+
 static void
 tic54x_sect (int arg)
 {
@@ -1148,51 +1161,55 @@ tic54x_sect (int arg)
     {
       char *name = NULL;
       int len;
+      /* Make sure all named initialized sections flagged properly.  If we
+         encounter instructions, we'll flag it with SEC_CODE as well.  */
+      const char *flags = ",\"w\"\n";
+
       /* If there are quotes, remove them.  */
       if (*input_line_pointer == '"')
-        {
-          name = demand_copy_C_string (&len);
-          demand_empty_rest_of_line ();
-          name = strcpy (xmalloc (len+10), name);
-        }
-      else 
-        {
-          int c;
-          name = input_line_pointer;
-          c = get_symbol_end ();
-          name = strcpy (xmalloc (len+10), name);
-          *input_line_pointer = c;
-          demand_empty_rest_of_line ();
-        }
-      /* Make sure all named initialized sections are SEC_DATA.  */
-      strcat (name, ",\"w\"\n");
+       {
+         name = demand_copy_C_string (&len);
+         demand_empty_rest_of_line ();
+         name = concat (name, flags, (char *) NULL);
+       }
+      else
+       {
+         int c;
+
+         c = get_symbol_name (&name);
+         name = concat (name, flags, (char *) NULL);
+         (void) restore_line_pointer (c);
+         demand_empty_rest_of_line ();
+       }
+
       input_scrub_insert_line (name);
       obj_coff_section (0);
 
       /* If there was a line label, make sure that it gets assigned the proper
-         section.  This is for compatibility, even though the actual behavior
-         is not explicitly defined.  For consistency, we make .sect behave
-         like .usect, since that is probably what people expect.  */
+        section.  This is for compatibility, even though the actual behavior
+        is not explicitly defined.  For consistency, we make .sect behave
+        like .usect, since that is probably what people expect.  */
       if (line_label != NULL)
-        {
-          S_SET_SEGMENT (line_label, now_seg);
-          symbol_set_frag (line_label, frag_now);
-          S_SET_VALUE (line_label, frag_now_fix ());
-          if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
-              S_SET_STORAGE_CLASS (line_label, C_LABEL);
-        }
+       {
+         S_SET_SEGMENT (line_label, now_seg);
+         symbol_set_frag (line_label, frag_now);
+         S_SET_VALUE (line_label, frag_now_fix ());
+         if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
+           S_SET_STORAGE_CLASS (line_label, C_LABEL);
+       }
     }
 }
 
-/* [symbol] .space space_in_bits 
+/* [symbol] .space space_in_bits
    [symbol] .bes space_in_bits
-   BES puts the symbol at the *last* word allocated 
+   BES puts the symbol at the *last* word allocated
 
    cribbed from s_space.  */
+
 static void
 tic54x_space (int arg)
 {
-  expressionS exp;
+  expressionS expn;
   char *p = 0;
   int octets = 0;
   long words;
@@ -1208,25 +1225,24 @@ tic54x_space (int arg)
 #endif
 
   /* Read the bit count.  */
-  expression (&exp);
+  expression (&expn);
 
   /* Some expressions are unresolvable until later in the assembly pass;
      postpone until relaxation/fixup.  we also have to postpone if a previous
      partial allocation has not been completed yet.  */
-  if (exp.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
+  if (expn.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
     {
-      struct bit_info *bi = xmalloc (sizeof (struct bit_info));
-      char *p;
+      struct bit_info *bi = XNEW (struct bit_info);
 
       bi->seg = now_seg;
       bi->type = bes;
       bi->sym = label;
-      p = frag_var (rs_machine_dependent, 
-                    65536*2, 1, (relax_substateT) 0,
-                    make_expr_symbol (&exp), (offsetT) 0, 
-                    (char *) bi);
+      p = frag_var (rs_machine_dependent,
+                   65536 * 2, 1, (relax_substateT) 0,
+                   make_expr_symbol (&expn), (offsetT) 0,
+                   (char *) bi);
       if (p)
-        *p = 0;
+       *p = 0;
 
       return;
     }
@@ -1237,33 +1253,34 @@ tic54x_space (int arg)
   if (bit_offset != 0 && bit_offset < 16)
     {
       int spare_bits = bits_per_byte - bit_offset;
-      if (spare_bits >= exp.X_add_number)
-        {
-          /* Don't have to do anything; sufficient bits have already been
-             allocated; just point the label to the right place.  */ 
-          if (label != NULL)
-            {
-              symbol_set_frag (label, frag_now);
-              S_SET_VALUE (label, frag_now_fix () - 1);
-              label = NULL;
-            }
-          frag_now->tc_frag_data += exp.X_add_number;
-          goto getout;
-        }
-      exp.X_add_number -= spare_bits;
+
+      if (spare_bits >= expn.X_add_number)
+       {
+         /* Don't have to do anything; sufficient bits have already been
+            allocated; just point the label to the right place.  */
+         if (label != NULL)
+           {
+             symbol_set_frag (label, frag_now);
+             S_SET_VALUE (label, frag_now_fix () - 1);
+             label = NULL;
+           }
+         frag_now->tc_frag_data += expn.X_add_number;
+         goto getout;
+       }
+      expn.X_add_number -= spare_bits;
       /* Set the label to point to the first word allocated, which in this
-         case is the previous word, which was only partially filled.  */
+        case is the previous word, which was only partially filled.  */
       if (!bes && label != NULL)
-        {
-          symbol_set_frag (label, frag_now);
-          S_SET_VALUE (label, frag_now_fix () - 1);
-          label = NULL;
-        }
+       {
+         symbol_set_frag (label, frag_now);
+         S_SET_VALUE (label, frag_now_fix () - 1);
+         label = NULL;
+       }
     }
   /* Convert bits to bytes/words and octets, rounding up.  */
-  words = ((exp.X_add_number + bits_per_byte - 1) / bits_per_byte);
+  words = ((expn.X_add_number + bits_per_byte - 1) / bits_per_byte);
   /* How many do we have left over?  */
-  bit_offset = exp.X_add_number % bits_per_byte;
+  bit_offset = expn.X_add_number % bits_per_byte;
   octets = words * OCTETS_PER_BYTE;
   if (octets < 0)
     {
@@ -1275,21 +1292,21 @@ tic54x_space (int arg)
       as_warn (_(".space/.bes repeat count is zero, ignored"));
       goto getout;
     }
-  
+
   /* If we are in the absolute section, just bump the offset.  */
   if (now_seg == absolute_section)
     {
       abs_section_offset += words;
       if (bes && label != NULL)
-        S_SET_VALUE (label, abs_section_offset - 1);
+       S_SET_VALUE (label, abs_section_offset - 1);
       frag_now->tc_frag_data = bit_offset;
       goto getout;
     }
-  
+
   if (!need_pass_2)
-    p = frag_var (rs_fill, 1, 1, 
-                  (relax_substateT) 0, (symbolS *) 0, 
-                  (offsetT) octets, (char *) 0);
+    p = frag_var (rs_fill, 1, 1,
+                 (relax_substateT) 0, (symbolS *) 0,
+                 (offsetT) octets, (char *) 0);
 
   /* Make note of how many bits of this word we've allocated so far.  */
   frag_now->tc_frag_data = bit_offset;
@@ -1298,9 +1315,9 @@ tic54x_space (int arg)
   if (bes && label != NULL)
     {
       symbol_set_frag (label, frag_now);
-      S_SET_VALUE (label, frag_now_fix ()-1);
+      S_SET_VALUE (label, frag_now_fix () - 1);
     }
-  
+
   if (p)
     *p = 0;
 
@@ -1309,18 +1326,18 @@ tic54x_space (int arg)
   demand_empty_rest_of_line ();
 }
 
-/* [symbol] .usect "section-name", size-in-words 
-                   [, [blocking-flag] [, alignment-flag]] 
+/* [symbol] .usect "section-name", size-in-words
+                  [, [blocking-flag] [, alignment-flag]]
 
-   Unitialized section.
+   Uninitialized section.
    Non-zero blocking means that if the section would cross a page (128-word)
    boundary, it will be page-aligned.
    Non-zero alignment aligns on a longword boundary.
 
    Has no effect on the current section.  */
-static void 
-tic54x_usect (x)
-  int x ATTRIBUTE_UNUSED;
+
+static void
+tic54x_usect (int x ATTRIBUTE_UNUSED)
 {
   char c;
   char *name;
@@ -1334,20 +1351,16 @@ tic54x_usect (x)
 
   ILLEGAL_WITHIN_STRUCT ();
 
-  current_seg = now_seg;       /* save current seg.  */
-  current_subseg = now_subseg; /* save current subseg.  */
-
-  if (*input_line_pointer == '"')
-    input_line_pointer++;
-  section_name = input_line_pointer;
-  c = get_symbol_end ();       /* Get terminator.  */
-  input_line_pointer++;                /* Skip null symbol terminator.  */
-  name = xmalloc (input_line_pointer - section_name + 1);
-  strcpy (name, section_name);
+  current_seg = now_seg;       /* Save current seg.  */
+  current_subseg = now_subseg; /* Save current subseg.  */
 
-  if (*input_line_pointer == ',')
+  c = get_symbol_name (&section_name); /* Get terminator.  */
+  name = xstrdup (section_name);
+  c = restore_line_pointer (c);
+  
+  if (c == ',')
     ++input_line_pointer;
-  else if (c != ',')
+  else
     {
       as_bad (_("Missing size argument"));
       ignore_rest_of_line ();
@@ -1361,24 +1374,24 @@ tic54x_usect (x)
     {
       ++input_line_pointer;
       if (*input_line_pointer != ',')
-        blocking_flag = get_absolute_expression ();
+       blocking_flag = get_absolute_expression ();
       else
-        blocking_flag = 0;
+       blocking_flag = 0;
 
       /* Read a possibly present fourth argument (alignment flag).  */
       if (*input_line_pointer == ',')
-        {
-          ++input_line_pointer;
-          alignment_flag = get_absolute_expression ();
-        }
+       {
+         ++input_line_pointer;
+         alignment_flag = get_absolute_expression ();
+       }
       else
-        alignment_flag = 0;
+       alignment_flag = 0;
     }
   else
     blocking_flag = alignment_flag = 0;
 
   seg = subseg_new (name, 0);
-  flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC;
+  flags = bfd_section_flags (seg) | SEC_ALLOC;
 
   if (alignment_flag)
     {
@@ -1392,66 +1405,64 @@ tic54x_usect (x)
       S_SET_SEGMENT (line_label, seg);
       symbol_set_frag (line_label, frag_now);
       S_SET_VALUE (line_label, frag_now_fix ());
-      /* set scl to label, since that's what TI does */
+      /* Set scl to label, since that's what TI does.  */
       if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
-        S_SET_STORAGE_CLASS (line_label, C_LABEL);
+       S_SET_STORAGE_CLASS (line_label, C_LABEL);
     }
 
   seg_info (seg)->bss = 1;     /* Uninitialized data.  */
 
-  p = frag_var (rs_fill, 1, 1, 
-                (relax_substateT) 0, (symbolS *) line_label,
-                size * OCTETS_PER_BYTE, (char *) 0);
+  p = frag_var (rs_fill, 1, 1,
+               (relax_substateT) 0, (symbolS *) line_label,
+               size * OCTETS_PER_BYTE, (char *) 0);
   *p = 0;
 
   if (blocking_flag)
-    flags |= SEC_BLOCK;
+    flags |= SEC_TIC54X_BLOCK;
 
-  if (!bfd_set_section_flags (stdoutput, seg, flags))
-    as_warn ("Error setting flags for \"%s\": %s", name,
+  if (!bfd_set_section_flags (seg, flags))
+    as_warn (_("Error setting flags for \"%s\": %s"), name,
             bfd_errmsg (bfd_get_error ()));
 
   subseg_set (current_seg, current_subseg);    /* Restore current seg.  */
   demand_empty_rest_of_line ();
-} 
+}
 
 static enum cpu_version
-lookup_version (ver)
-     const char *ver;
+lookup_version (const char *ver)
 {
   enum cpu_version version = VNONE;
-  
+
   if (ver[0] == '5' && ver[1] == '4')
     {
-      if (strlen (ver) == 3 &&
-          (ver[2] == '1' || ver[2] == '2' || ver[2] == '3' ||
-           ver[2] == '5' || ver[2] == '8' || ver[2] == '9'))
-        version = ver[2] - '0';
-      else if (strlen (ver) == 5 &&
-               toupper (ver[3]) == 'L' &&
-               toupper (ver[4]) == 'P' &&
-               (ver[2] == '5' || ver[2] == '6'))
-        version = ver[2] - '0' + 10;
+      if (strlen (ver) == 3
+         && (ver[2] == '1' || ver[2] == '2' || ver[2] == '3'
+             || ver[2] == '5' || ver[2] == '8' || ver[2] == '9'))
+       version = ver[2] - '0';
+      else if (strlen (ver) == 5
+              && TOUPPER (ver[3]) == 'L'
+              && TOUPPER (ver[4]) == 'P'
+              && (ver[2] == '5' || ver[2] == '6'))
+       version = ver[2] - '0' + 10;
     }
 
   return version;
 }
 
 static void
-set_cpu (version)
-     enum cpu_version version;
+set_cpu (enum cpu_version version)
 {
   cpu = version;
   if (version == V545LP || version == V546LP)
     {
       symbolS *symbolP = symbol_new ("__allow_lp", absolute_section,
-                                    (valueT)1, &zero_address_frag);
+                                    (valueT) 1, &zero_address_frag);
       SF_SET_LOCAL (symbolP);
       symbol_table_insert (symbolP);
     }
 }
 
-/* .version cpu-version 
+/* .version cpu-version
    cpu-version may be one of the following:
    541
    542
@@ -1465,9 +1476,8 @@ set_cpu (version)
    This is for compatibility only.  It currently has no affect on assembly.  */
 static int cpu_needs_set = 1;
 
-static void 
-tic54x_version (x)
-  int x ATTRIBUTE_UNUSED;
+static void
+tic54x_version (int x ATTRIBUTE_UNUSED)
 {
   enum cpu_version version = VNONE;
   enum cpu_version old_version = cpu;
@@ -1478,11 +1488,11 @@ tic54x_version (x)
 
   SKIP_WHITESPACE ();
   ver = input_line_pointer;
-  while (!is_end_of_line[(int)*input_line_pointer])
+  while (!is_end_of_line[(unsigned char) *input_line_pointer])
     ++input_line_pointer;
   c = *input_line_pointer;
   *input_line_pointer = 0;
-  
+
   version = lookup_version (ver);
 
   if (cpu != VNONE && cpu != version)
@@ -1508,6 +1518,7 @@ tic54x_version (x)
 }
 
 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble.  */
+
 static void
 tic54x_float_cons (int type)
 {
@@ -1517,32 +1528,31 @@ tic54x_float_cons (int type)
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
 #endif
-  
+
   /* Align to long word boundary (4 octets) unless it's ".xfloat".  */
   if (type != 'x')
     {
       frag_align (2, 0, 2);
       /* If there's a label, assign it to the first allocated word.  */
       if (line_label != NULL)
-        {
-          symbol_set_frag (line_label, frag_now);
-          S_SET_VALUE (line_label, frag_now_fix ());
-        }
+       {
+         symbol_set_frag (line_label, frag_now);
+         S_SET_VALUE (line_label, frag_now_fix ());
+       }
     }
 
   float_cons ('f');
 }
 
-/* The argument is capitalized if it should be zero-terminated 
+/* The argument is capitalized if it should be zero-terminated
    's' is normal string with upper 8-bits zero-filled, 'p' is packed.
-   Code copied from read.c, and slightly modified so that strings are packed
+   Code copied from stringer, and slightly modified so that strings are packed
    and encoded into the correct octets.  */
+
 static void
-tic54x_stringer (type)
-     int type;
+tic54x_stringer (int type)
 {
-  register unsigned int c;
-  char *start;
+  unsigned int c;
   int append_zero = type == 'S' || type == 'P';
   int packed = type == 'p' || type == 'P';
   int last_char = -1; /* Packed strings need two bytes at a time to encode.  */
@@ -1557,63 +1567,62 @@ tic54x_stringer (type)
   md_flush_pending_output ();
 #endif
 
-  c = ',';                     /* Do loop. */
+  c = ',';                     /* Do loop.  */
   while (c == ',')
     {
       SKIP_WHITESPACE ();
       switch (*input_line_pointer)
        {
-        default:
-          {
-            unsigned short value = get_absolute_expression ();
-            FRAG_APPEND_1_CHAR (value&0xFF);
-            FRAG_APPEND_1_CHAR ((value>>8)&0xFF);
-            break;
-          }
+       default:
+         {
+           unsigned short value = get_absolute_expression ();
+           FRAG_APPEND_1_CHAR ( value       & 0xFF);
+           FRAG_APPEND_1_CHAR ((value >> 8) & 0xFF);
+           break;
+         }
        case '\"':
-         ++input_line_pointer; /*->1st char of string. */
-         start = input_line_pointer;
+         ++input_line_pointer; /* -> 1st char of string.  */
          while (is_a_char (c = next_char_of_string ()))
            {
-              if (!packed)
-                {
-                  FRAG_APPEND_1_CHAR (c);
-                  FRAG_APPEND_1_CHAR (0);
-                }
-              else
-                {
-                  /* Packed strings are filled MS octet first.  */
-                  if (last_char == -1)
-                    last_char = c;
-                  else
-                    {
-                      FRAG_APPEND_1_CHAR (c);
-                      FRAG_APPEND_1_CHAR (last_char);
-                      last_char = -1;
-                    }
-                }
+             if (!packed)
+               {
+                 FRAG_APPEND_1_CHAR (c);
+                 FRAG_APPEND_1_CHAR (0);
+               }
+             else
+               {
+                 /* Packed strings are filled MS octet first.  */
+                 if (last_char == -1)
+                   last_char = c;
+                 else
+                   {
+                     FRAG_APPEND_1_CHAR (c);
+                     FRAG_APPEND_1_CHAR (last_char);
+                     last_char = -1;
+                   }
+               }
            }
          if (append_zero)
-            {
-              if (packed && last_char != -1)
-                {
-                  FRAG_APPEND_1_CHAR (0);
-                  FRAG_APPEND_1_CHAR (last_char);
-                  last_char = -1;
-                }
-              else
-                {
-                  FRAG_APPEND_1_CHAR (0);
-                  FRAG_APPEND_1_CHAR (0);
-                }
-            }
+           {
+             if (packed && last_char != -1)
+               {
+                 FRAG_APPEND_1_CHAR (0);
+                 FRAG_APPEND_1_CHAR (last_char);
+                 last_char = -1;
+               }
+             else
+               {
+                 FRAG_APPEND_1_CHAR (0);
+                 FRAG_APPEND_1_CHAR (0);
+               }
+           }
          know (input_line_pointer[-1] == '\"');
          break;
        }
       SKIP_WHITESPACE ();
       c = *input_line_pointer;
       if (!is_end_of_line[c])
-        ++input_line_pointer;
+       ++input_line_pointer;
     }
 
   /* Finish up any leftover packed string.  */
@@ -1626,34 +1635,32 @@ tic54x_stringer (type)
 }
 
 static void
-tic54x_p2align (arg)
-  int arg ATTRIBUTE_UNUSED;
+tic54x_p2align (int arg ATTRIBUTE_UNUSED)
 {
   as_bad (_("p2align not supported on this target"));
 }
 
 static void
-tic54x_align_words (arg)
-     int arg;
+tic54x_align_words (int arg)
 {
   /* Only ".align" with no argument is allowed within .struct/.union.  */
   int count = arg;
 
-  if (!is_end_of_line[(int)*input_line_pointer])
+  if (!is_end_of_line[(unsigned char) *input_line_pointer])
     {
       if (arg == 2)
-        as_warn (_("Argument to .even ignored"));
+       as_warn (_("Argument to .even ignored"));
       else
-        count = get_absolute_expression ();
+       count = get_absolute_expression ();
     }
 
   if (current_stag != NULL && arg == 128)
     {
       if (current_stag->current_bitfield_offset != 0)
-        {
-          current_stag->current_bitfield_offset = 0;
-          ++abs_section_offset;
-        }
+       {
+         current_stag->current_bitfield_offset = 0;
+         ++abs_section_offset;
+       }
       demand_empty_rest_of_line ();
       return;
     }
@@ -1663,12 +1670,12 @@ tic54x_align_words (arg)
   s_align_bytes (count << 1);
 }
 
-/* Initialize multiple-bit fields withing a single word of memory.  */
+/* Initialize multiple-bit fields within a single word of memory.  */
+
 static void
-tic54x_field (ignore)
-  int ignore ATTRIBUTE_UNUSED;
+tic54x_field (int ignore ATTRIBUTE_UNUSED)
 {
-  expressionS exp;
+  expressionS expn;
   int size = 16;
   char *p;
   valueT value;
@@ -1680,102 +1687,106 @@ tic54x_field (ignore)
       return;
     }
 
-  input_line_pointer = parse_expression (input_line_pointer, &exp);
+  input_line_pointer = parse_expression (input_line_pointer, &expn);
 
   if (*input_line_pointer == ',')
     {
       ++input_line_pointer;
       size = get_absolute_expression ();
       if (size < 1 || size > 32)
-        {
-          as_bad (_("Invalid field size, must be from 1 to 32"));
-          ignore_rest_of_line ();
-          return;
-        }
+       {
+         as_bad (_("Invalid field size, must be from 1 to 32"));
+         ignore_rest_of_line ();
+         return;
+       }
     }
 
   /* Truncate values to the field width.  */
-  if (exp.X_op != O_constant)
+  if (expn.X_op != O_constant)
     {
-      /* If the expression value is relocatable, the field size *must* be 16.  */
+      /* If the expression value is relocatable, the field size *must*
+         be 16.  */
       if (size != 16)
-        {
-          as_bad (_("field size must be 16 when value is relocatable"));
-          ignore_rest_of_line ();
-          return;
-        }
+       {
+         as_bad (_("field size must be 16 when value is relocatable"));
+         ignore_rest_of_line ();
+         return;
+       }
 
       frag_now->tc_frag_data = 0;
-      emit_expr (&exp, 2);
+      emit_expr (&expn, 2);
     }
   else
     {
       unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1;
-      value = exp.X_add_number;
-      exp.X_add_number &= fmask;
-      if (value != (valueT)exp.X_add_number)
-        as_warn (_("field value truncated"));
-      value = exp.X_add_number;
+
+      value = expn.X_add_number;
+      expn.X_add_number &= fmask;
+      if (value != (valueT) expn.X_add_number)
+       as_warn (_("field value truncated"));
+      value = expn.X_add_number;
       /* Bits are stored MS first.  */
       while (size >= 16)
-        {
-          frag_now->tc_frag_data = 0;
-          p = frag_more (2);
-          md_number_to_chars (p, (value >> (size - 16)) & 0xFFFF, 2);
-          size -= 16;
-        }
+       {
+         frag_now->tc_frag_data = 0;
+         p = frag_more (2);
+         md_number_to_chars (p, (value >> (size - 16)) & 0xFFFF, 2);
+         size -= 16;
+       }
       if (size > 0)
-        {
-          int bit_offset = frag_bit_offset (frag_now, now_seg);
-          fragS *alloc_frag = bit_offset_frag (frag_now, now_seg);
-          if (bit_offset == -1)
-            {
-              struct bit_info *bi = xmalloc (sizeof (struct bit_info));
-              /* We don't know the previous offset at this time, so store the
-                 info we need and figure it out later.  */
-              expressionS size_exp;
-              size_exp.X_op = O_constant;
-              size_exp.X_add_number = size;
-              bi->seg = now_seg;
-              bi->type = TYPE_FIELD;
-              bi->value = value;
-              p = frag_var (rs_machine_dependent,
-                            4, 1, (relax_substateT) 0,
-                            make_expr_symbol (&size_exp), (offsetT) 0,
-                            (char *) bi);
-              goto getout;
-            }
-          else if (bit_offset == 0 || bit_offset + size > 16)
-            {
-              /* Align a new field.  */
-              p = frag_more (2);
-              frag_now->tc_frag_data = 0;
-              alloc_frag = frag_now;
-            }
-          else
-            {
-              /* Put the new value entirely within the existing one.  */
-              p = alloc_frag == frag_now ? 
-                frag_now->fr_literal + frag_now_fix_octets () - 2 :
-                alloc_frag->fr_literal;
-              if (label != NULL)
-                {
-                  symbol_set_frag (label, alloc_frag);
-                  if (alloc_frag == frag_now)
-                    S_SET_VALUE (label, frag_now_fix () - 1);
-                  label = NULL;
-                }
-            }
-          value <<= 16 - alloc_frag->tc_frag_data - size;
-
-          /* OR in existing value.  */
-          if (alloc_frag->tc_frag_data)
-            value |= ((unsigned short)p[1]<<8) | p[0];
-          md_number_to_chars (p, value, 2);
-          alloc_frag->tc_frag_data += size;
-          if (alloc_frag->tc_frag_data == 16)
-            alloc_frag->tc_frag_data = 0;
-        }
+       {
+         int bit_offset = frag_bit_offset (frag_now, now_seg);
+
+         fragS *alloc_frag = bit_offset_frag (frag_now, now_seg);
+         if (bit_offset == -1)
+           {
+             struct bit_info *bi = XNEW (struct bit_info);
+             /* We don't know the previous offset at this time, so store the
+                info we need and figure it out later.  */
+             expressionS size_exp;
+
+             size_exp.X_op = O_constant;
+             size_exp.X_add_number = size;
+             bi->seg = now_seg;
+             bi->type = TYPE_FIELD;
+             bi->value = value;
+             p = frag_var (rs_machine_dependent,
+                           4, 1, (relax_substateT) 0,
+                           make_expr_symbol (&size_exp), (offsetT) 0,
+                           (char *) bi);
+             goto getout;
+           }
+         else if (bit_offset == 0 || bit_offset + size > 16)
+           {
+             /* Align a new field.  */
+             p = frag_more (2);
+             frag_now->tc_frag_data = 0;
+             alloc_frag = frag_now;
+           }
+         else
+           {
+             /* Put the new value entirely within the existing one.  */
+             p = alloc_frag == frag_now ?
+               frag_now->fr_literal + frag_now_fix_octets () - 2 :
+               alloc_frag->fr_literal;
+             if (label != NULL)
+               {
+                 symbol_set_frag (label, alloc_frag);
+                 if (alloc_frag == frag_now)
+                   S_SET_VALUE (label, frag_now_fix () - 1);
+                 label = NULL;
+               }
+           }
+         value <<= 16 - alloc_frag->tc_frag_data - size;
+
+         /* OR in existing value.  */
+         if (alloc_frag->tc_frag_data)
+           value |= ((unsigned short) p[1] << 8) | p[0];
+         md_number_to_chars (p, value, 2);
+         alloc_frag->tc_frag_data += size;
+         if (alloc_frag->tc_frag_data == 16)
+           alloc_frag->tc_frag_data = 0;
+       }
     }
  getout:
   demand_empty_rest_of_line ();
@@ -1783,22 +1794,22 @@ tic54x_field (ignore)
 
 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
    available yet.  seg_info ()->bss is the next best thing.  */
+
 static int
-tic54x_initialized_section (seg)
-  segT seg;
+tic54x_initialized_section (segT seg)
 {
   return !seg_info (seg)->bss;
 }
 
-/* .clink ["section name"] 
+/* .clink ["section name"]
 
    Marks the section as conditionally linked (link only if contents are
    referenced elsewhere.
    Without a name, refers to the current initialized section.
    Name is required for uninitialized sections.  */
+
 static void
-tic54x_clink (ignored)
-  int ignored ATTRIBUTE_UNUSED;
+tic54x_clink (int ignored ATTRIBUTE_UNUSED)
 {
   segT seg = now_seg;
 
@@ -1808,33 +1819,33 @@ tic54x_clink (ignored)
     {
       char *section_name = ++input_line_pointer;
       char *name;
+
       while (is_a_char (next_char_of_string ()))
-        ;
+       ;
       know (input_line_pointer[-1] == '\"');
       input_line_pointer[-1] = 0;
-      name = xmalloc (input_line_pointer - section_name + 1);
-      strcpy (name, section_name);
+      name = xstrdup (section_name);
 
       seg = bfd_get_section_by_name (stdoutput, name);
       if (seg == NULL)
-        {
-          as_bad (_("Unrecognized section '%s'"), section_name);
-          ignore_rest_of_line ();
-          return;
-        }
-    }
-  else
-    {
+       {
+         as_bad (_("Unrecognized section '%s'"), section_name);
+         ignore_rest_of_line ();
+         return;
+       }
+    }
+  else
+    {
       if (!tic54x_initialized_section (seg))
-        {
-          as_bad (_("Current section is unitialized, "
-                    "section name required for .clink"));
-          ignore_rest_of_line ();
-          return;
-        }
+       {
+         as_bad (_("Current section is uninitialized, "
+                   "section name required for .clink"));
+         ignore_rest_of_line ();
+         return;
+       }
     }
 
-  seg->flags |= SEC_CLINK;
+  seg->flags |= SEC_TIC54X_CLINK;
 
   demand_empty_rest_of_line ();
 }
@@ -1842,53 +1853,49 @@ tic54x_clink (ignored)
 /* Change the default include directory to be the current source file's
    directory, instead of the current working directory.  If DOT is non-zero,
    set to "." instead.  */
+
 static void
-tic54x_set_default_include (dot)
-  int dot;
+tic54x_set_default_include (void)
 {
-  char *dir = ".";
-  char *tmp = NULL;
-  
-  if (!dot)
-    {
-      char *curfile;
-      unsigned lineno;
-      
-      as_where (&curfile, &lineno);
-      dir = strcpy (xmalloc (strlen (curfile)+1), curfile);
-      tmp = strrchr (dir, '/');
-    }
+  char *dir, *tmp = NULL;
+  const char *curfile;
+  unsigned lineno;
+
+  curfile = as_where (&lineno);
+  dir = xstrdup (curfile);
+  tmp = strrchr (dir, '/');
   if (tmp != NULL)
     {
       int len;
+
       *tmp = '\0';
       len = strlen (dir);
       if (include_dir_count == 0)
-        {
-          include_dirs = (char **) xmalloc (sizeof (*include_dirs));
-          include_dir_count = 1;
-        }
+       {
+         include_dirs = XNEWVEC (const char *, 1);
+         include_dir_count = 1;
+       }
       include_dirs[0] = dir;
       if (len > include_dir_maxlen)
-        include_dir_maxlen = len;
+       include_dir_maxlen = len;
     }
   else if (include_dirs != NULL)
     include_dirs[0] = ".";
 }
 
-/* .include "filename" | filename 
+/* .include "filename" | filename
    .copy    "filename" | filename
 
-   FIXME 'include' file should be omitted from any output listing, 
+   FIXME 'include' file should be omitted from any output listing,
      'copy' should be included in any output listing
    FIXME -- prevent any included files from changing listing (compat only)
    FIXME -- need to include source file directory in search path; what's a
       good way to do this?
 
    Entering/exiting included/copied file clears all local labels.  */
+
 static void
-tic54x_include (ignored)
-  int ignored ATTRIBUTE_UNUSED;
+tic54x_include (int ignored ATTRIBUTE_UNUSED)
 {
   char newblock[] = " .newblock\n";
   char *filename;
@@ -1896,7 +1903,7 @@ tic54x_include (ignored)
   int len, c = -1;
 
   ILLEGAL_WITHIN_STRUCT ();
-  
+
   SKIP_WHITESPACE ();
 
   if (*input_line_pointer == '"')
@@ -1907,11 +1914,11 @@ tic54x_include (ignored)
   else
     {
       filename = input_line_pointer;
-      while (!is_end_of_line[(int)*input_line_pointer])
-        ++input_line_pointer;
+      while (!is_end_of_line[(unsigned char) *input_line_pointer])
+       ++input_line_pointer;
       c = *input_line_pointer;
       *input_line_pointer = '\0';
-      filename = strcpy (xmalloc (strlen (filename)+1), filename);
+      filename = xstrdup (filename);
       *input_line_pointer = c;
       demand_empty_rest_of_line ();
     }
@@ -1919,20 +1926,18 @@ tic54x_include (ignored)
      and a .newblock.
      The included file will be inserted before the newblock, so that the
      newblock is executed after the included file is processed.  */
-  input = xmalloc (sizeof (newblock) + strlen (filename) + 4);
-  sprintf (input, "\"%s\"\n%s", filename, newblock);
+  input = concat ("\"", filename, "\"\n", newblock, (char *) NULL);
   input_scrub_insert_line (input);
 
   tic54x_clear_local_labels (0);
 
-  tic54x_set_default_include (0);
+  tic54x_set_default_include ();
 
   s_include (0);
 }
 
 static void
-tic54x_message (type)
-     int type;
+tic54x_message (int type)
 {
   char *msg;
   char c;
@@ -1945,11 +1950,11 @@ tic54x_message (type)
   else
     {
       msg = input_line_pointer;
-      while (! is_end_of_line[(int)*input_line_pointer])
-        ++input_line_pointer;
+      while (!is_end_of_line[(unsigned char) *input_line_pointer])
+       ++input_line_pointer;
       c = *input_line_pointer;
       *input_line_pointer = 0;
-      msg = strcpy (xmalloc (strlen (msg) + 1), msg);
+      msg = xstrdup (msg);
       *input_line_pointer = c;
     }
 
@@ -1969,114 +1974,111 @@ tic54x_message (type)
   demand_empty_rest_of_line ();
 }
 
-/* .label <symbol> 
-   define a special symbol that refers to the loadtime address rather than the
+/* .label <symbol>
+   Define a special symbol that refers to the loadtime address rather than the
    runtime address within the current section.
 
    This symbol gets a special storage class so that when it is resolved, it is
    resolved relative to the load address (lma) of the section rather than the
    run address (vma).  */
+
 static void
-tic54x_label (ignored)
-  int ignored ATTRIBUTE_UNUSED;
+tic54x_label (int ignored ATTRIBUTE_UNUSED)
 {
-  char *name = input_line_pointer;
+  char *name;
   symbolS *symbolP;
   int c;
 
   ILLEGAL_WITHIN_STRUCT ();
 
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   symbolP = colon (name);
   S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
 
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
   demand_empty_rest_of_line ();
 }
 
 /* .mmregs
-   install all memory-mapped register names into the symbol table as absolute
-   local symbols.  */
+   Install all memory-mapped register names into the symbol table as
+   absolute local symbols.  */
+
 static void
-tic54x_mmregs (ignored)
-  int ignored ATTRIBUTE_UNUSED;
+tic54x_mmregs (int ignored ATTRIBUTE_UNUSED)
 {
-  symbol *sym;
+  tic54x_symbol *sym;
 
   ILLEGAL_WITHIN_STRUCT ();
 
-  for (sym = (symbol *)mmregs; sym->name; sym++)
+  for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
     {
       symbolS *symbolP = symbol_new (sym->name, absolute_section,
-                                     (valueT) sym->value, &zero_address_frag);
+                                    (valueT) sym->value, &zero_address_frag);
       SF_SET_LOCAL (symbolP);
       symbol_table_insert (symbolP);
     }
 }
 
 /* .loop [count]
-   count defaults to 1024.  */
+   Count defaults to 1024.  */
+
 static void
 tic54x_loop (int count)
 {
   ILLEGAL_WITHIN_STRUCT ();
 
   SKIP_WHITESPACE ();
-  if (!is_end_of_line[(int)*input_line_pointer])
-      count = get_absolute_expression ();
+  if (!is_end_of_line[(unsigned char) *input_line_pointer])
+    count = get_absolute_expression ();
 
-  do_repeat (count, "LOOP", "ENDLOOP");
+  do_repeat ((size_t) count, "LOOP", "ENDLOOP");
 }
 
 /* Normally, endloop gets eaten by the preceding loop.  */
+
 static void
-tic54x_endloop (ignore)
-  int ignore ATTRIBUTE_UNUSED;
+tic54x_endloop (int ignore ATTRIBUTE_UNUSED)
 {
   as_bad (_("ENDLOOP without corresponding LOOP"));
   ignore_rest_of_line ();
 }
 
 /* .break [condition].  */
+
 static void
-tic54x_break (ignore)
-  int ignore ATTRIBUTE_UNUSED;
+tic54x_break (int ignore ATTRIBUTE_UNUSED)
 {
   int cond = 1;
 
   ILLEGAL_WITHIN_STRUCT ();
 
   SKIP_WHITESPACE ();
-  if (!is_end_of_line[(int)*input_line_pointer])
-    {
-      cond = get_absolute_expression ();
-    }
+  if (!is_end_of_line[(unsigned char) *input_line_pointer])
+    cond = get_absolute_expression ();
+
   if (cond)
-    {
-      end_repeat (substitution_line ? 1 : 0);
-    }
+    end_repeat (substitution_line ? 1 : 0);
 }
 
 static void
-set_address_mode (mode)
-  int mode;
+set_address_mode (int mode)
 {
   amode = mode;
   if (mode == far_mode)
     {
-      symbolS *symbolP = symbol_new ("__allow_far", absolute_section, 
-                                    (valueT)1, &zero_address_frag);
+      symbolS *symbolP = symbol_new ("__allow_far", absolute_section,
+                                    (valueT) 1, &zero_address_frag);
       SF_SET_LOCAL (symbolP);
       symbol_table_insert (symbolP);
     }
 }
 
 static int address_mode_needs_set = 1;
+
 static void
-tic54x_address_mode (mode)
-  int mode;
+tic54x_address_mode (int mode)
 {
-  if (assembly_begun && amode != (unsigned)mode)
+  if (assembly_begun && amode != (unsigned) mode)
     {
       as_bad (_("Mixing of normal and extended addressing not supported"));
       ignore_rest_of_line ();
@@ -2094,10 +2096,10 @@ tic54x_address_mode (mode)
 }
 
 /* .sblock "section"|section [,...,"section"|section]
-   designate initialized sections for blocking.  */
+   Designate initialized sections for blocking.  */
+
 static void
-tic54x_sblock (ignore)
-  int ignore ATTRIBUTE_UNUSED;
+tic54x_sblock (int ignore ATTRIBUTE_UNUSED)
 {
   int c = ',';
 
@@ -2107,52 +2109,53 @@ tic54x_sblock (ignore)
     {
       segT seg;
       char *name;
-      
+
       if (*input_line_pointer == '"')
-        {
-          int len;
-          name = demand_copy_C_string (&len);
-        }
+       {
+         int len;
+
+         name = demand_copy_C_string (&len);
+       }
       else
-        {
-          char *section_name = input_line_pointer;
-          c = get_symbol_end ();
-          name = xmalloc (strlen (section_name)+1);
-          strcpy (name, section_name);
-          *input_line_pointer = c;
-        }
+       {
+         char *section_name;
+
+         c = get_symbol_name (&section_name);
+         name = xstrdup (section_name);
+         (void) restore_line_pointer (c);
+       }
 
       seg = bfd_get_section_by_name (stdoutput, name);
       if (seg == NULL)
-        {
-          as_bad (_("Unrecognized section '%s'"), name);
-          ignore_rest_of_line ();
-          return;
-        }
+       {
+         as_bad (_("Unrecognized section '%s'"), name);
+         ignore_rest_of_line ();
+         return;
+       }
       else if (!tic54x_initialized_section (seg))
-        {
-          as_bad (_(".sblock may be used for initialized sections only"));
-          ignore_rest_of_line ();
-          return;
-        }
-      seg->flags |= SEC_BLOCK;
+       {
+         as_bad (_(".sblock may be used for initialized sections only"));
+         ignore_rest_of_line ();
+         return;
+       }
+      seg->flags |= SEC_TIC54X_BLOCK;
 
       c = *input_line_pointer;
-      if (!is_end_of_line[(int)c])
-        ++input_line_pointer;
+      if (!is_end_of_line[(unsigned char) c])
+       ++input_line_pointer;
     }
 
   demand_empty_rest_of_line ();
 }
 
 /* symbol .set value
-   symbol .equ value 
+   symbol .equ value
 
    value must be defined externals; no forward-referencing allowed
    symbols assigned with .set/.equ may not be redefined.  */
+
 static void
-tic54x_set (ignore)
-  int ignore ATTRIBUTE_UNUSED;
+tic54x_set (int ignore ATTRIBUTE_UNUSED)
 {
   symbolS *symbolP;
   char *name;
@@ -2183,7 +2186,8 @@ tic54x_set (ignore)
 
 /* .fclist
    .fcnolist
-   list false conditional blocks.  */
+   List false conditional blocks.  */
+
 static void
 tic54x_fclist (int show)
 {
@@ -2202,11 +2206,11 @@ tic54x_sslist (int show)
   listing_sslist = show;
 }
 
-/* .var SYM[,...,SYMN] 
-   define a substitution string to be local to a macro.  */
+/* .var SYM[,...,SYMN]
+   Define a substitution string to be local to a macro.  */
+
 static void
-tic54x_var (ignore)
-  int ignore ATTRIBUTE_UNUSED;
+tic54x_var (int ignore ATTRIBUTE_UNUSED)
 {
   static char empty[] = "";
   char *name;
@@ -2220,41 +2224,40 @@ tic54x_var (ignore)
       ignore_rest_of_line ();
       return;
     }
-  do 
-    {
-      if (!isalpha (*input_line_pointer))
-        {
-          as_bad (_("Substitution symbols must begin with a letter"));
-          ignore_rest_of_line ();
-          return;
-        }
-      name = input_line_pointer;
-      c = get_symbol_end ();
-      /* .var symbols start out with a null string */
-      name = strcpy (xmalloc (strlen (name)+1), name);
+  do
+    {
+      if (!ISALPHA (*input_line_pointer))
+       {
+         as_bad (_("Substitution symbols must begin with a letter"));
+         ignore_rest_of_line ();
+         return;
+       }
+      c = get_symbol_name (&name);
+      /* .var symbols start out with a null string.  */
+      name = xstrdup (name);
       hash_insert (subsym_hash[macro_level], name, empty);
-      *input_line_pointer = c;
+      c = restore_line_pointer (c);
       if (c == ',')
-        {
-          ++input_line_pointer;
-          if (is_end_of_line[(int)*input_line_pointer])
-            c = *input_line_pointer;
-        }
+       {
+         ++input_line_pointer;
+         if (is_end_of_line[(unsigned char) *input_line_pointer])
+           c = *input_line_pointer;
+       }
     }
   while (c == ',');
 
   demand_empty_rest_of_line ();
 }
 
-/* .mlib <macro library filename> 
+/* .mlib <macro library filename>
 
    Macro libraries are archived (standard AR-format) text macro definitions
    Expand the file and include it.
 
    FIXME need to try the source file directory as well.  */
+
 static void
-tic54x_mlib (ignore)
-  int ignore ATTRIBUTE_UNUSED;
+tic54x_mlib (int ignore ATTRIBUTE_UNUSED)
 {
   char *filename;
   char *path;
@@ -2263,42 +2266,45 @@ tic54x_mlib (ignore)
 
   ILLEGAL_WITHIN_STRUCT ();
 
-  /* parse the filename */
+  /* Parse the filename.  */
   if (*input_line_pointer == '"')
     {
       if ((filename = demand_copy_C_string (&len)) == NULL)
-        return;
+       return;
     }
   else
     {
       SKIP_WHITESPACE ();
       len = 0;
-      while (! is_end_of_line[(int)*input_line_pointer]
-             && !isspace (*input_line_pointer))
-        {
-          obstack_1grow (&notes, *input_line_pointer);
-          ++input_line_pointer;
-          ++len;
-        }
+      while (!is_end_of_line[(unsigned char) *input_line_pointer]
+            && !ISSPACE (*input_line_pointer))
+       {
+         obstack_1grow (&notes, *input_line_pointer);
+         ++input_line_pointer;
+         ++len;
+       }
       obstack_1grow (&notes, '\0');
       filename = obstack_finish (&notes);
     }
   demand_empty_rest_of_line ();
 
-  tic54x_set_default_include (0);
-  path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
-  for (i=0;i < include_dir_count; i++)
+  tic54x_set_default_include ();
+  path = XNEWVEC (char, (unsigned long) len + include_dir_maxlen + 5);
+
+  for (i = 0; i < include_dir_count; i++)
     {
       FILE *try;
+
       strcpy (path, include_dirs[i]);
       strcat (path, "/");
       strcat (path, filename);
       if ((try = fopen (path, "r")) != NULL)
-        {
-          fclose (try);
-          break;
-        }
-  }
+       {
+         fclose (try);
+         break;
+       }
+    }
+
   if (i >= include_dir_count)
     {
       free (path);
@@ -2307,15 +2313,15 @@ tic54x_mlib (ignore)
 
   /* FIXME: if path is found, malloc'd storage is not freed.  Of course, this
      happens all over the place, and since the assembler doesn't usually keep
-     running for a very long time, it really doesn't matter...  */ 
+     running for a very long time, it really doesn't matter.  */
   register_dependency (path);
 
   /* Expand all archive entries to temporary files and include them.  */
   abfd = bfd_openr (path, NULL);
   if (!abfd)
     {
-      as_bad (_("Can't open macro library file '%s' for reading."), path);
-      as_perror ("%s", path);
+      as_bad (_("can't open macro library file '%s' for reading: %s"),
+             path, bfd_errmsg (bfd_get_error ()));
       ignore_rest_of_line ();
       return;
     }
@@ -2332,19 +2338,19 @@ tic54x_mlib (ignore)
     {
       /* Get a size at least as big as the archive member.  */
       bfd_size_type size = bfd_get_size (mbfd);
-      char *buf = xmalloc (size);
+      char *buf = XNEWVEC (char, size);
       char *fname = tmpnam (NULL);
       FILE *ftmp;
 
       /* We're not sure how big it is, but it will be smaller than "size".  */
-      bfd_read (buf, size, 1, mbfd);
+      size = bfd_bread (buf, size, mbfd);
 
-      /* Write to a temporary file, then use s_include to include it 
-         a bit of a hack...  */
+      /* Write to a temporary file, then use s_include to include it
+        a bit of a hack.  */
       ftmp = fopen (fname, "w+b");
-      fwrite ((void *)buf, size, 1, ftmp);
-      if (buf[size-1] != '\n')
-        fwrite ("\n", 1, 1, ftmp);
+      fwrite ((void *) buf, size, 1, ftmp);
+      if (size == 0 || buf[size - 1] != '\n')
+       fwrite ("\n", 1, 1, ftmp);
       fclose (ftmp);
       free (buf);
       input_scrub_insert_file (fname);
@@ -2352,114 +2358,95 @@ tic54x_mlib (ignore)
     }
 }
 
-const pseudo_typeS md_pseudo_table[] = 
-{
-  { "algebraic", s_ignore, 0 },
-  { "align", tic54x_align_words, 128 }, 
-  { "even", tic54x_align_words, 2 }, 
-  { "asg", tic54x_asg, 0 },
-  { "eval", tic54x_eval, 0 },
-  { "bss", tic54x_bss, 0 },
-  { "byte", tic54x_cons, 'b' },
-  { "ubyte", tic54x_cons, 'B' },
-  { "char", tic54x_cons, 'c' },
-  { "uchar", tic54x_cons, 'C' },
-  { "clink", tic54x_clink, 0 },
-  { "c_mode", tic54x_address_mode, c_mode },
-  { "copy", tic54x_include, 'c' },
-  { "include", tic54x_include, 'i' },
-  { "data", tic54x_sect, 'd' },
-  { "double", tic54x_float_cons, 'd' },
-  { "ldouble", tic54x_float_cons, 'l' },
-  { "drlist", s_ignore, 0 },
-  { "drnolist", s_ignore, 0 },
-  { "emsg", tic54x_message, 'e' },
-  { "mmsg", tic54x_message, 'm' },
-  { "wmsg", tic54x_message, 'w' },
-  /*{ "end",     s_end,                   0 }, */
-  { "far_mode", tic54x_address_mode, far_mode }, 
-  { "fclist",   tic54x_fclist, 1 },
-  { "fcnolist", tic54x_fclist, 0 },
-  { "field", tic54x_field, -1 },
-  { "float", tic54x_float_cons, 'f' },
-  { "xfloat",  tic54x_float_cons, 'x' },
-  { "global", tic54x_global, 'g' },
-  { "def", tic54x_global, 'd' },
-  { "ref", tic54x_global, 'r' },
-  { "half", tic54x_cons, 'h' },
-  { "uhalf", tic54x_cons, 'H' },
-  { "short", tic54x_cons, 's' },
-  { "ushort", tic54x_cons, 'S' },
-  { "if", s_if, (int)O_ne },
-  { "elseif", s_elseif, (int)O_ne },
-  { "else", s_else, 0 },
-  { "endif", s_endif, 0 },
-  { "int", tic54x_cons, 'i' },
-  { "uint", tic54x_cons, 'I' },
-  { "word", tic54x_cons, 'w' },
-  { "uword", tic54x_cons, 'W' },
-  { "label", tic54x_label, 0 }, /* loadtime address */
-  { "length",   s_ignore, 0 }, 
-  { "width",    s_ignore, 0 }, 
-  /*{ "list",     listing_list,      1 }, */
-  /*{ "nolist",   listing_list,      0 }, */
-  { "long", tic54x_cons, 'l' }, 
-  { "ulong", tic54x_cons, 'L' }, 
-  { "xlong", tic54x_cons, 'x' }, 
-  { "loop", tic54x_loop, 1024 }, 
-  { "break", tic54x_break, 0 }, 
-  { "endloop", tic54x_endloop, 0 }, 
-  { "mlib", tic54x_mlib, 0 }, 
-  { "mlist",     s_ignore, 0 }, 
-  { "mnolist",     s_ignore, 0 }, 
-  { "mmregs", tic54x_mmregs, 0 }, 
-  { "newblock", tic54x_clear_local_labels, 0 }, 
-  { "option",     s_ignore, 0 }, 
-  { "p2align", tic54x_p2align, 0 },
-  /*{ "page",     listing_eject,      0 }, */
-  { "sblock", tic54x_sblock, 0 }, 
-  { "sect", tic54x_sect, '*' }, 
-  { "set", tic54x_set, 0 }, 
-  { "equ", tic54x_set, 0 }, 
-  { "space", tic54x_space, 0 }, 
-  { "bes", tic54x_space, 1 }, 
-  { "sslist", tic54x_sslist, 1 }, 
-  { "ssnolist", tic54x_sslist, 0 }, 
-  { "string", tic54x_stringer, 's' },
-  { "pstring", tic54x_stringer, 'p' },
-  { "struct", tic54x_struct, 0 }, 
-  { "tag", tic54x_tag, 0 }, 
-  { "endstruct", tic54x_endstruct, 0 }, 
-  { "tab",     s_ignore, 0 }, 
-  { "text", tic54x_sect, 't' }, 
-  /*{ "title",     listing_title,      0 }, */
-  { "union", tic54x_struct, 1 }, 
-  { "endunion", tic54x_endstruct, 1 }, 
-  { "usect", tic54x_usect, 0 }, 
-  { "var", tic54x_var, 0 }, 
-  { "version", tic54x_version, 0 }, 
-  {0, 0, 0}
-};
-
-#if 0
-/* For debugging, strings for each operand type.  */
-static const char *optypes[] = 
-{
-  "none", "Xmem", "Ymem", "pmad", "dmad", "Smem", "Lmem", "MMR", "PA",
-  "Sind", "xpmad", "xpmad+", "MMRX", "MMRY", 
-  "SRC1", "SRC", "RND", "DST", 
-  "ARX", 
-  "SHIFT", "SHFT",
-  "B", "A", "lk", "TS", "k8", "16", "BITC", "CC", "CC2", "CC3", "123", "031", 
-  "k5", "k8u", "ASM", "T", "DP", "ARP", "k3", "lku", "N", "SBIT", "12",
-  "k9", "TRN",
+const pseudo_typeS md_pseudo_table[] =
+{
+  { "algebraic", s_ignore                 ,          0 },
+  { "align"    , tic54x_align_words       ,        128 },
+  { "ascii"    , tic54x_stringer          ,        'p' },
+  { "asciz"    , tic54x_stringer          ,        'P' },
+  { "even"     , tic54x_align_words       ,          2 },
+  { "asg"      , tic54x_asg               ,          0 },
+  { "eval"     , tic54x_eval              ,          0 },
+  { "bss"      , tic54x_bss               ,          0 },
+  { "byte"     , tic54x_cons              ,        'b' },
+  { "ubyte"    , tic54x_cons              ,        'B' },
+  { "char"     , tic54x_cons              ,        'c' },
+  { "uchar"    , tic54x_cons              ,        'C' },
+  { "clink"    , tic54x_clink             ,          0 },
+  { "c_mode"   , tic54x_address_mode      ,     c_mode },
+  { "copy"     , tic54x_include           ,        'c' },
+  { "include"  , tic54x_include           ,        'i' },
+  { "data"     , tic54x_sect              ,        'd' },
+  { "double"   , tic54x_float_cons        ,        'd' },
+  { "ldouble"  , tic54x_float_cons        ,        'l' },
+  { "drlist"   , s_ignore                 ,          0 },
+  { "drnolist" , s_ignore                 ,          0 },
+  { "emsg"     , tic54x_message           ,        'e' },
+  { "mmsg"     , tic54x_message           ,        'm' },
+  { "wmsg"     , tic54x_message           ,        'w' },
+  { "far_mode" , tic54x_address_mode      ,   far_mode },
+  { "fclist"   , tic54x_fclist            ,          1 },
+  { "fcnolist" , tic54x_fclist            ,          0 },
+  { "field"    , tic54x_field             ,         -1 },
+  { "float"    , tic54x_float_cons        ,        'f' },
+  { "xfloat"   , tic54x_float_cons        ,        'x' },
+  { "global"   , tic54x_global            ,        'g' },
+  { "def"      , tic54x_global            ,        'd' },
+  { "ref"      , tic54x_global            ,        'r' },
+  { "half"     , tic54x_cons              ,        'h' },
+  { "uhalf"    , tic54x_cons              ,        'H' },
+  { "short"    , tic54x_cons              ,        's' },
+  { "ushort"   , tic54x_cons              ,        'S' },
+  { "if"       , s_if                     , (int) O_ne },
+  { "elseif"   , s_elseif                 , (int) O_ne },
+  { "else"     , s_else                   ,          0 },
+  { "endif"    , s_endif                  ,          0 },
+  { "int"      , tic54x_cons              ,        'i' },
+  { "uint"     , tic54x_cons              ,        'I' },
+  { "word"     , tic54x_cons              ,        'w' },
+  { "uword"    , tic54x_cons              ,        'W' },
+  { "label"    , tic54x_label             ,          0 }, /* Loadtime
+                                                             address.  */
+  { "length"   , s_ignore                 ,          0 },
+  { "width"    , s_ignore                 ,          0 },
+  { "long"     , tic54x_cons              ,        'l' },
+  { "ulong"    , tic54x_cons              ,        'L' },
+  { "xlong"    , tic54x_cons              ,        'x' },
+  { "loop"     , tic54x_loop              ,       1024 },
+  { "break"    , tic54x_break             ,          0 },
+  { "endloop"  , tic54x_endloop           ,          0 },
+  { "mlib"     , tic54x_mlib              ,          0 },
+  { "mlist"    , s_ignore                 ,          0 },
+  { "mnolist"  , s_ignore                 ,          0 },
+  { "mmregs"   , tic54x_mmregs            ,          0 },
+  { "newblock" , tic54x_clear_local_labels,          0 },
+  { "option"   , s_ignore                 ,          0 },
+  { "p2align"  , tic54x_p2align           ,          0 },
+  { "sblock"   , tic54x_sblock            ,          0 },
+  { "sect"     , tic54x_sect              ,        '*' },
+  { "set"      , tic54x_set               ,          0 },
+  { "equ"      , tic54x_set               ,          0 },
+  { "space"    , tic54x_space             ,          0 },
+  { "bes"      , tic54x_space             ,          1 },
+  { "sslist"   , tic54x_sslist            ,          1 },
+  { "ssnolist" , tic54x_sslist            ,          0 },
+  { "string"   , tic54x_stringer          ,        's' },
+  { "pstring"  , tic54x_stringer          ,        'p' },
+  { "struct"   , tic54x_struct            ,          0 },
+  { "tag"      , tic54x_tag               ,          0 },
+  { "endstruct", tic54x_endstruct         ,          0 },
+  { "tab"      , s_ignore                 ,          0 },
+  { "text"     , tic54x_sect              ,        't' },
+  { "union"    , tic54x_struct            ,          1 },
+  { "endunion" , tic54x_endstruct         ,          1 },
+  { "usect"    , tic54x_usect             ,          0 },
+  { "var"      , tic54x_var               ,          0 },
+  { "version"  , tic54x_version           ,          0 },
+  {0           , 0                        ,          0 }
 };
-#endif
 
 int
-md_parse_option (c, arg)
-  int c;
-  char *arg;
+md_parse_option (int c, const char *arg)
 {
   switch (c)
     {
@@ -2467,19 +2454,20 @@ md_parse_option (c, arg)
       return 0;
     case OPTION_COFF_VERSION:
       {
-        int version = atoi (arg);
-        if (version != 0 && version != 1 && version != 2)
-          as_fatal (_("Bad COFF version '%s'"), arg);
-        /* FIXME -- not yet implemented */
-        break;
+       int version = atoi (arg);
+
+       if (version != 0 && version != 1 && version != 2)
+         as_fatal (_("Bad COFF version '%s'"), arg);
+       /* FIXME -- not yet implemented.  */
+       break;
       }
     case OPTION_CPU_VERSION:
       {
-        cpu = lookup_version (arg);
-        cpu_needs_set = 1;
-        if (cpu == VNONE)
-          as_fatal (_("Bad CPU version '%s'"), arg);
-        break;
+       cpu = lookup_version (arg);
+       cpu_needs_set = 1;
+       if (cpu == VNONE)
+         as_fatal (_("Bad CPU version '%s'"), arg);
+       break;
       }
     case OPTION_ADDRESS_MODE:
       amode = far_mode;
@@ -2487,61 +2475,49 @@ md_parse_option (c, arg)
       break;
     case OPTION_STDERR_TO_FILE:
       {
-        char *filename = arg;
-        FILE *fp = fopen (filename, "w+");
-        if (fp == NULL)
-          as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
-        fclose (fp);
-        if ((fp = freopen (filename, "w+", stderr)) == NULL)
-          as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
-        break;
+       const char *filename = arg;
+       FILE *fp = fopen (filename, "w+");
+
+       if (fp == NULL)
+         as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
+       fclose (fp);
+       if ((fp = freopen (filename, "w+", stderr)) == NULL)
+         as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
+       break;
       }
     }
 
   return 1;
 }
 
-/* Create a "local" substitution string hash table for a new macro level 
+/* Create a "local" substitution string hash table for a new macro level
    Some docs imply that macros have to use .newblock in order to be able
    to re-use a local label.  We effectively do an automatic .newblock by
    deleting the local label hash between macro invocations.  */
-void 
-tic54x_macro_start ()
+
+void
+tic54x_macro_start (void)
 {
-  ++macro_level;
+  if (++macro_level >= MAX_SUBSYM_HASH)
+    {
+      as_fatal (_("Macro nesting is too deep"));
+      return;
+    }
   subsym_hash[macro_level] = hash_new ();
   local_label_hash[macro_level] = hash_new ();
 }
 
 void
-tic54x_macro_info (info)
-     void *info;
+tic54x_macro_info (const macro_entry *macro)
 {
-  struct formal_struct
-  {
-    struct formal_struct *next;        /* next formal in list */
-    sb name;                   /* name of the formal */
-    sb def;                    /* the default value */
-    sb actual;                 /* the actual argument (changed on each expansion) */
-    int index;                 /* the index of the formal 0..formal_count-1 */
-  } *entry;
-  struct macro_struct
-  {
-    sb sub;                    /* substitution text. */
-    int formal_count;          /* number of formal args. */
-    struct formal_struct *formals;     /* pointer to list of formal_structs */
-    struct hash_control *formal_hash; /* hash table of formals. */
-  } *macro;
-
-  macro = (struct macro_struct *)info;
+  const formal_entry *entry;
 
   /* Put the formal args into the substitution symbol table.  */
   for (entry = macro->formals; entry; entry = entry->next)
     {
-      char *name = strncpy (xmalloc (entry->name.len + 1),
-                            entry->name.ptr, entry->name.len);
-      char *value = strncpy (xmalloc (entry->actual.len + 1),
-                             entry->actual.ptr, entry->actual.len);
+      char *name = xstrndup (entry->name.ptr, entry->name.len);
+      char *value = xstrndup (entry->actual.ptr, entry->actual.len);
+
       name[entry->name.len] = '\0';
       value[entry->actual.len] = '\0';
       hash_insert (subsym_hash[macro_level], name, value);
@@ -2549,8 +2525,9 @@ tic54x_macro_info (info)
 }
 
 /* Get rid of this macro's .var's, arguments, and local labels.  */
+
 void
-tic54x_macro_end ()
+tic54x_macro_end (void)
 {
   hash_die (subsym_hash[macro_level]);
   subsym_hash[macro_level] = NULL;
@@ -2560,40 +2537,35 @@ tic54x_macro_end ()
 }
 
 static int
-subsym_symlen (a, ignore)
-  char *a;
-  char *ignore ATTRIBUTE_UNUSED;
+subsym_symlen (char *a, char *ignore ATTRIBUTE_UNUSED)
 {
   return strlen (a);
 }
 
 /* Compare symbol A to string B.  */
+
 static int
-subsym_symcmp (a, b)
-     char *a;
-     char *b;
+subsym_symcmp (char *a, char *b)
 {
   return strcmp (a, b);
 }
 
-/* Return the index of the first occurence of B in A, or zero if none 
+/* Return the index of the first occurrence of B in A, or zero if none
    assumes b is an integer char value as a string.  Index is one-based.  */
+
 static int
-subsym_firstch (a, b)
-     char *a;
-     char *b;
+subsym_firstch (char *a, char *b)
 {
   int val = atoi (b);
   char *tmp = strchr (a, val);
-  
+
   return tmp ? tmp - a + 1 : 0;
 }
 
 /* Similar to firstch, but returns index of last occurrence of B in A.  */
+
 static int
-subsym_lastch (a, b)
-  char *a;
-  char *b;
+subsym_lastch (char *a, char *b)
 {
   int val = atoi (b);
   char *tmp = strrchr (a, val);
@@ -2602,11 +2574,10 @@ subsym_lastch (a, b)
 }
 
 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
-   symbol table). */
+   symbol table).  */
+
 static int
-subsym_isdefed (a, ignore)
-  char *a;
-  char *ignore ATTRIBUTE_UNUSED;
+subsym_isdefed (char *a, char *ignore ATTRIBUTE_UNUSED)
 {
   symbolS *symbolP = symbol_find (a);
 
@@ -2616,10 +2587,9 @@ subsym_isdefed (a, ignore)
 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
    A, or zero if B is a null string.  Both arguments *must* be substitution
    symbols, unsubstituted.  */
+
 static int
-subsym_ismember (sym, list)
-     char *sym;
-     char *list;
+subsym_ismember (char *sym, char *list)
 {
   char *elem, *ptr, *listv;
 
@@ -2634,8 +2604,7 @@ subsym_ismember (sym, list)
       return 0;
     }
 
-  ptr = elem = xmalloc (strlen (listv)+1);
-  strcpy (elem, listv);
+  ptr = elem = xstrdup (listv);
   while (*ptr && *ptr != ',')
     ++ptr;
   *ptr++ = 0;
@@ -2644,7 +2613,7 @@ subsym_ismember (sym, list)
 
   /* Reassign the list.  */
   subsym_create_or_replace (list, ptr);
-  
+
   /* Assume this value, docs aren't clear.  */
   return *list != 0;
 }
@@ -2655,39 +2624,38 @@ subsym_ismember (sym, list)
    3 if hexadecimal
    4 if character
    5 if decimal.  */
+
 static int
-subsym_iscons (a, ignore)
-  char *a;
-  char *ignore ATTRIBUTE_UNUSED;
+subsym_iscons (char *a, char *ignore ATTRIBUTE_UNUSED)
 {
-  expressionS exp;
+  expressionS expn;
 
-  parse_expression (a, &exp);
+  parse_expression (a, &expn);
 
-  if (exp.X_op == O_constant)
+  if (expn.X_op == O_constant)
     {
       int len = strlen (a);
 
-      switch (toupper (a[len-1]))
-        {
-        case 'B':
-          return 1;
-        case 'Q':
-          return 2;
-        case 'H':
-          return 3;
-        case '\'':
-          return 4;
-        default:
-          break;
-        }
+      switch (TOUPPER (a[len - 1]))
+       {
+       case 'B':
+         return 1;
+       case 'Q':
+         return 2;
+       case 'H':
+         return 3;
+       case '\'':
+         return 4;
+       default:
+         break;
+       }
       /* No suffix; either octal, hex, or decimal.  */
       if (*a == '0' && len > 1)
-        {
-          if (toupper (a[1]) == 'X')
-            return 3;
-          return 2;
-        }
+       {
+         if (TOUPPER (a[1]) == 'X')
+           return 3;
+         return 2;
+       }
       return 5;
     }
 
@@ -2695,17 +2663,16 @@ subsym_iscons (a, ignore)
 }
 
 /* Return 1 if A is a valid symbol name.  Expects string input.   */
+
 static int
-subsym_isname (a, ignore)
-  char *a;
-  char *ignore ATTRIBUTE_UNUSED;
+subsym_isname (char *a, char *ignore ATTRIBUTE_UNUSED)
 {
   if (!is_name_beginner (*a))
     return 0;
   while (*a)
     {
       if (!is_part_of_name (*a))
-        return 0;
+       return 0;
       ++a;
     }
   return 1;
@@ -2714,10 +2681,9 @@ subsym_isname (a, ignore)
 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
    been seen; if so, recognize any memory-mapped register.
    Note this does not recognize "A" or "B" accumulators.  */
+
 static int
-subsym_isreg (a, ignore)
-  char *a;
-  char *ignore ATTRIBUTE_UNUSED;
+subsym_isreg (char *a, char *ignore ATTRIBUTE_UNUSED)
 {
   if (hash_find (reg_hash, a))
     return 1;
@@ -2726,13 +2692,13 @@ subsym_isreg (a, ignore)
   return 0;
 }
 
-/* Return the structrure size, given the stag.  */
+/* Return the structure size, given the stag.  */
+
 static int
-subsym_structsz (name, ignore)
-  char *name;
-  char *ignore ATTRIBUTE_UNUSED;
+subsym_structsz (char *name, char *ignore ATTRIBUTE_UNUSED)
 {
-  struct stag *stag = (struct stag *)hash_find (stag_hash, name);
+  struct stag *stag = (struct stag *) hash_find (stag_hash, name);
+
   if (stag)
     return stag->size;
 
@@ -2745,167 +2711,134 @@ subsym_structsz (name, ignore)
    structure within another structure, or it might be something else
    altogether.  since the TI assembler doesn't seem to ever do anything but
    return zero, we punt and return zero.  */
+
 static int
-subsym_structacc (stag_name, ignore)
-  char *stag_name ATTRIBUTE_UNUSED;
-  char *ignore ATTRIBUTE_UNUSED;
+subsym_structacc (char *stag_name ATTRIBUTE_UNUSED,
+                 char *ignore ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 static float
-math_ceil (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_ceil (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)ceil (arg1);
+  return (float) ceil (arg1);
 }
 
 static float
-math_cvi (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_cvi (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (int)arg1;
+  return (int) arg1;
 }
 
 static float
-math_floor (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_floor (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)floor (arg1);
+  return (float) floor (arg1);
 }
 
 static float
 math_fmod (float arg1, float arg2)
 {
-  return (int)arg1 % (int)arg2;
+  return (int) arg1 % (int) arg2;
 }
 
 static float
-math_int (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_int (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return ((float)((int)arg1)) == arg1;
+  return ((float) ((int) arg1)) == arg1;
 }
 
 static float
-math_round (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_round (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return arg1 > 0 ? (int)(arg1 + 0.5) : (int)(arg1 - 0.5);
+  return arg1 > 0 ? (int) (arg1 + 0.5) : (int) (arg1 - 0.5);
 }
 
 static float
-math_sgn (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_sgn (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
   return (arg1 < 0) ? -1 : (arg1 ? 1 : 0);
 }
 
 static float
-math_trunc (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_trunc (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (int)arg1;
+  return (int) arg1;
 }
 
 static float
-math_acos (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_acos (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)acos (arg1);
+  return (float) acos (arg1);
 }
 
 static float
-math_asin (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_asin (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)asin (arg1);
+  return (float) asin (arg1);
 }
 
 static float
-math_atan (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_atan (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)atan (arg1);
+  return (float) atan (arg1);
 }
 
 static float
-math_atan2(float arg1, float arg2)
+math_atan2 (float arg1, float arg2)
 {
-  return (float)atan2 (arg1, arg2);
+  return (float) atan2 (arg1, arg2);
 }
 
 static float
-math_cosh (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_cosh (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)cosh (arg1);
+  return (float) cosh (arg1);
 }
 
 static float
-math_cos (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_cos (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)cos (arg1);
+  return (float) cos (arg1);
 }
 
 static float
-math_cvf (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_cvf (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)arg1;
+  return (float) arg1;
 }
 
 static float
-math_exp (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_exp (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)exp (arg1);
+  return (float) exp (arg1);
 }
 
 static float
-math_fabs (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_fabs (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)fabs (arg1);
+  return (float) fabs (arg1);
 }
 
 /* expr1 * 2^expr2.  */
+
 static float
 math_ldexp (float arg1, float arg2)
 {
-  return arg1 * (float)pow (2.0, arg2);
+  return arg1 * (float) pow (2.0, arg2);
 }
 
 static float
-math_log10 (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_log10 (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)log10 (arg1);
+  return (float) log10 (arg1);
 }
 
 static float
-math_log (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_log (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)log (arg1);
+  return (float) log (arg1);
 }
 
 static float
@@ -2923,54 +2856,44 @@ math_min (float arg1, float arg2)
 static float
 math_pow (float arg1, float arg2)
 {
-  return (float)pow (arg1, arg2);
+  return (float) pow (arg1, arg2);
 }
 
 static float
-math_sin (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_sin (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)sin (arg1);
+  return (float) sin (arg1);
 }
 
 static float
-math_sinh (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_sinh (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)sinh (arg1);
+  return (float) sinh (arg1);
 }
 
 static float
-math_sqrt (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_sqrt (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)sqrt (arg1);
+  return (float) sqrt (arg1);
 }
 
 static float
-math_tan (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_tan (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)tan (arg1);
+  return (float) tan (arg1);
 }
 
 static float
-math_tanh (arg1, ignore)
-  float arg1;
-  float ignore ATTRIBUTE_UNUSED;
+math_tanh (float arg1, float ignore ATTRIBUTE_UNUSED)
 {
-  return (float)tanh (arg1);
+  return (float) tanh (arg1);
 }
 
 /* Built-in substitution symbol functions and math functions.  */
-typedef struct 
+typedef struct
 {
-  char *name;
-  int (*proc)(char *, char *);
+  const char *name;
+  int (*proc) (char *, char *);
   int nargs;
 } subsym_proc_entry;
 
@@ -2993,8 +2916,8 @@ static const subsym_proc_entry subsym_procs[] =
 
 typedef struct
 {
-  char *name;
-  float (*proc)(float, float);
+  const char *name;
+  float (*proc) (float, float);
   int nargs;
   int int_return;
 } math_proc_entry;
@@ -3010,7 +2933,7 @@ static const math_proc_entry math_procs[] =
   { "$acos", math_acos, 1, 0 },
   { "$asin", math_asin, 1, 0 },
   { "$atan", math_atan, 1, 0 },
-  { "$atan2", math_atan2, 2, 0 }, 
+  { "$atan2", math_atan2, 2, 0 },
   { "$ceil", math_ceil, 1, 0 },
   { "$cosh", math_cosh, 1, 0 },
   { "$cos", math_cos, 1, 0 },
@@ -3036,11 +2959,10 @@ static const math_proc_entry math_procs[] =
 };
 
 void
-md_begin ()
+md_begin (void)
 {
-  template *opcode;
-  partemplate *paropcode;
-  symbol *sym;
+  insn_template *tm;
+  tic54x_symbol *sym;
   const subsym_proc_entry *subsym_proc;
   const math_proc_entry *math_proc;
   const char *hash_err;
@@ -3050,340 +2972,296 @@ md_begin ()
 
   local_label_id = 0;
 
-  /* Look for A_DIR and add it to the include list. a */
+  /* Look for A_DIR and add it to the include list.  */
   if (A_DIR != NULL)
     {
       char *tmp = xstrdup (A_DIR);
-      do {
-        char *next = strchr (tmp, ';');
-        if (next)
-          *next++ = '\0';
-        add_include_dir (tmp);
-        tmp = next;
-      } while (tmp != NULL);
+
+      do
+       {
+         char *next = strchr (tmp, ';');
+
+         if (next)
+           *next++ = '\0';
+         add_include_dir (tmp);
+         tmp = next;
+       }
+      while (tmp != NULL);
     }
 
   op_hash = hash_new ();
-  for (opcode=(template *)tic54x_optab; opcode->name; opcode++)
+  for (tm = (insn_template *) tic54x_optab; tm->name; tm++)
     {
-      if (hash_find (op_hash, opcode->name))
-        continue;
-      hash_err = hash_insert (op_hash, opcode->name, (char *)opcode);
+      if (hash_find (op_hash, tm->name))
+       continue;
+      hash_err = hash_insert (op_hash, tm->name, (char *) tm);
       if (hash_err)
-        as_fatal ("Internal Error: Can't hash %s: %s", 
-                  opcode->name, hash_err);
+       as_fatal ("Internal Error: Can't hash %s: %s",
+                 tm->name, hash_err);
     }
   parop_hash = hash_new ();
-  for (paropcode=(partemplate *)tic54x_paroptab; paropcode->name; paropcode++)
+  for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
     {
-      if (hash_find (parop_hash, paropcode->name))
-        continue;
-      hash_err = hash_insert (parop_hash, paropcode->name, (char *)paropcode);
+      if (hash_find (parop_hash, tm->name))
+       continue;
+      hash_err = hash_insert (parop_hash, tm->name, (char *) tm);
       if (hash_err)
-        as_fatal ("Internal Error: Can't hash %s: %s", 
-                  paropcode->name, hash_err);
+       as_fatal ("Internal Error: Can't hash %s: %s",
+                 tm->name, hash_err);
     }
   reg_hash = hash_new ();
-  for (sym = (symbol *)regs; sym->name; sym++)
+  for (sym = (tic54x_symbol *) regs; sym->name; sym++)
     {
       /* Add basic registers to the symbol table.  */
       symbolS *symbolP = symbol_new (sym->name, absolute_section,
-                                     (valueT)sym->value, &zero_address_frag);
+                                    (valueT) sym->value, &zero_address_frag);
       SF_SET_LOCAL (symbolP);
       symbol_table_insert (symbolP);
-      hash_err = hash_insert (reg_hash, sym->name, (char *)sym);
+      hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
     }
-  for (sym = (symbol *)mmregs; sym->name; sym++)
-    hash_err = hash_insert (reg_hash, sym->name, (char *)sym);
+  for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
+    hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
   mmreg_hash = hash_new ();
-  for (sym = (symbol *)mmregs; sym->name; sym++)
-    {
-      hash_err = hash_insert (mmreg_hash, sym->name, (char *)sym);
-    }
+  for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
+    hash_err = hash_insert (mmreg_hash, sym->name, (char *) sym);
+
   cc_hash = hash_new ();
-  for (sym = (symbol *)condition_codes; sym->name; sym++)
-    {
-      hash_err = hash_insert (cc_hash, sym->name, (char *)sym);
-    }
+  for (sym = (tic54x_symbol *) condition_codes; sym->name; sym++)
+    hash_err = hash_insert (cc_hash, sym->name, (char *) sym);
+
   cc2_hash = hash_new ();
-  for (sym = (symbol *)cc2_codes; sym->name; sym++)
-    {
-      hash_err = hash_insert (cc2_hash, sym->name, (char *)sym);
-    }
+  for (sym = (tic54x_symbol *) cc2_codes; sym->name; sym++)
+    hash_err = hash_insert (cc2_hash, sym->name, (char *) sym);
+
   cc3_hash = hash_new ();
-  for (sym = (symbol *)cc3_codes; sym->name; sym++)
-    {
-      hash_err = hash_insert (cc3_hash, sym->name, (char *)sym);
-    }
+  for (sym = (tic54x_symbol *) cc3_codes; sym->name; sym++)
+    hash_err = hash_insert (cc3_hash, sym->name, (char *) sym);
+
   sbit_hash = hash_new ();
-  for (sym = (symbol *)status_bits; sym->name; sym++)
-    {
-      hash_err = hash_insert (sbit_hash, sym->name, (char *)sym);
-    }
+  for (sym = (tic54x_symbol *) status_bits; sym->name; sym++)
+    hash_err = hash_insert (sbit_hash, sym->name, (char *) sym);
+
   misc_symbol_hash = hash_new ();
-  for (symname = (char **)misc_symbols; *symname; symname++)
-    {
-      hash_err = hash_insert (misc_symbol_hash, *symname, *symname);
-    }
+  for (symname = (char **) misc_symbols; *symname; symname++)
+    hash_err = hash_insert (misc_symbol_hash, *symname, *symname);
+
   /* Only the base substitution table and local label table are initialized;
      the others (for local macro substitution) get instantiated as needed.  */
   local_label_hash[0] = hash_new ();
   subsym_hash[0] = hash_new ();
   for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++)
-    {
-      hash_err = hash_insert (subsym_hash[0], subsym_proc->name, 
-                              (char *)subsym_proc);
-    }
+    hash_err = hash_insert (subsym_hash[0], subsym_proc->name,
+                           (char *) subsym_proc);
+
   math_hash = hash_new ();
   for (math_proc = math_procs; math_proc->name; math_proc++)
     {
       /* Insert into the main subsym hash for recognition; insert into
-         the math hash to actually store information.  */
+        the math hash to actually store information.  */
       hash_err = hash_insert (subsym_hash[0], math_proc->name,
-                              (char *)math_proc);
+                             (char *) math_proc);
       hash_err = hash_insert (math_hash, math_proc->name,
-                              (char *)math_proc);
+                             (char *) math_proc);
     }
   subsym_recurse_hash = hash_new ();
   stag_hash = hash_new ();
 }
 
-typedef struct _tic54x_insn
-{
-  const template *tm;               /* opcode template */
-  const partemplate *ptm;           /* parallel opcode template */
-
-  char mnemonic[MAX_LINE];          /* opcode name/mnemonic */
-  char parmnemonic[MAX_LINE];       /* 2nd mnemonic of parallel insn */
-
-  int opcount;
-  struct opstruct
-  {
-    char buf[MAX_LINE];
-    enum optype type;
-    expressionS exp;
-  } operands[MAX_OPERANDS];
-
-  int paropcount;
-  struct opstruct paroperands[MAX_OPERANDS];
-
-  int is_lkaddr;
-  int lkoperand;
-  int words;                        /* size of insn in 16-bit words */
-  int using_default_dst;            /* do we need to explicitly set an 
-                                       omitted OP_DST operand? */
-  struct
-  {
-    unsigned short word;            /* final encoded opcode data */
-    int unresolved;
-    int r_nchars;                     /* relocation size */
-    bfd_reloc_code_real_type r_type; /* relocation type */
-    expressionS addr_expr;          /* storage for unresolved expressions */
-  } opcode[3];
-} tic54x_insn;
-
-static int encode_operand (tic54x_insn *, enum optype, struct opstruct *);
-static int encode_dmad (tic54x_insn *, struct opstruct *, int);
-static int operands_match (tic54x_insn *, struct opstruct *, int, 
-                           const enum optype *, int, int);
-static int encode_address (tic54x_insn *, struct opstruct *);
-
 static int
-is_accumulator (operand)
-     struct opstruct *operand;
+is_accumulator (struct opstruct *operand)
 {
-  return strcasecmp (operand->buf, "a") == 0 
+  return strcasecmp (operand->buf, "a") == 0
     || strcasecmp (operand->buf, "b") == 0;
 }
 
-/* Return the number of operands found, or -1 on error, copying the operands
-   into the given array and the accompanying expressions into the next array.  */
+/* Return the number of operands found, or -1 on error, copying the
+   operands into the given array and the accompanying expressions into
+   the next array.  */
+
 static int
-get_operands (operands, line)
-  struct opstruct operands[];
-  char *line;
+get_operands (struct opstruct operands[], char *line)
 {
   char *lptr = line;
   int numexp = 0;
   int expecting_operand = 0;
   int i;
 
-  while (numexp < MAX_OPERANDS && !is_end_of_line[(int)*lptr])
+  while (numexp < MAX_OPERANDS && !is_end_of_line[(unsigned char) *lptr])
     {
       int paren_not_balanced = 0;
       char *op_start, *op_end;
-      while (*lptr && isspace (*lptr))
-        ++lptr;
+
+      while (*lptr && ISSPACE (*lptr))
+       ++lptr;
       op_start = lptr;
       while (paren_not_balanced || *lptr != ',')
-        {
-          if (*lptr == '\0')
-            {
-              if (paren_not_balanced)
-                {
-                  as_bad ("Unbalanced parenthesis in operand %d", numexp);
-                  return -1;
-                }
-              else
-                break;
-            }
-          if (*lptr == '(')
-            ++paren_not_balanced;
-          else if (*lptr == ')')
-            --paren_not_balanced;
-          ++lptr;
-        }
+       {
+         if (*lptr == '\0')
+           {
+             if (paren_not_balanced)
+               {
+                 as_bad (_("Unbalanced parenthesis in operand %d"), numexp);
+                 return -1;
+               }
+             else
+               break;
+           }
+         if (*lptr == '(')
+           ++paren_not_balanced;
+         else if (*lptr == ')')
+           --paren_not_balanced;
+         ++lptr;
+       }
       op_end = lptr;
       if (op_end != op_start)
-        {
-          int len = op_end - op_start;
-          strncpy (operands[numexp].buf, op_start, len);
-          operands[numexp].buf[len] = 0;
-          /* Trim trailing spaces; while the preprocessor gets rid of most,
-             there are weird usage patterns that can introduce them
-             (i.e. using strings for macro args).  */
-          while (len > 0 && isspace (operands[numexp].buf[len-1]))
-            operands[numexp].buf[--len] = 0;
-          lptr = op_end;
-          ++numexp;
-        }
-      else 
-        {
-          if (expecting_operand || *lptr == ',')
-            {
-              as_bad ("Expecting operand after ','");
-              return -1;
-            }
-        }
+       {
+         int len = op_end - op_start;
+
+         strncpy (operands[numexp].buf, op_start, len);
+         operands[numexp].buf[len] = 0;
+         /* Trim trailing spaces; while the preprocessor gets rid of most,
+            there are weird usage patterns that can introduce them
+            (i.e. using strings for macro args).  */
+         while (len > 0 && ISSPACE (operands[numexp].buf[len - 1]))
+           operands[numexp].buf[--len] = 0;
+         lptr = op_end;
+         ++numexp;
+       }
+      else
+       {
+         if (expecting_operand || *lptr == ',')
+           {
+             as_bad (_("Expecting operand after ','"));
+             return -1;
+           }
+       }
       if (*lptr == ',')
-        {
-          if (*++lptr == '\0')
-            {
-              as_bad ("Expecting operand after ','");
-              return -1;
-            }
-          expecting_operand = 1;
-        }
+       {
+         if (*++lptr == '\0')
+           {
+             as_bad (_("Expecting operand after ','"));
+             return -1;
+           }
+         expecting_operand = 1;
+       }
     }
 
-  while (*lptr && isspace (*lptr++))
+  while (*lptr && ISSPACE (*lptr++))
     ;
-  if (!is_end_of_line[(int)*lptr])
+  if (!is_end_of_line[(unsigned char) *lptr])
     {
-      as_bad ("Extra junk on line");
+      as_bad (_("Extra junk on line"));
       return -1;
     }
 
   /* OK, now parse them into expressions.  */
-  for (i=0;i < numexp;i++)
+  for (i = 0; i < numexp; i++)
     {
       memset (&operands[i].exp, 0, sizeof (operands[i].exp));
       if (operands[i].buf[0] == '#')
-        {
-          /* immediate */
-          parse_expression (operands[i].buf + 1, &operands[i].exp);
-        }
+       {
+         /* Immediate.  */
+         parse_expression (operands[i].buf + 1, &operands[i].exp);
+       }
       else if (operands[i].buf[0] == '@')
-        {
-          /* direct notation */
-          parse_expression (operands[i].buf + 1, &operands[i].exp);
-        }
+       {
+         /* Direct notation.  */
+         parse_expression (operands[i].buf + 1, &operands[i].exp);
+       }
       else if (operands[i].buf[0] == '*')
-        {
-          /* indirect */
-          char *paren = strchr (operands[i].buf, '(');
-          /* Allow immediate syntax in the inner expression.  */
-          if (paren && paren[1] == '#')
-              *++paren = '(';
-
-          /* Pull out the lk expression or SP offset, if present.  */
-          if (paren != NULL)
-            {
-              int len = strlen (paren);
-              char *end = paren + len;
-              int c;
-              while (end[-1] != ')')
-                if (--end <= paren)
-                  {
-                    as_bad (_("Badly formed address expression"));
-                    return -1;
-                  }
-              c = *end;
-              *end = '\0';
-              parse_expression (paren, &operands[i].exp);
-              *end = c;
-            }
-          else
-            operands[i].exp.X_op = O_absent;
-        }
+       {
+         /* Indirect.  */
+         char *paren = strchr (operands[i].buf, '(');
+
+         /* Allow immediate syntax in the inner expression.  */
+         if (paren && paren[1] == '#')
+           *++paren = '(';
+
+         /* Pull out the lk expression or SP offset, if present.  */
+         if (paren != NULL)
+           {
+             int len = strlen (paren);
+             char *end = paren + len;
+             int c;
+
+             while (end[-1] != ')')
+               if (--end <= paren)
+                 {
+                   as_bad (_("Badly formed address expression"));
+                   return -1;
+                 }
+             c = *end;
+             *end = '\0';
+             parse_expression (paren, &operands[i].exp);
+             *end = c;
+           }
+         else
+           operands[i].exp.X_op = O_absent;
+       }
       else
-        {
-          parse_expression (operands[i].buf, &operands[i].exp);
-        }
+       parse_expression (operands[i].buf, &operands[i].exp);
     }
 
   return numexp;
 }
 
 /* Predicates for different operand types.  */
+
 static int
-is_immediate (operand)
-     struct opstruct *operand;
+is_immediate (struct opstruct *operand)
 {
-  return  *operand->buf == '#';
+  return *operand->buf == '#';
 }
 
 /* This is distinguished from immediate because some numbers must be constants
    and must *not* have the '#' prefix.  */
+
 static int
-is_absolute (operand)
-     struct opstruct *operand;
+is_absolute (struct opstruct *operand)
 {
   return operand->exp.X_op == O_constant && !is_immediate (operand);
 }
 
 /* Is this an indirect operand?  */
+
 static int
-is_indirect (operand)
-     struct opstruct *operand;
+is_indirect (struct opstruct *operand)
 {
   return operand->buf[0] == '*';
 }
 
 /* Is this a valid dual-memory operand?  */
+
 static int
-is_dual (operand)
-     struct opstruct *operand;
+is_dual (struct opstruct *operand)
 {
   if (is_indirect (operand) && strncasecmp (operand->buf, "*ar", 3) == 0)
     {
       char *tmp = operand->buf + 3;
       int arf;
       int valid_mod;
-      
+
       arf = *tmp++ - '0';
       /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%.  */
       valid_mod = *tmp == '\0' ||
-        strcasecmp (tmp, "-") == 0 ||
-        strcasecmp (tmp, "+") == 0 || 
-        strcasecmp (tmp, "+0%") == 0;
+       strcasecmp (tmp, "-") == 0 ||
+       strcasecmp (tmp, "+") == 0 ||
+       strcasecmp (tmp, "+0%") == 0;
       return arf >= 2 && arf <= 5 && valid_mod;
     }
   return 0;
 }
 
 static int
-is_mmreg (operand)
-     struct opstruct *operand;
+is_mmreg (struct opstruct *operand)
 {
-  return is_absolute (operand) || is_immediate (operand)
-    || hash_find (mmreg_hash, operand->buf) != 0;
+  return (is_absolute (operand)
+         || is_immediate (operand)
+         || hash_find (mmreg_hash, operand->buf) != 0);
 }
 
 static int
-is_type (operand, type)
-  struct opstruct *operand;
-  enum optype type;
+is_type (struct opstruct *operand, enum optype type)
 {
   switch (type)
     {
@@ -3416,12 +3294,12 @@ is_type (operand, type)
     case OP_DST:
       return is_accumulator (operand);
     case OP_B:
-      return is_accumulator (operand) && toupper (operand->buf[0]) == 'B';
+      return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'B';
     case OP_A:
-      return is_accumulator (operand) && toupper (operand->buf[0]) == 'A';
+      return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'A';
     case OP_ARX:
-      return strncasecmp ("ar", operand->buf, 2) == 0 
-        && isdigit (operand->buf[2]);
+      return strncasecmp ("ar", operand->buf, 2) == 0
+       && ISDIGIT (operand->buf[2]);
     case OP_SBIT:
       return hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand);
     case OP_CC:
@@ -3429,39 +3307,39 @@ is_type (operand, type)
     case OP_CC2:
       return hash_find (cc2_hash, operand->buf) != 0;
     case OP_CC3:
-      return hash_find (cc3_hash, operand->buf) != 0 
-        || is_immediate (operand) || is_absolute (operand);
+      return hash_find (cc3_hash, operand->buf) != 0
+       || is_immediate (operand) || is_absolute (operand);
     case OP_16:
       return (is_immediate (operand) || is_absolute (operand))
-        && operand->exp.X_add_number == 16;
+       && operand->exp.X_add_number == 16;
     case OP_N:
       /* Allow st0 or st1 instead of a numeric.  */
       return is_absolute (operand) || is_immediate (operand) ||
-        strcasecmp ("st0", operand->buf) == 0 ||
-        strcasecmp ("st1", operand->buf) == 0;
+       strcasecmp ("st0", operand->buf) == 0 ||
+       strcasecmp ("st1", operand->buf) == 0;
     case OP_12:
     case OP_123:
       return is_absolute (operand) || is_immediate (operand);
     case OP_SHFT:
       return (is_immediate (operand) || is_absolute (operand))
-        && operand->exp.X_add_number >= 0 && operand->exp.X_add_number < 16;
+       && operand->exp.X_add_number >= 0 && operand->exp.X_add_number < 16;
     case OP_SHIFT:
       /* Let this one catch out-of-range values.  */
       return (is_immediate (operand) || is_absolute (operand))
-        && operand->exp.X_add_number != 16;
+       && operand->exp.X_add_number != 16;
     case OP_BITC:
     case OP_031:
     case OP_k8:
       return is_absolute (operand) || is_immediate (operand);
     case OP_k8u:
-      return is_immediate (operand) 
-        && operand->exp.X_op == O_constant 
-        && operand->exp.X_add_number >= 0
-        && operand->exp.X_add_number < 256;
+      return is_immediate (operand)
+       && operand->exp.X_op == O_constant
+       && operand->exp.X_add_number >= 0
+       && operand->exp.X_add_number < 256;
     case OP_lk:
     case OP_lku:
-      /* Allow anything; assumes opcodes are ordered with Smem operands 
-         versions first.  */
+      /* Allow anything; assumes opcodes are ordered with Smem operands
+        versions first.  */
       return 1;
     case OP_k5:
     case OP_k3:
@@ -3469,8 +3347,8 @@ is_type (operand, type)
       /* Just make sure it's an integer; check range later.  */
       return is_immediate (operand);
     case OP_T:
-      return strcasecmp ("t", operand->buf) == 0 || 
-        strcasecmp ("treg", operand->buf) == 0;
+      return strcasecmp ("t", operand->buf) == 0 ||
+       strcasecmp ("treg", operand->buf) == 0;
     case OP_TS:
       return strcasecmp ("ts", operand->buf) == 0;
     case OP_ASM:
@@ -3487,36 +3365,34 @@ is_type (operand, type)
 }
 
 static int
-operands_match (insn, operands, opcount, refoptype, minops, maxops)
-  tic54x_insn *insn;
-  struct opstruct *operands;
-  int opcount;
-  const enum optype *refoptype;
-  int minops, maxops;
+operands_match (tic54x_insn *insn,
+               struct opstruct *operands,
+               int opcount,
+               const enum optype *refoptype,
+               int minops,
+               int maxops)
 {
   int op = 0, refop = 0;
 
   if (opcount == 0 && minops == 0)
-    {
-      return 1;
-    }
+    return 1;
 
   while (op <= maxops && refop <= maxops)
     {
       while (!is_type (&operands[op], OPTYPE (refoptype[refop])))
-        {
-          /* Skip an optional template operand if it doesn't agree
-             with the current operand.  */
-          if (refoptype[refop] & OPT)
-            {
-              ++refop;
-              --maxops;
-              if (refop > maxops)
-                return 0;
-            }
-          else
-            return 0;
-        }
+       {
+         /* Skip an optional template operand if it doesn't agree
+            with the current operand.  */
+         if (refoptype[refop] & OPT)
+           {
+             ++refop;
+             --maxops;
+             if (refop > maxops)
+               return 0;
+           }
+         else
+           return 0;
+       }
 
       /* Save the actual operand type for later use.  */
       operands[op].type = OPTYPE (refoptype[refop]);
@@ -3524,47 +3400,45 @@ operands_match (insn, operands, opcount, refoptype, minops, maxops)
       ++op;
       /* Have we matched them all yet?  */
       if (op == opcount)
-        {
-          while (op < maxops)
-            {
-              /* If a later operand is *not* optional, no match.  */
-              if ((refoptype[refop] & OPT) == 0)
-                return 0;
-              /* Flag any implicit default OP_DST operands so we know to add
-                 them explicitly when encoding the operand later.  */
-              if (OPTYPE (refoptype[refop]) == OP_DST)
-                insn->using_default_dst = 1;
-              ++refop;
-              ++op;
-            }
-
-          return 1;
-        }
+       {
+         while (op < maxops)
+           {
+             /* If a later operand is *not* optional, no match.  */
+             if ((refoptype[refop] & OPT) == 0)
+               return 0;
+             /* Flag any implicit default OP_DST operands so we know to add
+                them explicitly when encoding the operand later.  */
+             if (OPTYPE (refoptype[refop]) == OP_DST)
+               insn->using_default_dst = 1;
+             ++refop;
+             ++op;
+           }
+
+         return 1;
+       }
     }
 
   return 0;
 }
 
-/* 16-bit direct memory address 
+/* 16-bit direct memory address
    Explicit dmad operands are always in last word of insn (usually second
    word, but bumped to third if lk addressing is used)
 
    We allow *(dmad) notation because the TI assembler allows it.
 
-   XPC_CODE: 
+   XPC_CODE:
    0 for 16-bit addresses
    1 for full 23-bit addresses
    2 for the upper 7 bits of a 23-bit address (LDX).  */
+
 static int
-encode_dmad (insn, operand, xpc_code)
-  tic54x_insn *insn;
-  struct opstruct *operand;
-  int xpc_code;
+encode_dmad (tic54x_insn *insn, struct opstruct *operand, int xpc_code)
 {
   int op = 1 + insn->is_lkaddr;
 
   /* Only allow *(dmad) expressions; all others are invalid.  */
-  if (is_indirect (operand) && operand->buf[strlen (operand->buf)-1] != ')')
+  if (is_indirect (operand) && operand->buf[strlen (operand->buf) - 1] != ')')
     {
       as_bad (_("Invalid dmad syntax '%s'"), operand->buf);
       return 0;
@@ -3575,16 +3449,17 @@ encode_dmad (insn, operand, xpc_code)
   if (insn->opcode[op].addr_expr.X_op == O_constant)
     {
       valueT value = insn->opcode[op].addr_expr.X_add_number;
+
       if (xpc_code == 1)
-        {
-          insn->opcode[0].word &= 0xFF80;
-          insn->opcode[0].word |= (value >> 16) & 0x7F;
-          insn->opcode[1].word = value & 0xFFFF;
-        }
+       {
+         insn->opcode[0].word &= 0xFF80;
+         insn->opcode[0].word |= (value >> 16) & 0x7F;
+         insn->opcode[1].word = value & 0xFFFF;
+       }
       else if (xpc_code == 2)
-        insn->opcode[op].word = (value >> 16) & 0xFFFF;
+       insn->opcode[op].word = (value >> 16) & 0xFFFF;
       else
-        insn->opcode[op].word = value;
+       insn->opcode[op].word = value;
     }
   else
     {
@@ -3593,22 +3468,22 @@ encode_dmad (insn, operand, xpc_code)
       insn->opcode[op].r_nchars = 2;
 
       if (amode == c_mode)
-        insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
+       insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
       else if (xpc_code == 1)
-        {
-          /* This relocation spans two words, so adjust accordingly.  */
-          insn->opcode[0].addr_expr = operand->exp;
-          insn->opcode[0].r_type = BFD_RELOC_TIC54X_23;
-          insn->opcode[0].r_nchars = 4;
-          insn->opcode[0].unresolved = 1;
-          /* It's really 2 words, but we want to stop encoding after the
-             first, since we must encode both words at once.  */
-          insn->words = 1;
-        }
+       {
+         /* This relocation spans two words, so adjust accordingly.  */
+         insn->opcode[0].addr_expr = operand->exp;
+         insn->opcode[0].r_type = BFD_RELOC_TIC54X_23;
+         insn->opcode[0].r_nchars = 4;
+         insn->opcode[0].unresolved = 1;
+         /* It's really 2 words, but we want to stop encoding after the
+            first, since we must encode both words at once.  */
+         insn->words = 1;
+       }
       else if (xpc_code == 2)
-        insn->opcode[op].r_type = BFD_RELOC_TIC54X_MS7_OF_23;
+       insn->opcode[op].r_type = BFD_RELOC_TIC54X_MS7_OF_23;
       else
-        insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
+       insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
 
       insn->opcode[op].unresolved = 1;
     }
@@ -3616,12 +3491,10 @@ encode_dmad (insn, operand, xpc_code)
   return 1;
 }
 
-
 /* 7-bit direct address encoding.  */
+
 static int
-encode_address (insn, operand)
-  tic54x_insn *insn;
-  struct opstruct *operand;
+encode_address (tic54x_insn *insn, struct opstruct *operand)
 {
   /* Assumes that dma addresses are *always* in word 0 of the opcode.  */
   insn->opcode[0].addr_expr = operand->exp;
@@ -3630,6 +3503,8 @@ encode_address (insn, operand)
     insn->opcode[0].word |= (operand->exp.X_add_number & 0x7F);
   else
     {
+      if (operand->exp.X_op == O_register)
+        as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand->buf);
       /* Do the fixup later; just store the expression.  */
       insn->opcode[0].r_nchars = 1;
       insn->opcode[0].r_type = BFD_RELOC_TIC54X_PARTLS7;
@@ -3640,9 +3515,7 @@ encode_address (insn, operand)
 }
 
 static int
-encode_indirect (insn, operand)
-  tic54x_insn *insn;
-  struct opstruct *operand;
+encode_indirect (tic54x_insn *insn, struct opstruct *operand)
 {
   int arf;
   int mod;
@@ -3650,23 +3523,23 @@ encode_indirect (insn, operand)
   if (insn->is_lkaddr)
     {
       /* lk addresses always go in the second insn word.  */
-      mod = ((toupper (operand->buf[1]) == 'A') ? 12 :
-             (operand->buf[1] == '(') ? 15 :
-             (strchr (operand->buf, '%') != NULL) ? 14 : 13);
+      mod = ((TOUPPER (operand->buf[1]) == 'A') ? 12 :
+            (operand->buf[1] == '(') ? 15 :
+            (strchr (operand->buf, '%') != NULL) ? 14 : 13);
       arf = ((mod == 12) ? operand->buf[3] - '0' :
-             (mod == 15) ? 0 : operand->buf[4] - '0');
-      
+            (mod == 15) ? 0 : operand->buf[4] - '0');
+
       insn->opcode[1].addr_expr = operand->exp;
 
       if (operand->exp.X_op == O_constant)
-        insn->opcode[1].word = operand->exp.X_add_number;
+       insn->opcode[1].word = operand->exp.X_add_number;
       else
-        {
-          insn->opcode[1].word = 0;
-          insn->opcode[1].r_nchars = 2;
-          insn->opcode[1].r_type = BFD_RELOC_TIC54X_16_OF_23;
-          insn->opcode[1].unresolved = 1;
-        }
+       {
+         insn->opcode[1].word = 0;
+         insn->opcode[1].r_nchars = 2;
+         insn->opcode[1].r_type = BFD_RELOC_TIC54X_16_OF_23;
+         insn->opcode[1].unresolved = 1;
+       }
     }
   else if (strncasecmp (operand->buf, "*sp (", 4) == 0)
     {
@@ -3675,50 +3548,51 @@ encode_indirect (insn, operand)
     }
   else
     {
-      arf = (toupper (operand->buf[1]) == 'A' ? 
-             operand->buf[3] : operand->buf[4]) - '0';
-      
-      if (operand->buf[1] == '+') 
-        {
-          mod = 3;                    /* *+ARx */
-          if (insn->tm->flags & FL_SMR)
-            as_warn (_("Address mode *+ARx is write-only. "
-                       "Results of reading are undefined."));
-        }
-      else if (operand->buf[4] == '\0') 
-        mod = 0;                    /* *ARx */
+      arf = (TOUPPER (operand->buf[1]) == 'A' ?
+            operand->buf[3] : operand->buf[4]) - '0';
+
+      if (operand->buf[1] == '+')
+       {
+         mod = 3;                  /* *+ARx  */
+         if (insn->tm->flags & FL_SMR)
+           as_warn (_("Address mode *+ARx is write-only. "
+                      "Results of reading are undefined."));
+       }
+      else if (operand->buf[4] == '\0')
+       mod = 0;                    /* *ARx  */
       else if (operand->buf[5] == '\0')
-        mod = (operand->buf[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
+       mod = (operand->buf[4] == '-' ? 1 : 2); /* *ARx+ / *ARx-  */
       else if (operand->buf[6] == '\0')
-        {
-          if (operand->buf[5] == '0')
-            mod = (operand->buf[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
-          else
-            mod = (operand->buf[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
-        }
-      else if (toupper (operand->buf[6]) == 'B')
-        mod = (operand->buf[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
-      else if (toupper (operand->buf[6]) == '%')
-        mod = (operand->buf[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
+       {
+         if (operand->buf[5] == '0')
+           mod = (operand->buf[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0  */
+         else
+           mod = (operand->buf[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-%  */
+       }
+      else if (TOUPPER (operand->buf[6]) == 'B')
+       mod = (operand->buf[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B  */
+      else if (TOUPPER (operand->buf[6]) == '%')
+       mod = (operand->buf[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0%  */
       else
-        {
-          as_bad (_("Unrecognized indirect address format \"%s\""), 
-                  operand->buf);
-          return 0;
-        }
-    }      
+       {
+         as_bad (_("Unrecognized indirect address format \"%s\""),
+                 operand->buf);
+         return 0;
+       }
+    }
 
-  insn->opcode[0].word |= 0x80 | (mod<<3) | arf;
+  insn->opcode[0].word |= 0x80 | (mod << 3) | arf;
 
   return 1;
 }
 
 static int
-encode_integer (insn, operand, which, min, max, mask)
-  tic54x_insn *insn;
-  struct opstruct *operand;
-  int which, min, max;
-  unsigned short mask;
+encode_integer (tic54x_insn *insn,
+               struct opstruct *operand,
+               int which,
+               int min,
+               int max,
+               unsigned short mask)
 {
   long parse, integer;
 
@@ -3728,43 +3602,43 @@ encode_integer (insn, operand, which, min, max, mask)
     {
       parse = operand->exp.X_add_number;
       /* Hack -- fixup for 16-bit hex quantities that get converted positive
-         instead of negative.  */
+        instead of negative.  */
       if ((parse & 0x8000) && min == -32768 && max == 32767)
-        integer = (short)parse;
+       integer = (short) parse;
       else
-        integer = parse;
+       integer = parse;
 
       if (integer >= min && integer <= max)
-        {
-          insn->opcode[which].word |= (integer & mask);
-          return 1;
-        }
-      as_bad (_("Operand '%s' out of range (%d <= x <= %d)"), 
-              operand->buf, min, max);
+       {
+         insn->opcode[which].word |= (integer & mask);
+         return 1;
+       }
+      as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
+             operand->buf, min, max);
     }
   else
     {
       if (insn->opcode[which].addr_expr.X_op == O_constant)
-        {
-          insn->opcode[which].word |= 
-            insn->opcode[which].addr_expr.X_add_number & mask;
-        }
+       {
+         insn->opcode[which].word |=
+           insn->opcode[which].addr_expr.X_add_number & mask;
+       }
       else
-        {
-          /* Do the fixup later; just store the expression.  */
-          bfd_reloc_code_real_type rtype = 
-            (mask == 0x1FF ? BFD_RELOC_TIC54X_PARTMS9 : 
-             mask == 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23 :
-             mask == 0x7F ? BFD_RELOC_TIC54X_PARTLS7 : BFD_RELOC_8);
-          int size = (mask == 0x1FF || mask == 0xFFFF) ? 2 : 1;
-
-          if (rtype == BFD_RELOC_8)
-            as_bad (_("Error in relocation handling"));
-
-          insn->opcode[which].r_nchars = size;
-          insn->opcode[which].r_type = rtype;
-          insn->opcode[which].unresolved = 1;
-        }
+       {
+         /* Do the fixup later; just store the expression.  */
+         bfd_reloc_code_real_type rtype =
+           (mask == 0x1FF ? BFD_RELOC_TIC54X_PARTMS9 :
+            mask == 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23 :
+            mask == 0x7F ? BFD_RELOC_TIC54X_PARTLS7 : BFD_RELOC_8);
+         int size = (mask == 0x1FF || mask == 0xFFFF) ? 2 : 1;
+
+         if (rtype == BFD_RELOC_8)
+           as_bad (_("Error in relocation handling"));
+
+         insn->opcode[which].r_nchars = size;
+         insn->opcode[which].r_type = rtype;
+         insn->opcode[which].unresolved = 1;
+       }
 
       return 1;
     }
@@ -3773,11 +3647,9 @@ encode_integer (insn, operand, which, min, max, mask)
 }
 
 static int
-encode_condition (insn, operand)
-  tic54x_insn *insn;
-  struct opstruct *operand;
+encode_condition (tic54x_insn *insn, struct opstruct *operand)
 {
-  symbol *cc = (symbol *)hash_find (cc_hash, operand->buf);
+  tic54x_symbol *cc = (tic54x_symbol *) hash_find (cc_hash, operand->buf);
   if (!cc)
     {
       as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
@@ -3796,38 +3668,38 @@ encode_condition (insn, operand)
   if (((insn->opcode[0].word & 0xFF) != 0))
     {
       if ((insn->opcode[0].word & CC_GROUP) != (cc->value & CC_GROUP))
-        {
-          as_bad (_("Condition \"%s\" does not match preceding group"), 
-                  operand->buf);
-          return 0;
-        }
+       {
+         as_bad (_("Condition \"%s\" does not match preceding group"),
+                 operand->buf);
+         return 0;
+       }
       if (insn->opcode[0].word & CC_GROUP)
-        {
-          if ((insn->opcode[0].word & CC_ACC) != (cc->value & CC_ACC))
-            {
-              as_bad (_("Condition \"%s\" uses a different accumulator from "
-                        "a preceding condition"), 
-                      operand->buf);
-              return 0;
-            }
-          if ((insn->opcode[0].word & CATG_A1) && (cc->value & CATG_A1))
-            {
-              as_bad (_("Only one comparison conditional allowed"));
-              return 0;
-            }
-          if ((insn->opcode[0].word & CATG_B1) && (cc->value & CATG_B1))
-            {
-              as_bad (_("Only one overflow conditional allowed"));
-              return 0;
-            }
-        }
-      else if (((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2)) ||
-               ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2)) ||
-               ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
-        {
-          as_bad (_("Duplicate %s conditional"), operand->buf);
-          return 0;
-        }
+       {
+         if ((insn->opcode[0].word & CC_ACC) != (cc->value & CC_ACC))
+           {
+             as_bad (_("Condition \"%s\" uses a different accumulator from "
+                       "a preceding condition"),
+                     operand->buf);
+             return 0;
+           }
+         if ((insn->opcode[0].word & CATG_A1) && (cc->value & CATG_A1))
+           {
+             as_bad (_("Only one comparison conditional allowed"));
+             return 0;
+           }
+         if ((insn->opcode[0].word & CATG_B1) && (cc->value & CATG_B1))
+           {
+             as_bad (_("Only one overflow conditional allowed"));
+             return 0;
+           }
+       }
+      else if (   ((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2))
+              || ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2))
+              || ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
+       {
+         as_bad (_("Duplicate %s conditional"), operand->buf);
+         return 0;
+       }
     }
 
   insn->opcode[0].word |= cc->value;
@@ -3835,11 +3707,9 @@ encode_condition (insn, operand)
 }
 
 static int
-encode_cc3 (insn, operand)
-  tic54x_insn *insn;
-  struct opstruct *operand;
+encode_cc3 (tic54x_insn *insn, struct opstruct *operand)
 {
-  symbol *cc3 = (symbol *)hash_find (cc3_hash, operand->buf);
+  tic54x_symbol *cc3 = (tic54x_symbol *) hash_find (cc3_hash, operand->buf);
   int value = cc3 ? cc3->value : operand->exp.X_add_number << 8;
 
   if ((value & 0x0300) != value)
@@ -3852,11 +3722,10 @@ encode_cc3 (insn, operand)
 }
 
 static int
-encode_arx (insn, operand)
-  tic54x_insn *insn;
-  struct opstruct *operand;
+encode_arx (tic54x_insn *insn, struct opstruct *operand)
 {
   int arf = strlen (operand->buf) >= 3 ? operand->buf[2] - '0' : -1;
+
   if (strncasecmp ("ar", operand->buf, 2) || arf < 0 || arf > 7)
     {
       as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
@@ -3867,11 +3736,10 @@ encode_arx (insn, operand)
 }
 
 static int
-encode_cc2 (insn, operand)
-  tic54x_insn *insn;
-  struct opstruct *operand;
+encode_cc2 (tic54x_insn *insn, struct opstruct *operand)
 {
-  symbol *cc2 = (symbol *)hash_find (cc2_hash, operand->buf);
+  tic54x_symbol *cc2 = (tic54x_symbol *) hash_find (cc2_hash, operand->buf);
+
   if (!cc2)
     {
       as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
@@ -3882,30 +3750,27 @@ encode_cc2 (insn, operand)
 }
 
 static int
-encode_operand (insn, type, operand)
-  tic54x_insn *insn;
-  enum optype type;
-  struct opstruct *operand;
+encode_operand (tic54x_insn *insn, enum optype type, struct opstruct *operand)
 {
-  int ext = insn->tm && ((insn->tm->flags & FL_EXT) != 0);
+  int ext = (insn->tm->flags & FL_EXT) != 0;
 
   if (type == OP_MMR && operand->exp.X_op != O_constant)
     {
       /* Disallow long-constant addressing for memory-mapped addressing.  */
       if (insn->is_lkaddr)
-        {
-          as_bad (_("lk addressing modes are invalid for memory-mapped "
-                    "register addressing"));
-          return 0;
-        }
+       {
+         as_bad (_("lk addressing modes are invalid for memory-mapped "
+                   "register addressing"));
+         return 0;
+       }
       type = OP_Smem;
       /* Warn about *+ARx when used with MMR operands.  */
       if (strncasecmp (operand->buf, "*+ar", 4) == 0)
-        {
-          as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
-                     "register addressing.  Resulting behavior is "
-                     "undefined."));
-        }
+       {
+         as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
+                    "register addressing.  Resulting behavior is "
+                    "undefined."));
+       }
     }
 
   switch (type)
@@ -3916,44 +3781,44 @@ encode_operand (insn, type, operand)
       /* 16-bit immediate value.  */
       return encode_dmad (insn, operand, 0);
     case OP_SRC:
-      if (toupper (*operand->buf) == 'B')
-        {
-          insn->opcode[ext ?  (1 + insn->is_lkaddr) : 0].word |= (1<<9);
-          if (insn->using_default_dst)
-            insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1<<8);
-        }
+      if (TOUPPER (*operand->buf) == 'B')
+       {
+         insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 9);
+         if (insn->using_default_dst)
+           insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
+       }
       return 1;
     case OP_RND:
-      /* Make sure this agrees with with the OP_DST operand.  */
-      if (!((toupper (operand->buf[0]) == 'B') ^
-            ((insn->opcode[0].word & (1<<8)) != 0)))
-        {
-          as_bad (_("Destination accumulator for each part of this parallel "
-                    "instruction must be different"));
-          return 0;
-        }
+      /* Make sure this agrees with the OP_DST operand.  */
+      if (!((TOUPPER (operand->buf[0]) == 'B') ^
+           ((insn->opcode[0].word & (1 << 8)) != 0)))
+       {
+         as_bad (_("Destination accumulator for each part of this parallel "
+                   "instruction must be different"));
+         return 0;
+       }
       return 1;
     case OP_SRC1:
     case OP_DST:
-      if (toupper (operand->buf[0]) == 'B')
-        insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1<<8);
+      if (TOUPPER (operand->buf[0]) == 'B')
+       insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
       return 1;
     case OP_Xmem:
     case OP_Ymem:
-    {
-      int mod = (operand->buf[4] == '\0' ? 0 : /* *arx */
-                 operand->buf[4] == '-' ? 1 : /* *arx- */
-                 operand->buf[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
-      int arf = operand->buf[3] - '0' - 2;
-      int code = (mod << 2)|arf;
-      insn->opcode[0].word |= (code << (type == OP_Xmem ? 4 : 0));
-      return 1;
-    }
+      {
+       int mod = (operand->buf[4] == '\0' ? 0 : /* *arx  */
+                  operand->buf[4] == '-' ? 1 : /* *arx-  */
+                  operand->buf[5] == '\0' ? 2 : 3); /* *arx+, *arx+0%  */
+       int arf = operand->buf[3] - '0' - 2;
+       int code = (mod << 2) | arf;
+       insn->opcode[0].word |= (code << (type == OP_Xmem ? 4 : 0));
+       return 1;
+      }
     case OP_Lmem:
     case OP_Smem:
       if (!is_indirect (operand))
-        return encode_address (insn, operand);
-      /* fall through */
+       return encode_address (insn, operand);
+      /* Fall through.  */
     case OP_Sind:
       return encode_indirect (insn, operand);
     case OP_xpmad_ms7:
@@ -3968,36 +3833,38 @@ encode_operand (insn, type, operand)
     case OP_MMRX:
     case OP_MMRY:
     case OP_MMR:
-    {
-      int value = operand->exp.X_add_number;
-      if (type == OP_MMR)
-        insn->opcode[0].word |= value;
-      else {
-        if (value < 16 || value > 24)
-          {
-            as_bad (_("Memory mapped register \"%s\" out of range"), 
-                    operand->buf);
-            return 0;
-          }
-        if (type == OP_MMRX)
-          insn->opcode[0].word |= (value - 16) << 4;
-        else
-          insn->opcode[0].word |= (value - 16);
+      {
+       int value = operand->exp.X_add_number;
+
+       if (type == OP_MMR)
+         insn->opcode[0].word |= value;
+       else
+         {
+           if (value < 16 || value > 24)
+             {
+               as_bad (_("Memory mapped register \"%s\" out of range"),
+                       operand->buf);
+               return 0;
+             }
+           if (type == OP_MMRX)
+             insn->opcode[0].word |= (value - 16) << 4;
+           else
+             insn->opcode[0].word |= (value - 16);
+         }
+       return 1;
       }
-      return 1;
-    }
     case OP_B:
     case OP_A:
       return 1;
     case OP_SHFT:
-      return encode_integer (insn, operand, ext + insn->is_lkaddr, 
-                             0, 15, 0xF);
+      return encode_integer (insn, operand, ext + insn->is_lkaddr,
+                            0, 15, 0xF);
     case OP_SHIFT:
-      return encode_integer (insn, operand, ext + insn->is_lkaddr, 
-                             -16, 15, 0x1F);
+      return encode_integer (insn, operand, ext + insn->is_lkaddr,
+                            -16, 15, 0x1F);
     case OP_lk:
       return encode_integer (insn, operand, 1 + insn->is_lkaddr,
-                             -32768, 32767, 0xFFFF);
+                            -32768, 32767, 0xFFFF);
     case OP_CC:
       return encode_condition (insn, operand);
     case OP_CC2:
@@ -4009,68 +3876,70 @@ encode_operand (insn, type, operand)
     case OP_k8:
       return encode_integer (insn, operand, 0, -128, 127, 0xFF);
     case OP_123:
-    {
-      int value = operand->exp.X_add_number;
-      int code;
-      if (value < 1 || value > 3)
-        {
-          as_bad (_("Invalid operand (use 1, 2, or 3)"));
-          return 0;
-        }
-      code = value == 1 ? 0 : value == 2 ? 0x2 : 0x1;
-      insn->opcode[0].word |= (code << 8);
-      return 1;
-    }
+      {
+       int value = operand->exp.X_add_number;
+       int code;
+       if (value < 1 || value > 3)
+         {
+           as_bad (_("Invalid operand (use 1, 2, or 3)"));
+           return 0;
+         }
+       code = value == 1 ? 0 : value == 2 ? 0x2 : 0x1;
+       insn->opcode[0].word |= (code << 8);
+       return 1;
+      }
     case OP_031:
       return encode_integer (insn, operand, 0, 0, 31, 0x1F);
     case OP_k8u:
       return encode_integer (insn, operand, 0, 0, 255, 0xFF);
     case OP_lku:
-      return encode_integer (insn, operand, 1 + insn->is_lkaddr, 
-                             0, 65535, 0xFFFF);
+      return encode_integer (insn, operand, 1 + insn->is_lkaddr,
+                            0, 65535, 0xFFFF);
     case OP_SBIT:
-    {
-      symbol *sbit = (symbol *)hash_find (sbit_hash, operand->buf);
-      int value = is_absolute (operand) ? 
-        operand->exp.X_add_number : (sbit ? sbit->value : -1);
-      int reg = 0;
-      
-      if (insn->opcount == 1)
-        {
-          if (!sbit)
-            {
-              as_bad (_("A status register or status bit name is required"));
-              return 0;
-            }
-          /* Guess the register based on the status bit; "ovb" is the last
-             status bit defined for st0.  */
-          if (sbit > (symbol *)hash_find (sbit_hash, "ovb"))
-            reg = 1;
-        }
-      if (value == -1)
-        {
-          as_bad (_("Unrecognized status bit \"%s\""), operand->buf);
-          return 0;
-        }
-      insn->opcode[0].word |= value;
-      insn->opcode[0].word |= (reg << 9);
-      return 1;
-    }
+      {
+       tic54x_symbol *sbit = (tic54x_symbol *)
+         hash_find (sbit_hash, operand->buf);
+       int value = is_absolute (operand) ?
+         operand->exp.X_add_number : (sbit ? sbit->value : -1);
+       int reg = 0;
+
+       if (insn->opcount == 1)
+         {
+           if (!sbit)
+             {
+               as_bad (_("A status register or status bit name is required"));
+               return 0;
+             }
+           /* Guess the register based on the status bit; "ovb" is the last
+              status bit defined for st0.  */
+           if (sbit > (tic54x_symbol *) hash_find (sbit_hash, "ovb"))
+             reg = 1;
+         }
+       if (value == -1)
+         {
+           as_bad (_("Unrecognized status bit \"%s\""), operand->buf);
+           return 0;
+         }
+       insn->opcode[0].word |= value;
+       insn->opcode[0].word |= (reg << 9);
+       return 1;
+      }
     case OP_N:
       if (strcasecmp (operand->buf, "st0") == 0
-          || strcasecmp (operand->buf, "st1") == 0)
-        {
-          insn->opcode[0].word |= ((unsigned short)(operand->buf[2] - '0'))<<9;
-          return 1;
-        }
+         || strcasecmp (operand->buf, "st1") == 0)
+       {
+         insn->opcode[0].word |=
+           ((unsigned short) (operand->buf[2] - '0')) << 9;
+         return 1;
+       }
       else if (operand->exp.X_op == O_constant
-               && (operand->exp.X_add_number == 0 
-                   || operand->exp.X_add_number == 1))
-        {
-          insn->opcode[0].word |= ((unsigned short)
-                                   (operand->exp.X_add_number))<<9;
-          return 1;
-        }
+              && (operand->exp.X_add_number == 0
+                  || operand->exp.X_add_number == 1))
+       {
+         insn->opcode[0].word |=
+           ((unsigned short) (operand->exp.X_add_number)) << 9;
+         return 1;
+       }
       as_bad (_("Invalid status register \"%s\""), operand->buf);
       return 0;
     case OP_k5:
@@ -4080,12 +3949,12 @@ encode_operand (insn, type, operand)
     case OP_k9:
       return encode_integer (insn, operand, 0, 0, 0x1FF, 0x1FF);
     case OP_12:
-      if (operand->exp.X_add_number != 1 
-          && operand->exp.X_add_number != 2)
-        {
-          as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand->buf);
-          return 0;
-        }
+      if (operand->exp.X_add_number != 1
+         && operand->exp.X_add_number != 2)
+       {
+         as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand->buf);
+         return 0;
+       }
       insn->opcode[0].word |= (operand->exp.X_add_number - 1) << 9;
       return 1;
     case OP_16:
@@ -4105,73 +3974,82 @@ encode_operand (insn, type, operand)
 }
 
 static void
-emit_insn (insn)
-  tic54x_insn *insn;
+emit_insn (tic54x_insn *insn)
 {
   int i;
-  for (i=0;i < insn->words;i++)
+  flagword oldflags = bfd_section_flags (now_seg);
+  flagword flags = oldflags | SEC_CODE;
+
+  if (!bfd_set_section_flags (now_seg, flags))
+        as_warn (_("error setting flags for \"%s\": %s"),
+                 bfd_section_name (now_seg),
+                 bfd_errmsg (bfd_get_error ()));
+
+  for (i = 0; i < insn->words; i++)
     {
-      int size = (insn->opcode[i].unresolved 
-                  && insn->opcode[i].r_type == BFD_RELOC_TIC54X_23) ? 4 : 2;
+      int size = (insn->opcode[i].unresolved
+                 && insn->opcode[i].r_type == BFD_RELOC_TIC54X_23) ? 4 : 2;
       char *p = frag_more (size);
 
       if (size == 2)
-        md_number_to_chars (p, (valueT)insn->opcode[i].word, 2);
+       md_number_to_chars (p, (valueT) insn->opcode[i].word, 2);
       else
-        md_number_to_chars (p, (valueT)insn->opcode[i].word << 16, 4);
-        
+       md_number_to_chars (p, (valueT) insn->opcode[i].word << 16, 4);
+
       if (insn->opcode[i].unresolved)
-        fix_new_exp (frag_now, p - frag_now->fr_literal,
-                     insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr,
-                     false, insn->opcode[i].r_type);
+       fix_new_exp (frag_now, p - frag_now->fr_literal,
+                    insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr,
+                    FALSE, insn->opcode[i].r_type);
     }
 }
 
-/* Convert the operand strings into appropriate opcode values 
+/* Convert the operand strings into appropriate opcode values
    return the total number of words used by the instruction.  */
+
 static int
-build_insn (insn)
-  tic54x_insn *insn;
+build_insn (tic54x_insn *insn)
 {
   int i;
 
   /* Only non-parallel instructions support lk addressing.  */
-  if (insn->tm)
-    {
-      for (i=0; i < insn->opcount; i++)
-        {
-          if ((OPTYPE (insn->operands[i].type) == OP_Smem ||
-               OPTYPE (insn->operands[i].type) == OP_Lmem ||
-               OPTYPE (insn->operands[i].type) == OP_Sind) &&
-              strchr (insn->operands[i].buf, '(') &&
-              /* Don't mistake stack-relative addressing for lk addressing.  */
-              strncasecmp (insn->operands[i].buf, "*sp (", 4) != 0)
-            {
-              insn->is_lkaddr = 1;
-              insn->lkoperand = i;
-              break;
-            }
-        }
-    }
-  insn->words = 
-    (insn->tm ? insn->tm->words : insn->ptm->words) + insn->is_lkaddr;
-
-  insn->opcode[0].word = insn->tm ? insn->tm->opcode : insn->ptm->opcode;
-  if (insn->tm && (insn->tm->flags & FL_EXT))
-      insn->opcode[1 + insn->is_lkaddr].word = insn->tm->opcode2;
-
-  for (i=0; i < insn->opcount; i++)
+  if (!(insn->tm->flags & FL_PAR))
     {
-      enum optype type = insn->operands[i].type;
-      if (!encode_operand (insn, type, &insn->operands[i]))
-        return 0;
+      for (i = 0; i < insn->opcount; i++)
+       {
+         if ((OPTYPE (insn->operands[i].type) == OP_Smem
+              || OPTYPE (insn->operands[i].type) == OP_Lmem
+              || OPTYPE (insn->operands[i].type) == OP_Sind)
+             && strchr (insn->operands[i].buf, '(')
+             /* Don't mistake stack-relative addressing for lk addressing.  */
+             && strncasecmp (insn->operands[i].buf, "*sp (", 4) != 0)
+           {
+             insn->is_lkaddr = 1;
+             insn->lkoperand = i;
+             break;
+           }
+       }
     }
-  if (insn->ptm) for (i=0; i < insn->paropcount; i++)
+  insn->words = insn->tm->words + insn->is_lkaddr;
+
+  insn->opcode[0].word = insn->tm->opcode;
+  if (insn->tm->flags & FL_EXT)
+    insn->opcode[1 + insn->is_lkaddr].word = insn->tm->opcode2;
+
+  for (i = 0; i < insn->opcount; i++)
     {
-      enum optype partype = insn->paroperands[i].type;
-      if (!encode_operand (insn, partype, &insn->paroperands[i]))
-        return 0;
+      enum optype type = insn->operands[i].type;
+
+      if (!encode_operand (insn, type, &insn->operands[i]))
+       return 0;
     }
+  if (insn->tm->flags & FL_PAR)
+    for (i = 0; i < insn->paropcount; i++)
+      {
+       enum optype partype = insn->paroperands[i].type;
+
+       if (!encode_operand (insn, partype, &insn->paroperands[i]))
+         return 0;
+      }
 
   emit_insn (insn);
 
@@ -4179,104 +4057,102 @@ build_insn (insn)
 }
 
 static int
-optimize_insn (insn)
-  tic54x_insn *insn;
+optimize_insn (tic54x_insn *insn)
 {
-  /* Optimize some instructions, helping out the brain-dead programmer.  */ 
+  /* Optimize some instructions, helping out the brain-dead programmer.  */
 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
   if (strcasecmp (insn->tm->name, "add") == 0)
     {
-      if (insn->opcount > 1 &&
-          is_accumulator (&insn->operands[insn->opcount-2]) &&
-          is_accumulator (&insn->operands[insn->opcount-1]) &&
-          strcasecmp (insn->operands[insn->opcount-2].buf,
-                     insn->operands[insn->opcount-1].buf) == 0)
-        {
-          --insn->opcount;
-          insn->using_default_dst = 1;
-          return 1;
-        }
-      
+      if (insn->opcount > 1
+         && is_accumulator (&insn->operands[insn->opcount - 2])
+         && is_accumulator (&insn->operands[insn->opcount - 1])
+         && strcasecmp (insn->operands[insn->opcount - 2].buf,
+                        insn->operands[insn->opcount - 1].buf) == 0)
+       {
+         --insn->opcount;
+         insn->using_default_dst = 1;
+         return 1;
+       }
+
       /* Try to collapse if Xmem and shift count is zero.  */
-      if ((OPTYPE (insn->tm->operand_types[0]) == OP_Xmem &&
-           OPTYPE (insn->tm->operand_types[1]) == OP_SHFT &&
-           is_zero (insn->operands[1])) ||
-          /* Or if Smem, shift is zero or absent, and SRC == DST.  */
-          (OPTYPE (insn->tm->operand_types[0]) == OP_Smem &&
-           OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT &&
-           is_type (&insn->operands[1], OP_SHIFT) && 
-           is_zero (insn->operands[1]) && insn->opcount == 3))
-        {
-          insn->operands[1] = insn->operands[2];
-          insn->opcount = 2;
-          return 1;
-        }
+      if ((OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
+          && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT
+          && is_zero (insn->operands[1]))
+         /* Or if Smem, shift is zero or absent, and SRC == DST.  */
+         || (OPTYPE (insn->tm->operand_types[0]) == OP_Smem
+             && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
+             && is_type (&insn->operands[1], OP_SHIFT)
+             && is_zero (insn->operands[1]) && insn->opcount == 3))
+       {
+         insn->operands[1] = insn->operands[2];
+         insn->opcount = 2;
+         return 1;
+       }
     }
   else if (strcasecmp (insn->tm->name, "ld") == 0)
     {
       if (insn->opcount == 3 && insn->operands[0].type != OP_SRC)
-        {
-          if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT ||
-               OPTYPE (insn->tm->operand_types[1]) == OP_SHFT) &&
-              is_zero (insn->operands[1]) &&
-              (OPTYPE (insn->tm->operand_types[0]) != OP_lk ||
-               (insn->operands[0].exp.X_op == O_constant &&
-                insn->operands[0].exp.X_add_number <= 255 &&
-                insn->operands[0].exp.X_add_number >= 0)))
-            {
-              insn->operands[1] = insn->operands[2];
-              insn->opcount = 2;
-              return 1;
-            }
-        }
-    }
-  else if (strcasecmp (insn->tm->name, "sth") == 0 ||
-           strcasecmp (insn->tm->name, "stl") == 0)
-    {
-      if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT ||
-           OPTYPE (insn->tm->operand_types[1]) == OP_SHFT) &&
-          is_zero (insn->operands[1]))
-        {
-          insn->operands[1] = insn->operands[2];
-          insn->opcount = 2;
-          return 1;
-        }
+       {
+         if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
+              || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
+             && is_zero (insn->operands[1])
+             && (OPTYPE (insn->tm->operand_types[0]) != OP_lk
+                 || (insn->operands[0].exp.X_op == O_constant
+                     && insn->operands[0].exp.X_add_number <= 255
+                     && insn->operands[0].exp.X_add_number >= 0)))
+           {
+             insn->operands[1] = insn->operands[2];
+             insn->opcount = 2;
+             return 1;
+           }
+       }
+    }
+  else if (strcasecmp (insn->tm->name, "sth") == 0
+          || strcasecmp (insn->tm->name, "stl") == 0)
+    {
+      if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
+          || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
+         && is_zero (insn->operands[1]))
+       {
+         insn->operands[1] = insn->operands[2];
+         insn->opcount = 2;
+         return 1;
+       }
     }
   else if (strcasecmp (insn->tm->name, "sub") == 0)
     {
-      if (insn->opcount > 1 &&
-          is_accumulator (&insn->operands[insn->opcount-2]) &&
-          is_accumulator (&insn->operands[insn->opcount-1]) &&
-          strcasecmp (insn->operands[insn->opcount-2].buf,
-                     insn->operands[insn->opcount-1].buf) == 0)
-        {
-          --insn->opcount;
-          insn->using_default_dst = 1;
-          return 1;
-        }
-      
-      if (((OPTYPE (insn->tm->operand_types[0]) == OP_Smem &&
-            OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT) ||
-           (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem &&
-            OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)) &&
-          is_zero (insn->operands[1]) &&
-          insn->opcount == 3)
-        {
-          insn->operands[1] = insn->operands[2];
-          insn->opcount = 2;
-          return 1;
-        }
+      if (insn->opcount > 1
+         && is_accumulator (&insn->operands[insn->opcount - 2])
+         && is_accumulator (&insn->operands[insn->opcount - 1])
+         && strcasecmp (insn->operands[insn->opcount - 2].buf,
+                        insn->operands[insn->opcount - 1].buf) == 0)
+       {
+         --insn->opcount;
+         insn->using_default_dst = 1;
+         return 1;
+       }
+
+      if (   ((OPTYPE (insn->tm->operand_types[0]) == OP_Smem
+           && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT)
+          || (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
+           && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT))
+         && is_zero (insn->operands[1])
+         && insn->opcount == 3)
+       {
+         insn->operands[1] = insn->operands[2];
+         insn->opcount = 2;
+         return 1;
+       }
     }
   return 0;
 }
 
 /* Find a matching template if possible, and get the operand strings.  */
+
 static int
-tic54x_parse_insn (insn, line)
-  tic54x_insn *insn;
-  char *line;
+tic54x_parse_insn (tic54x_insn *insn, char *line)
 {
-  insn->tm = (template *)hash_find (op_hash, insn->mnemonic);
+  insn->tm = (insn_template *) hash_find (op_hash, insn->mnemonic);
   if (!insn->tm)
     {
       as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic);
@@ -4285,144 +4161,141 @@ tic54x_parse_insn (insn, line)
 
   insn->opcount = get_operands (insn->operands, line);
   if (insn->opcount < 0)
-      return 0;
+    return 0;
 
   /* Check each variation of operands for this mnemonic.  */
   while (insn->tm->name && strcasecmp (insn->tm->name, insn->mnemonic) == 0)
     {
-      if (insn->opcount >= insn->tm->minops &&
-          insn->opcount <= insn->tm->maxops &&
-          operands_match (insn, &insn->operands[0], insn->opcount,
-                          insn->tm->operand_types, 
-                          insn->tm->minops, insn->tm->maxops))
-        {
-          /* SUCCESS! now try some optimizations.  */
-          if (optimize_insn (insn))
-            {
-              insn->tm = (template *)hash_find (op_hash, 
-                                                insn->mnemonic);
-              continue;
-            }
-
-          return 1;
-        }
+      if (insn->opcount >= insn->tm->minops
+         && insn->opcount <= insn->tm->maxops
+         && operands_match (insn, &insn->operands[0], insn->opcount,
+                            insn->tm->operand_types,
+                            insn->tm->minops, insn->tm->maxops))
+       {
+         /* SUCCESS! now try some optimizations.  */
+         if (optimize_insn (insn))
+           {
+             insn->tm = (insn_template *) hash_find (op_hash,
+                                                      insn->mnemonic);
+             continue;
+           }
+
+         return 1;
+       }
       ++(insn->tm);
     }
-  as_bad (_("Unrecognized operand list '%s' for instruction '%s'"), 
-            line, insn->mnemonic);
+  as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
+         line, insn->mnemonic);
   return 0;
 }
 
 /* We set this in start_line_hook, 'cause if we do a line replacement, we
    won't be able to see the next line.  */
 static int parallel_on_next_line_hint = 0;
+
 /* See if this is part of a parallel instruction
    Look for a subsequent line starting with "||".  */
+
 static int
-next_line_shows_parallel (next_line)
-  char *next_line;
+next_line_shows_parallel (char *next_line)
 {
-  /* look for the second half */
-  while (isspace (*next_line))
+  /* Look for the second half.  */
+  while (*next_line != 0 && ISSPACE (*next_line))
     ++next_line;
 
-  return (next_line[0] == PARALLEL_SEPARATOR &&
-          next_line[1] == PARALLEL_SEPARATOR);
+  return (next_line[0] == PARALLEL_SEPARATOR
+         && next_line[1] == PARALLEL_SEPARATOR);
 }
 
 static int
-tic54x_parse_parallel_insn_firstline (insn, line)
-  tic54x_insn *insn;
-  char *line;
+tic54x_parse_parallel_insn_firstline (tic54x_insn *insn, char *line)
 {
-  insn->ptm = (partemplate *)hash_find (parop_hash, insn->mnemonic);
-  if (!insn->ptm)
+  insn->tm = (insn_template *) hash_find (parop_hash, insn->mnemonic);
+  if (!insn->tm)
     {
-      as_bad (_("Unrecognized parallel instruction \"%s\""), 
-              insn->mnemonic);
+      as_bad (_("Unrecognized parallel instruction \"%s\""),
+             insn->mnemonic);
       return 0;
     }
 
-  while (insn->ptm->name && strcasecmp (insn->ptm->name,
+  while (insn->tm->name && strcasecmp (insn->tm->name,
                                        insn->mnemonic) == 0)
     {
       insn->opcount = get_operands (insn->operands, line);
       if (insn->opcount < 0)
-        return 0;
-      if (insn->opcount == 2 && 
-          operands_match (insn, &insn->operands[0], insn->opcount,
-                          insn->ptm->operand_types, 2, 2))
-        {
-          return 1;
-        }
-      ++(insn->ptm);
+       return 0;
+      if (insn->opcount == 2
+         && operands_match (insn, &insn->operands[0], insn->opcount,
+                            insn->tm->operand_types, 2, 2))
+       {
+         return 1;
+       }
+      ++(insn->tm);
     }
   /* Didn't find a matching parallel; try for a normal insn.  */
   return 0;
 }
 
 /* Parse the second line of a two-line parallel instruction.  */
+
 static int
-tic54x_parse_parallel_insn_lastline (insn, line)
-  tic54x_insn *insn;
-  char *line;
+tic54x_parse_parallel_insn_lastline (tic54x_insn *insn, char *line)
 {
   int valid_mnemonic = 0;
-  
+
   insn->paropcount = get_operands (insn->paroperands, line);
-  while (insn->ptm->name && strcasecmp (insn->ptm->name,
-                                       insn->mnemonic) == 0)
+  while (insn->tm->name && strcasecmp (insn->tm->name,
+                                      insn->mnemonic) == 0)
     {
-      if (strcasecmp (insn->ptm->parname, insn->parmnemonic) == 0)
-        {
-          valid_mnemonic = 1;
-          if (insn->paropcount >= insn->ptm->minops &&
-              insn->paropcount <= insn->ptm->maxops &&
-              operands_match (insn, insn->paroperands, 
-                              insn->paropcount,
-                              insn->ptm->paroperand_types,
-                              insn->ptm->minops, insn->ptm->maxops))
-            {
-              return 1;
-            }
-        }
-      ++(insn->ptm);
+      if (strcasecmp (insn->tm->parname, insn->parmnemonic) == 0)
+       {
+         valid_mnemonic = 1;
+
+         if (insn->paropcount >= insn->tm->minops
+             && insn->paropcount <= insn->tm->maxops
+             && operands_match (insn, insn->paroperands,
+                                insn->paropcount,
+                                insn->tm->paroperand_types,
+                                insn->tm->minops, insn->tm->maxops))
+           return 1;
+       }
+      ++(insn->tm);
     }
   if (valid_mnemonic)
     as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
-            insn->parmnemonic);
+           insn->parmnemonic);
   else
     as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
-            insn->mnemonic, insn->parmnemonic);
+           insn->mnemonic, insn->parmnemonic);
 
   return 0;
 }
 
 /* If quotes found, return copy of line up to closing quote;
-   otherwise up until terminator 
-   if it's a string, pass as-is; otherwise attempt substitution symbol
+   otherwise up until terminator.
+   If it's a string, pass as-is; otherwise attempt substitution symbol
    replacement on the value.  */
+
 static char *
-subsym_get_arg (char *line, char *terminators, char **str, int nosub)
+subsym_get_arg (char *line, const char *terminators, char **str, int nosub)
 {
   char *ptr = line;
   char *endp;
   int is_string = *line == '"';
-  int is_char = isdigit (*line);
+  int is_char = ISDIGIT (*line);
 
   if (is_char)
     {
-      while (isdigit (*ptr))
-        ++ptr;
+      while (ISDIGIT (*ptr))
+       ++ptr;
       endp = ptr;
-      *str = xmalloc (ptr - line + 1);
-      strncpy (*str, line, ptr - line);
-      (*str)[ptr - line] = 0;
+      *str = xmemdup0 (line, ptr - line);
     }
   else if (is_string)
     {
       char *savedp = input_line_pointer;
       int len;
+
       input_line_pointer = ptr;
       *str = demand_copy_C_string (&len);
       endp = input_line_pointer;
@@ -4430,30 +4303,28 @@ subsym_get_arg (char *line, char *terminators, char **str, int nosub)
 
       /* Do forced substitutions if requested.  */
       if (!nosub && **str == ':')
-        *str = subsym_substitute (*str, 1);
+       *str = subsym_substitute (*str, 1);
     }
   else
     {
-      char *term = terminators;
+      const char *term = terminators;
       char *value = NULL;
 
       while (*ptr && *ptr != *term)
-        {
-          if (!*term)
-            {
-              term = terminators;
-              ++ptr;
-            }
-          else
-            ++term;
-        }
+       {
+         if (!*term)
+           {
+             term = terminators;
+             ++ptr;
+           }
+         else
+           ++term;
+       }
       endp = ptr;
-      *str = xmalloc (ptr - line + 1);
-      strncpy (*str, line, ptr - line);
-      (*str)[ptr - line] = 0;
+      *str = xmemdup0 (line, ptr - line);
       /* Do simple substitution, if available.  */
       if (!nosub && (value = subsym_lookup (*str, macro_level)) != NULL)
-          *str = value;
+       *str = value;
     }
 
   return endp;
@@ -4463,20 +4334,19 @@ subsym_get_arg (char *line, char *terminators, char **str, int nosub)
    We start at the innermost macro level, so that existing locals remain local
    Note: we're treating macro args identically to .var's; I don't know if
    that's compatible w/TI's assembler.  */
+
 static void
-subsym_create_or_replace (name, value)
-     char *name;
-     char *value;
+subsym_create_or_replace (char *name, char *value)
 {
   int i;
 
-  for (i=macro_level;i > 0;i--)
+  for (i = macro_level; i > 0; i--)
     {
       if (hash_find (subsym_hash[i], name))
-        {
-          hash_replace (subsym_hash[i], name, value);
-          return;
-        }
+       {
+         hash_replace (subsym_hash[i], name, value);
+         return;
+       }
     }
   if (hash_find (subsym_hash[0], name))
     hash_replace (subsym_hash[0], name, value);
@@ -4484,385 +4354,368 @@ subsym_create_or_replace (name, value)
     hash_insert (subsym_hash[0], name, value);
 }
 
-/* Look up the substitution string replacement for the given symbol 
-   start with the innermost macro substituion table given and work outwards.  */
+/* Look up the substitution string replacement for the given symbol.
+   Start with the innermost macro substitution table given and work
+   outwards.  */
+
 static char *
-subsym_lookup (name, nest_level)
-     char *name;
-     int nest_level;
+subsym_lookup (char *name, int nest_level)
 {
   char *value = hash_find (subsym_hash[nest_level], name);
 
   if (value || nest_level == 0)
     return value;
 
-  return subsym_lookup (name, nest_level-1);
+  return subsym_lookup (name, nest_level - 1);
 }
 
 /* Do substitution-symbol replacement on the given line (recursively).
-   return the argument if no substitution was done 
+   return the argument if no substitution was done
 
    Also look for built-in functions ($func (arg)) and local labels.
 
    If FORCED is set, look for forced substitutions of the form ':SYMBOL:'.  */
+
 static char *
 subsym_substitute (char *line, int forced)
 {
   /* For each apparent symbol, see if it's a substitution symbol, and if so,
      replace it in the input.  */
-  char *replacement; /* current replacement for LINE */
-  char *head; /* start of line */
-  char *ptr; /* current examination point */
-  int changed = 0; /* did we make a substitution? */
-  int eval_line = 0; /* is this line a .eval/.asg statement? */
-  int eval_symbol = 0; /* are we in the middle of the symbol for .eval/.asg? */
+  char *replacement; /* current replacement for LINE.  */
+  char *head; /* Start of line.  */
+  char *ptr; /* Current examination point.  */
+  int changed = 0; /* Did we make a substitution?  */
+  int eval_line = 0; /* Is this line a .eval/.asg statement?  */
+  int eval_symbol = 0; /* Are we in the middle of the symbol for
+                          .eval/.asg?  */
   char *eval_end = NULL;
   int recurse = 1;
   int line_conditional = 0;
   char *tmp;
 
   /* Work with a copy of the input line.  */
-  replacement = xmalloc (strlen (line) + 1);
-  strcpy (replacement, line);
+  replacement = xstrdup (line);
 
   ptr = head = replacement;
 
   /* Flag lines where we might need to replace a single '=' with two;
      GAS uses single '=' to assign macro args values, and possibly other
      places, so limit what we replace.  */
-  if (strstr (line, ".if") 
-      || strstr (line, ".elseif") 
+  if (strstr (line, ".if")
+      || strstr (line, ".elseif")
       || strstr (line, ".break"))
-    {
-      line_conditional = 1;
-    }
+    line_conditional = 1;
 
   /* Watch out for .eval, so that we avoid doing substitution on the
      symbol being assigned a value.  */
   if (strstr (line, ".eval") || strstr (line, ".asg"))
-      eval_line = 1;
+    eval_line = 1;
 
-  /* If it's a macro definition, don't do substitution on the argument names.  */
+  /* If it's a macro definition, don't do substitution on the argument
+     names.  */
   if (strstr (line, ".macro"))
     return line;
 
-  while (!is_end_of_line[(int)*ptr])
+  unsigned char current_char;
+  while (!is_end_of_line[(current_char = * (unsigned char *) ptr)])
     {
-      int current_char = *ptr;
-
       /* Need to update this since LINE may have been modified.  */
       if (eval_line)
-          eval_end = strrchr (ptr, ',');
+       eval_end = strrchr (ptr, ',');
 
       /* Replace triple double quotes with bounding quote/escapes.  */
       if (current_char == '"' && ptr[1] == '"' && ptr[2] == '"')
-        {
-          ptr[1] = '\\';
-          tmp = strstr (ptr+2, "\"\"\"");
-          if (tmp)
-            tmp[0] = '\\';
-          changed = 1;
-        }
+       {
+         ptr[1] = '\\';
+         tmp = strstr (ptr + 2, "\"\"\"");
+         if (tmp)
+           tmp[0] = '\\';
+         changed = 1;
+       }
 
       /* Replace a single '=' with a '==';
-         for compatibility with older code only.  */
-      if (line_conditional && current_char == '=') 
-        {
-          if (ptr[1] == '=')
-            {
-              ptr += 2; 
-              continue;
-            }
-          *ptr++ = '\0';
-          tmp = xmalloc (strlen (head) + 2 + strlen (ptr) + 1);
-          sprintf (tmp, "%s==%s", head, ptr);
-          /* Continue examining after the '=='.  */
-          ptr = tmp + strlen (head) + 2;
-          free (replacement);
-          head = replacement = tmp;
-          changed = 1;
-        }
+        for compatibility with older code only.  */
+      if (line_conditional && current_char == '=')
+       {
+         if (ptr[1] == '=')
+           {
+             ptr += 2;
+             continue;
+           }
+         *ptr++ = '\0';
+         tmp = concat (head, "==", ptr, (char *) NULL);
+         /* Continue examining after the '=='.  */
+         ptr = tmp + strlen (head) + 2;
+         free (replacement);
+         head = replacement = tmp;
+         changed = 1;
+       }
 
       /* Flag when we've reached the symbol part of .eval/.asg.  */
       if (eval_line && ptr >= eval_end)
-        eval_symbol = 1;
+       eval_symbol = 1;
 
       /* For each apparent symbol, see if it's a substitution symbol, and if
-         so, replace it in the input.  */
+        so, replace it in the input.  */
       if ((forced && current_char == ':')
-          || (!forced && is_name_beginner (current_char)))
-        {
-          char *name; /* symbol to be replaced */
-          char *savedp = input_line_pointer;
-          int c;
-          char *value = NULL;
-          char *tail; /* rest of line after symbol */
-          
-          /* Skip the colon.  */
-          if (forced)
-            ++ptr;
-
-          name = input_line_pointer = ptr;
-          c = get_symbol_end ();
-          /* '?' is not normally part of a symbol, but it IS part of a local
-             label.  */ 
-          if (c == '?')
-            {
-              *input_line_pointer++ = c;
-              c = *input_line_pointer;
-              *input_line_pointer = '\0';
-            }
-          /* Avoid infinite recursion; if a symbol shows up a second time for
-             substitution, leave it as is.  */
-          if (hash_find (subsym_recurse_hash, name) == NULL)
-            value = subsym_lookup (name, macro_level);
-          else
-            as_warn (_("%s symbol recursion stopped at "
-                       "second appearance of '%s'"), 
-                     forced ? "Forced substitution": "Substitution", name);
-          ptr = tail = input_line_pointer;
-          input_line_pointer = savedp;
-
-          /* Check for local labels; replace them with the appropriate
-             substitution.  */
-          if ((*name == '$' && isdigit (name[1]) && name[2] == '\0') 
-              || name[strlen (name)-1] == '?')
-            {
-              /* Use an existing identifier for that label if, available, or
-                 create a new, unique identifier.  */
-              value = hash_find (local_label_hash[macro_level], name);
-              if (value == NULL)
-                {
-                  char digit[11];
-                  char *namecopy = strcpy (xmalloc (strlen (name) + 1), name);
-                  value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
-                                  name);
-                  if (*value != '$')
-                    value[strlen (value)-1] = '\0';
-                  sprintf (digit, ".%d", local_label_id++);
-                  strcat (value, digit);
-                  hash_insert (local_label_hash[macro_level], namecopy, value);
-                }
-              /* Indicate where to continue looking for substitutions.  */
-              ptr = tail;
-            }
-          /* Check for built-in subsym and math functions.  */
-          else if (value != NULL && *name == '$')
-            {
-              subsym_proc_entry *entry = (subsym_proc_entry *)value;
-              math_proc_entry *math_entry = hash_find (math_hash, name);
-              char *arg1, *arg2 = NULL;
-
-              *ptr = c;
-              if (entry == NULL)
-                {
-                  as_bad (_("Unrecognized substitution symbol function"));
-                  break;
-                }
-              else if (*ptr != '(')
-                {
-                  as_bad (_("Missing '(' after substitution symbol function"));
-                  break;
-                }
-              ++ptr;
-              if (math_entry != NULL)
-                {
-                  float arg1, arg2 = 0;
-                  volatile float fresult;
-
-                  arg1 = (float)strtod (ptr, &ptr);
-                  if (math_entry->nargs == 2)
-                    {
-                      if (*ptr++ != ',')
-                        {
-                          as_bad (_("Expecting second argument"));
-                          break;
-                        }
-                      arg2 = (float)strtod (ptr, &ptr);
-                    }
-                  fresult = (*math_entry->proc)(arg1, arg2);
-                  value = xmalloc (128);
-                  if (math_entry->int_return)
-                    sprintf (value, "%d", (int)fresult);
-                  else
-                    sprintf (value, "%f", fresult);
-                  if (*ptr++ != ')')
-                    {
-                      as_bad (_("Extra junk in function call, expecting ')'"));
-                      break;
-                    }
-                  /* Don't bother recursing; the replacement isn't a symbol.  */
-                  recurse = 0;
-                }
-              else
-                {
-                  int val;
-                  int arg_type[2] = {*ptr == '"',0};
-                  int ismember = !strcmp (entry->name, "$ismember");
-                  /* Parse one or two args, which must be a substitution
-                     symbol, string or a character-string constant.  */
-                  /* For all functions, a string or substitution symbol may be
-                     used, with the following exceptions:
-                     firstch/lastch: 2nd arg must be character constant
-                     ismember: both args must be substitution symbols.  */
-                  ptr = subsym_get_arg (ptr, ",)", &arg1, ismember);
-                  if (!arg1)
-                    break;
-                  if (entry->nargs == 2)
-                    {
-                      if (*ptr++ != ',')
-                        {
-                          as_bad (_("Function expects two arguments"));
-                          break;
-                        }
-                      /* Character constants are converted to numerics
-                         by the preprocessor.  */
-                      arg_type[1] = (isdigit (*ptr)) ? 2 : (*ptr == '"');
-                      ptr = subsym_get_arg (ptr, ")", &arg2, ismember);
-                    }
-                  /* Args checking.  */
-                  if ((!strcmp (entry->name, "$firstch")
-                       || !strcmp (entry->name, "$lastch")) 
-                      && arg_type[1] != 2)
-                    {
-                      as_bad (_("Expecting character constant argument"));
-                      break;
-                    }
-                  if (ismember
-                      && (arg_type[0] != 0 || arg_type[1] != 0))
-                    {
-                      as_bad (_("Both arguments must be substitution symbols"));
-                      break;
-                    }
-                  if (*ptr++ != ')')
-                    {
-                      as_bad (_("Extra junk in function call, expecting ')'"));
-                      break;
-                    }
-                  val = (*entry->proc)(arg1, arg2);
-                  value = xmalloc (64);
-                  sprintf (value, "%d", val);
-                }
-              /* Fix things up to replace the entire expression, not just the
-                 function name.  */
-              tail = ptr;
-              c = *tail;
-            }
-
-          if (value != NULL && !eval_symbol)
-            {
-              /* Replace the symbol with its string replacement and
-                 continue.  Recursively replace VALUE until either no
-                 substitutions are performed, or a substitution that has been
-                 previously made is encountered again.
-
-                 put the symbol into the recursion hash table so we only
-                 try to replace a symbol once.  */
-              if (recurse)
-                {
-                  hash_insert (subsym_recurse_hash, name, name);
-                  value = subsym_substitute (value, macro_level > 0);
-                  hash_delete (subsym_recurse_hash, name);
-                }
-
-              /* Temporarily zero-terminate where the symbol started.  */
-              *name = 0; 
-              if (forced)
-                {
-                  if (c == '(')
-                    {
-                      /* Subscripted substitution symbol -- use just the
-                         indicated portion of the string; the description
-                         kinda indicates that forced substituion is not
-                         supposed to be recursive, but I'm not sure.  */
-                      unsigned beg, len = 1; /* default to a single char */
-                      char *newval = strcpy (xmalloc (strlen (value)+1), value);
-
-                      savedp = input_line_pointer;
-                      input_line_pointer = tail + 1;
-                      beg = get_absolute_expression ();
-                      if (beg < 1)
-                        {
-                          as_bad (_("Invalid subscript (use 1 to %d)"), 
-                                  strlen (value));
-                          break;
-                        }
-                      if (*input_line_pointer == ',')
-                        {
-                          ++input_line_pointer;
-                          len = get_absolute_expression ();
-                          if (beg + len > strlen (value))
-                            {
-                              as_bad (_("Invalid length (use 0 to %d"),
-                                     strlen (value) - beg);
-                              break;
-                            }
-                        }
-                      newval += beg - 1;
-                      newval[len] = 0;
-                      tail = input_line_pointer;
-                      if (*tail++ != ')')
-                        {
-                          as_bad (_("Missing ')' in subscripted substitution "
-                                    "symbol expression"));
-                          break;
-                        }
-                      c = *tail;
-                      input_line_pointer = savedp;
-
-                      value = newval;
-                    }
-                  name[-1] = 0;
-                }
-              tmp = xmalloc (strlen (head) + strlen (value) + 
-                             strlen (tail+1) + 2);
-              strcpy (tmp, head);
-              strcat (tmp, value);
-              /* Make sure forced substitutions are properly terminated.  */
-              if (forced)
-                {
-                  if (c != ':')
-                    {
-                      as_bad (_("Missing forced substitution terminator ':'"));
-                      break;
-                    }
-                  ++tail;
-#if 0
-                  /* Try to replace required whitespace 
-                     eliminated by the preprocessor; technically, a forced
-                     substitution could come anywhere, even mid-symbol,
-                     e.g. if x is "0", 'sym:x:end' should result in 'sym0end',
-                     but 'sym:x: end' should result in 'sym0 end'.
-                     FIXME -- this should really be fixed in the preprocessor,
-                     but would require several new states;
-                     KEEP_WHITE_AROUND_COLON does part of the job, but isn't
-                     complete.  */
-                  if ((is_part_of_name (tail[1])
-                       && tail[1] != '.'
-                       && tail[1] != '$') 
-                      || tail[1] == '\0' || tail[1] == ',' || tail[1] == '"')
-                    ++tail;
-                  else
-                    *tail = ' ';
-#endif
-                }
-              else
-                /* Restore the character after the symbol end.  */
-                *tail = c;
-              strcat (tmp, tail);
-              /* Continue examining after the replacement value.  */
-              ptr = tmp + strlen (head) + strlen (value);
-              free (replacement);
-              head = replacement = tmp;
-              changed = 1;
-            }
-          else
-            *ptr = c;
-        }
+         || (!forced && is_name_beginner (current_char)))
+       {
+         char *name; /* Symbol to be replaced.  */
+         char *savedp = input_line_pointer;
+         int c;
+         char *value = NULL;
+         char *tail; /* Rest of line after symbol.  */
+
+         /* Skip the colon.  */
+         if (forced)
+           ++ptr;
+
+         input_line_pointer = ptr;
+         c = get_symbol_name (&name);
+         /* '?' is not normally part of a symbol, but it IS part of a local
+            label.  */
+         if (c == '?')
+           {
+             *input_line_pointer++ = c;
+             c = *input_line_pointer;
+             *input_line_pointer = '\0';
+           }
+         /* Avoid infinite recursion; if a symbol shows up a second time for
+            substitution, leave it as is.  */
+         if (hash_find (subsym_recurse_hash, name) == NULL)
+           value = subsym_lookup (name, macro_level);
+         else
+           as_warn (_("%s symbol recursion stopped at "
+                      "second appearance of '%s'"),
+                    forced ? "Forced substitution" : "Substitution", name);
+         ptr = tail = input_line_pointer;
+         input_line_pointer = savedp;
+
+         /* Check for local labels; replace them with the appropriate
+            substitution.  */
+         if ((*name == '$' && ISDIGIT (name[1]) && name[2] == '\0')
+             || name[strlen (name) - 1] == '?')
+           {
+             /* Use an existing identifier for that label if, available, or
+                create a new, unique identifier.  */
+             value = hash_find (local_label_hash[macro_level], name);
+             if (value == NULL)
+               {
+                 char digit[11];
+                 char *namecopy = xstrdup (name);
+
+                 value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
+                                 name);
+                 if (*value != '$')
+                   value[strlen (value) - 1] = '\0';
+                 sprintf (digit, ".%d", local_label_id++);
+                 strcat (value, digit);
+                 hash_insert (local_label_hash[macro_level], namecopy, value);
+               }
+             /* Indicate where to continue looking for substitutions.  */
+             ptr = tail;
+           }
+         /* Check for built-in subsym and math functions.  */
+         else if (value != NULL && *name == '$')
+           {
+             subsym_proc_entry *entry = (subsym_proc_entry *) value;
+             math_proc_entry *math_entry = hash_find (math_hash, name);
+             char *arg1, *arg2 = NULL;
+
+             *ptr = c;
+             if (entry == NULL)
+               {
+                 as_bad (_("Unrecognized substitution symbol function"));
+                 break;
+               }
+             else if (*ptr != '(')
+               {
+                 as_bad (_("Missing '(' after substitution symbol function"));
+                 break;
+               }
+             ++ptr;
+             if (math_entry != NULL)
+               {
+                 float farg1, farg2 = 0;
+                 volatile float fresult;
+
+                 farg1 = (float) strtod (ptr, &ptr);
+                 if (math_entry->nargs == 2)
+                   {
+                     if (*ptr++ != ',')
+                       {
+                         as_bad (_("Expecting second argument"));
+                         break;
+                       }
+                     farg2 = (float) strtod (ptr, &ptr);
+                   }
+                 fresult = (*math_entry->proc) (farg1, farg2);
+                 value = XNEWVEC (char, 128);
+                 if (math_entry->int_return)
+                   sprintf (value, "%d", (int) fresult);
+                 else
+                   sprintf (value, "%f", fresult);
+                 if (*ptr++ != ')')
+                   {
+                     as_bad (_("Extra junk in function call, expecting ')'"));
+                     break;
+                   }
+                 /* Don't bother recursing; the replacement isn't a
+                     symbol.  */
+                 recurse = 0;
+               }
+             else
+               {
+                 int val;
+                 int arg_type[2] = { *ptr == '"' , 0 };
+                 int ismember = !strcmp (entry->name, "$ismember");
+
+                 /* Parse one or two args, which must be a substitution
+                    symbol, string or a character-string constant.  */
+                 /* For all functions, a string or substitution symbol may be
+                    used, with the following exceptions:
+                    firstch/lastch: 2nd arg must be character constant
+                    ismember: both args must be substitution symbols.  */
+                 ptr = subsym_get_arg (ptr, ",)", &arg1, ismember);
+                 if (!arg1)
+                   break;
+                 if (entry->nargs == 2)
+                   {
+                     if (*ptr++ != ',')
+                       {
+                         as_bad (_("Function expects two arguments"));
+                         break;
+                       }
+                     /* Character constants are converted to numerics
+                        by the preprocessor.  */
+                     arg_type[1] = (ISDIGIT (*ptr)) ? 2 : (*ptr == '"');
+                     ptr = subsym_get_arg (ptr, ")", &arg2, ismember);
+                   }
+                 /* Args checking.  */
+                 if ((!strcmp (entry->name, "$firstch")
+                      || !strcmp (entry->name, "$lastch"))
+                     && arg_type[1] != 2)
+                   {
+                     as_bad (_("Expecting character constant argument"));
+                     break;
+                   }
+                 if (ismember
+                     && (arg_type[0] != 0 || arg_type[1] != 0))
+                   {
+                     as_bad (_("Both arguments must be substitution symbols"));
+                     break;
+                   }
+                 if (*ptr++ != ')')
+                   {
+                     as_bad (_("Extra junk in function call, expecting ')'"));
+                     break;
+                   }
+                 val = (*entry->proc) (arg1, arg2);
+                 value = XNEWVEC (char, 64);
+                 sprintf (value, "%d", val);
+               }
+             /* Fix things up to replace the entire expression, not just the
+                function name.  */
+             tail = ptr;
+             c = *tail;
+           }
+
+         if (value != NULL && !eval_symbol)
+           {
+             /* Replace the symbol with its string replacement and
+                continue.  Recursively replace VALUE until either no
+                substitutions are performed, or a substitution that has been
+                previously made is encountered again.
+
+                Put the symbol into the recursion hash table so we only
+                try to replace a symbol once.  */
+             if (recurse)
+               {
+                 hash_insert (subsym_recurse_hash, name, name);
+                 value = subsym_substitute (value, macro_level > 0);
+                 hash_delete (subsym_recurse_hash, name, FALSE);
+               }
+
+             /* Temporarily zero-terminate where the symbol started.  */
+             *name = 0;
+             if (forced)
+               {
+                 if (c == '(')
+                   {
+                     /* Subscripted substitution symbol -- use just the
+                        indicated portion of the string; the description
+                        kinda indicates that forced substitution is not
+                        supposed to be recursive, but I'm not sure.  */
+                     unsigned beg, len = 1; /* default to a single char */
+                     char *newval = xstrdup (value);
+
+                     savedp = input_line_pointer;
+                     input_line_pointer = tail + 1;
+                     beg = get_absolute_expression ();
+                     if (beg < 1)
+                       {
+                         as_bad (_("Invalid subscript (use 1 to %d)"),
+                                 (int) strlen (value));
+                         break;
+                       }
+                     if (*input_line_pointer == ',')
+                       {
+                         ++input_line_pointer;
+                         len = get_absolute_expression ();
+                         if (beg + len > strlen (value))
+                           {
+                             as_bad (_("Invalid length (use 0 to %d)"),
+                                     (int) strlen (value) - beg);
+                             break;
+                           }
+                       }
+                     newval += beg - 1;
+                     newval[len] = 0;
+                     tail = input_line_pointer;
+                     if (*tail++ != ')')
+                       {
+                         as_bad (_("Missing ')' in subscripted substitution "
+                                   "symbol expression"));
+                         break;
+                       }
+                     c = *tail;
+                     input_line_pointer = savedp;
+
+                     value = newval;
+                   }
+                 name[-1] = 0;
+               }
+             tmp = xmalloc (strlen (head) + strlen (value) +
+                            strlen (tail + 1) + 2);
+             strcpy (tmp, head);
+             strcat (tmp, value);
+             /* Make sure forced substitutions are properly terminated.  */
+             if (forced)
+               {
+                 if (c != ':')
+                   {
+                     as_bad (_("Missing forced substitution terminator ':'"));
+                     break;
+                   }
+                 ++tail;
+               }
+             else
+               /* Restore the character after the symbol end.  */
+               *tail = c;
+             strcat (tmp, tail);
+             /* Continue examining after the replacement value.  */
+             ptr = tmp + strlen (head) + strlen (value);
+             free (replacement);
+             head = replacement = tmp;
+             changed = 1;
+           }
+         else
+           *ptr = c;
+       }
       else
-        {
-          ++ptr;
-        }
+       {
+         ++ptr;
+       }
     }
 
   if (changed)
@@ -4871,28 +4724,28 @@ subsym_substitute (char *line, int forced)
     return line;
 }
 
-/* We use this to handle substitution symbols 
+/* We use this to handle substitution symbols
    hijack input_line_pointer, replacing it with our substituted string.
 
    .sslist should enable listing the line after replacements are made...
 
    returns the new buffer limit.  */
+
 void
-tic54x_start_line_hook ()
+tic54x_start_line_hook (void)
 {
   char *line, *endp;
   char *replacement = NULL;
 
   /* Work with a copy of the input line, including EOL char.  */
-  endp = input_line_pointer;
-  while (!is_end_of_line[(int)*endp++])
-    ;
-  line = xmalloc (endp - input_line_pointer + 1);
-  strncpy (line, input_line_pointer, endp - input_line_pointer + 1);
-  line[endp - input_line_pointer] = 0;
+  for (endp = input_line_pointer; *endp != 0; )
+    if (is_end_of_line[(unsigned char) *endp++])
+      break;
+
+  line = xmemdup0 (input_line_pointer, endp - input_line_pointer);
 
   /* Scan ahead for parallel insns.  */
-  parallel_on_next_line_hint = next_line_shows_parallel (endp + 1);
+  parallel_on_next_line_hint = next_line_shows_parallel (endp);
 
   /* If within a macro, first process forced replacements.  */
   if (macro_level > 0)
@@ -4904,32 +4757,32 @@ tic54x_start_line_hook ()
   if (replacement != line)
     {
       char *tmp = replacement;
-      char *comment = strchr (replacement,';');
-      char endc = replacement[strlen (replacement)-1];
+      char *comment = strchr (replacement, ';');
+      char endc = replacement[strlen (replacement) - 1];
 
       /* Clean up the replacement; we'd prefer to have this done by the
-         standard preprocessing equipment (maybe do_scrub_chars?)
-         but for now, do a quick-and-dirty.  */
+        standard preprocessing equipment (maybe do_scrub_chars?)
+        but for now, do a quick-and-dirty.  */
       if (comment != NULL)
-        {
-          comment[0] = endc;
-          comment[1] = 0;
-          --comment;
-        }
-      else 
-        comment = replacement + strlen (replacement) - 1;
+       {
+         comment[0] = endc;
+         comment[1] = 0;
+         --comment;
+       }
+      else
+       comment = replacement + strlen (replacement) - 1;
 
       /* Trim trailing whitespace.  */
-      while (isspace (*comment))
-        {
-          comment[0] = endc;
-          comment[1] = 0;
-          --comment;
-        }
+      while (ISSPACE (*comment))
+       {
+         comment[0] = endc;
+         comment[1] = 0;
+         --comment;
+       }
 
       /* Compact leading whitespace.  */
-      while (isspace (tmp[0]) && isspace (tmp[1]))
-        ++tmp;
+      while (ISSPACE (tmp[0]) && ISSPACE (tmp[1]))
+       ++tmp;
 
       input_line_pointer = endp;
       input_scrub_insert_line (tmp);
@@ -4950,11 +4803,10 @@ tic54x_start_line_hook ()
    machine dependent instruction.  This function is supposed to emit
    the frags/bytes it assembles to.  */
 void
-md_assemble (line)
-  char *line;
+md_assemble (char *line)
 {
   static int repeat_slot = 0;
-  static int delay_slots = 0; /* how many delay slots left to fill? */
+  static int delay_slots = 0; /* How many delay slots left to fill?  */
   static int is_parallel = 0;
   static tic54x_insn insn;
   char *lptr;
@@ -4962,7 +4814,7 @@ md_assemble (line)
   int c;
 
   input_line_pointer = line;
-  c = get_symbol_end ();
+  c = get_symbol_name (&line);
 
   if (cpu == VNONE)
     cpu = V542;
@@ -4988,22 +4840,25 @@ md_assemble (line)
       input_line_pointer = savedp;
 
       if (tic54x_parse_parallel_insn_lastline (&insn, lptr))
-        {
-          int words = build_insn (&insn);
-
-          if (delay_slots != 0)
-            {
-              if (words > delay_slots)
-                {
-                  as_bad (_("Instruction does not fit in available delay "
-                            "slots (%d-word insn, %d slots left)"), 
-                            words, delay_slots);
-                  delay_slots = 0;
-                  return;
-                }
-              delay_slots -= words;
-            }
-        }
+       {
+         int words = build_insn (&insn);
+
+         if (delay_slots != 0)
+           {
+             if (words > delay_slots)
+               {
+                 as_bad (ngettext ("Instruction does not fit in available "
+                                   "delay slots (%d-word insn, %d slot left)",
+                                   "Instruction does not fit in available "
+                                   "delay slots (%d-word insn, %d slots left)",
+                                   delay_slots),
+                         words, delay_slots);
+                 delay_slots = 0;
+                 return;
+               }
+             delay_slots -= words;
+           }
+       }
       return;
     }
 
@@ -5012,7 +4867,7 @@ md_assemble (line)
   lptr = input_line_pointer;
   *lptr = c;
   input_line_pointer = savedp;
-  
+
   /* See if this line is part of a parallel instruction; if so, either this
      line or the next line will have the "||" specifier preceding the
      mnemonic, and we look for it in the parallel insn hash table.  */
@@ -5020,24 +4875,24 @@ md_assemble (line)
     {
       char *tmp = strstr (line, "||");
       if (tmp != NULL)
-        *tmp = '\0';
+       *tmp = '\0';
 
       if (tic54x_parse_parallel_insn_firstline (&insn, lptr))
-        {
-          is_parallel = 1;
-          /* If the parallel part is on the same line, process it now,
-             otherwise let the assembler pick up the next line for us.  */
-          if (tmp != NULL)
-            {
-              while (isspace (tmp[2]))
-                ++tmp;
-              md_assemble (tmp+2);
-            }
-        }
+       {
+         is_parallel = 1;
+         /* If the parallel part is on the same line, process it now,
+            otherwise let the assembler pick up the next line for us.  */
+         if (tmp != NULL)
+           {
+             while (ISSPACE (tmp[2]))
+               ++tmp;
+             md_assemble (tmp + 2);
+           }
+       }
       else
-        {
-          as_bad (_("Unrecognized parallel instruction '%s'"), line);
-        }
+       {
+         as_bad (_("Unrecognized parallel instruction '%s'"), line);
+       }
       return;
     }
 
@@ -5045,92 +4900,97 @@ md_assemble (line)
     {
       int words;
 
-      if ((insn.tm->flags & FL_LP) 
-          && cpu != V545LP && cpu != V546LP)
-        {
-          as_bad (_("Instruction '%s' requires an LP cpu version"),
-                  insn.tm->name);
-          return;
-        }
-      if ((insn.tm->flags & FL_FAR) 
-          && amode != far_mode)
-        {
-          as_bad (_("Instruction '%s' requires far mode addressing"),
-                  insn.tm->name);
-          return;
-        }
+      if ((insn.tm->flags & FL_LP)
+         && cpu != V545LP && cpu != V546LP)
+       {
+         as_bad (_("Instruction '%s' requires an LP cpu version"),
+                 insn.tm->name);
+         return;
+       }
+      if ((insn.tm->flags & FL_FAR)
+         && amode != far_mode)
+       {
+         as_bad (_("Instruction '%s' requires far mode addressing"),
+                 insn.tm->name);
+         return;
+       }
 
       words = build_insn (&insn);
 
       /* Is this instruction in a delay slot?  */
       if (delay_slots)
-        {
-          if (words > delay_slots)
-            {
-              as_warn (_("Instruction does not fit in available delay "
-                         "slots (%d-word insn, %d slots left). "
-                         "Resulting behavior is undefined."), 
-                       words, delay_slots);
-              delay_slots = 0;
-              return;
-            }
-          /* Branches in delay slots are not allowed.  */
-          if (insn.tm->flags & FL_BMASK)
-            {
-              as_warn (_("Instructions which cause PC discontinuity are not "
-                         "allowed in a delay slot. "
-                         "Resulting behavior is undefined."));
-            }
-          delay_slots -= words;
-        }
-      
-      /* Is this instruction the target of a repeat? */
+       {
+         if (words > delay_slots)
+           {
+             as_warn (ngettext ("Instruction does not fit in available "
+                                "delay slots (%d-word insn, %d slot left). "
+                                "Resulting behavior is undefined.",
+                                "Instruction does not fit in available "
+                                "delay slots (%d-word insn, %d slots left). "
+                                "Resulting behavior is undefined.",
+                                delay_slots),
+                      words, delay_slots);
+             delay_slots = 0;
+             return;
+           }
+         /* Branches in delay slots are not allowed.  */
+         if (insn.tm->flags & FL_BMASK)
+           {
+             as_warn (_("Instructions which cause PC discontinuity are not "
+                        "allowed in a delay slot. "
+                        "Resulting behavior is undefined."));
+           }
+         delay_slots -= words;
+       }
+
+      /* Is this instruction the target of a repeat?  */
       if (repeat_slot)
-        {
-          if (insn.tm->flags & FL_NR)
-            as_warn (_("'%s' is not repeatable. "
-                       "Resulting behavior is undefined."), 
-                     insn.tm->name);
-          else if (insn.is_lkaddr)
-            as_warn (_("Instructions using long offset modifiers or absolute "
-                       "addresses are not repeatable. "
-                       "Resulting behavior is undefined."));
-          repeat_slot = 0;
-        }
-      
+       {
+         if (insn.tm->flags & FL_NR)
+           as_warn (_("'%s' is not repeatable. "
+                      "Resulting behavior is undefined."),
+                    insn.tm->name);
+         else if (insn.is_lkaddr)
+           as_warn (_("Instructions using long offset modifiers or absolute "
+                      "addresses are not repeatable. "
+                      "Resulting behavior is undefined."));
+         repeat_slot = 0;
+       }
+
       /* Make sure we check the target of a repeat instruction.  */
       if (insn.tm->flags & B_REPEAT)
-        {
-          repeat_slot = 1;
-          /* FIXME -- warn if repeat_slot == 1 at EOF.  */
-        }
+       {
+         repeat_slot = 1;
+         /* FIXME -- warn if repeat_slot == 1 at EOF.  */
+       }
       /* Make sure we check our delay slots for validity.  */
       if (insn.tm->flags & FL_DELAY)
-        {
-          delay_slots = 2;
-          /* FIXME -- warn if delay_slots != 0 at EOF.  */
-        }
+       {
+         delay_slots = 2;
+         /* FIXME -- warn if delay_slots != 0 at EOF.  */
+       }
     }
 }
 
 /* Do a final adjustment on the symbol table; in this case, make sure we have
    a ".file" symbol.  */
+
 void
-tic54x_adjust_symtab ()
+tic54x_adjust_symtab (void)
 {
   if (symbol_rootP == NULL
       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
     {
-      char *filename;
       unsigned lineno;
-      as_where (&filename, &lineno);
-      c_dot_file_symbol (filename);
+      const char * filename = as_where (&lineno);
+      c_dot_file_symbol (filename, 0);
     }
 }
 
 /* In order to get gas to ignore any | chars at the start of a line,
-   this function returns true if a | is found in a line. 
-   This lets us process parallel instructions, which span two lines. */
+   this function returns true if a | is found in a line.
+   This lets us process parallel instructions, which span two lines.  */
+
 int
 tic54x_unrecognized_line (int c)
 {
@@ -5143,14 +5003,10 @@ tic54x_unrecognized_line (int c)
    FIXME -- obviously this isn't done yet.  These locals still show up in the
    symbol table.  */
 void
-tic54x_define_label (sym)
-     symbolS *sym;
+tic54x_define_label (symbolS *sym)
 {
-  /*static int local_label_count = 0;*/
-  /*const char *name = S_GET_NAME (sym);*/
-
   /* Just in case we need this later; note that this is not necessarily the
-     same thing as line_label... 
+     same thing as line_label...
      When aligning or assigning labels to fields, sometimes the label is
      assigned other than the address at which the label appears.
      FIXME -- is this really needed? I think all the proper label assignment
@@ -5159,31 +5015,31 @@ tic54x_define_label (sym)
 }
 
 /* Try to parse something that normal parsing failed at.  */
+
 symbolS *
-tic54x_undefined_symbol (name)
-     char *name;
+tic54x_undefined_symbol (char *name)
 {
-  symbol *sym;
+  tic54x_symbol *sym;
 
   /* Not sure how to handle predefined symbols.  */
-  if ((sym = (symbol *)hash_find (cc_hash, name)) != NULL ||
-      (sym = (symbol *)hash_find (cc2_hash, name)) != NULL ||
-      (sym = (symbol *)hash_find (cc3_hash, name)) != NULL ||
-      (sym = (symbol *)hash_find (misc_symbol_hash, name)) != NULL ||
-      (sym = (symbol *)hash_find (sbit_hash, name)) != NULL)
+  if ((sym = (tic54x_symbol *) hash_find (cc_hash, name)) != NULL ||
+      (sym = (tic54x_symbol *) hash_find (cc2_hash, name)) != NULL ||
+      (sym = (tic54x_symbol *) hash_find (cc3_hash, name)) != NULL ||
+      (sym = (tic54x_symbol *) hash_find (misc_symbol_hash, name)) != NULL ||
+      (sym = (tic54x_symbol *) hash_find (sbit_hash, name)) != NULL)
     {
-      return symbol_new (name, reg_section, 
-                         (valueT) sym->value,
-                         &zero_address_frag);
+      return symbol_new (name, reg_section,
+                        (valueT) sym->value,
+                        &zero_address_frag);
     }
 
-  if ((sym = (symbol *)hash_find (reg_hash, name)) != NULL ||
-      (sym = (symbol *)hash_find (mmreg_hash, name)) != NULL ||
+  if ((sym = (tic54x_symbol *) hash_find (reg_hash, name)) != NULL ||
+      (sym = (tic54x_symbol *) hash_find (mmreg_hash, name)) != NULL ||
       !strcasecmp (name, "a") || !strcasecmp (name, "b"))
     {
-      return symbol_new (name, reg_section, 
-                         (valueT) sym ? sym->value : 0,
-                         &zero_address_frag);
+      return symbol_new (name, reg_section,
+                        (valueT) sym ? sym->value : 0,
+                        &zero_address_frag);
     }
 
   return NULL;
@@ -5191,63 +5047,33 @@ tic54x_undefined_symbol (name)
 
 /* Parse a name in an expression before the expression parser takes a stab at
    it.  */
+
 int
-tic54x_parse_name (name, exp)
-     char *name ATTRIBUTE_UNUSED;
-     expressionS *exp ATTRIBUTE_UNUSED;
+tic54x_parse_name (char *name ATTRIBUTE_UNUSED,
+                  expressionS *expn ATTRIBUTE_UNUSED)
 {
-#if 0
-  symbol *sym = (symbol *)hash_find (mmreg_hash, name);
-  /* If it's a MMREG, replace it with its constant value.  */
-  if (sym)
-    {
-      exp->X_op = O_constant;
-      exp->X_add_number = sym->value;
-      return 1;
-    }
-#endif
   return 0;
 }
 
-char *
-md_atof (type, literalP, sizeP)
-     int type;
-     char *literalP;
-     int *sizeP;
+const char *
+md_atof (int type, char *literalP, int *sizeP)
 {
-#define MAX_LITTLENUMS 2
-  LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  LITTLENUM_TYPE *word;
-  /* only one precision on the c54x */
-  int prec = 2;
-  char *t = atof_ieee (input_line_pointer, type, words);
-  if (t)
-    input_line_pointer = t;
-  *sizeP = 4;
-
-  /* Target data is little-endian, but floats are stored big-"word"ian.  ugh.  */
-  for (word = words; prec--;)
-    {
-      md_number_to_chars (literalP, (long)(*word++), sizeof (LITTLENUM_TYPE));
-      literalP += sizeof (LITTLENUM_TYPE);
-    }
-
-  return 0;
+  /* Target data is little-endian, but floats are stored
+     big-"word"ian.  ugh.  */
+  return ieee_md_atof (type, literalP, sizeP, TRUE);
 }
 
 arelent *
-tc_gen_reloc (section, fixP)
-     asection *section;
-     fixS *fixP;
+tc_gen_reloc (asection *section, fixS *fixP)
 {
   arelent *rel;
   bfd_reloc_code_real_type code = fixP->fx_r_type;
   asymbol *sym = symbol_get_bfdsym (fixP->fx_addsy);
 
-  rel = (arelent *) xmalloc (sizeof (arelent));
-  rel->sym_ptr_ptr = (asymbol **)xmalloc (sizeof (asymbol *));
+  rel = XNEW (arelent);
+  rel->sym_ptr_ptr = XNEW (asymbol *);
   *rel->sym_ptr_ptr = sym;
-  /* We assume that all rel->address are host byte offsets */
+  /* We assume that all rel->address are host byte offsets */
   rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
   rel->address /= OCTETS_PER_BYTE;
   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
@@ -5259,18 +5085,19 @@ tc_gen_reloc (section, fixP)
       const char *name = S_GET_NAME (fixP->fx_addsy);
       if (name == NULL)
        name = "<unknown>";
-      as_fatal ("Cannot generate relocation type for symbol %s, code %s", 
-                name, bfd_get_reloc_code_name (code));
+      as_fatal ("Cannot generate relocation type for symbol %s, code %s",
+               name, bfd_get_reloc_code_name (code));
       return NULL;
     }
   return rel;
 }
 
 /* Handle cons expressions.  */
+
 void
-tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *exp)
+tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
+                    bfd_reloc_code_real_type r)
 {
-  bfd_reloc_code_real_type r;
   switch (octets)
     {
     default:
@@ -5283,33 +5110,32 @@ tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *exp)
     case 4:
       /* TI assembler always uses this, regardless of addressing mode.  */
       if (emitting_long)
-        r = BFD_RELOC_TIC54X_23;
+       r = BFD_RELOC_TIC54X_23;
       else
-        /* We never want to directly generate this; this is provided for 
-           stabs support only.  */
-        r = BFD_RELOC_32;
+       /* We never want to directly generate this; this is provided for
+          stabs support only.  */
+       r = BFD_RELOC_32;
       break;
     }
-  fix_new_exp (frag, where, octets, exp, 0, r);
+  fix_new_exp (frag, where, octets, expn, 0, r);
 }
 
-/* Attempt to simplify or even eliminate a fixup.  
+/* Attempt to simplify or even eliminate a fixup.
    To indicate that a fixup has been eliminated, set fixP->fx_done.
 
    If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry.   */
-int
-md_apply_fix (fixP, valP)
-     fixS *fixP;
-     valueT *valP;
+
+void
+md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
-  valueT val = *valP;
+  valueT val = * valP;
 
   switch (fixP->fx_r_type)
     {
     default:
       as_fatal ("Bad relocation type: 0x%02x", fixP->fx_r_type);
-      return 0;
+      return;
     case BFD_RELOC_TIC54X_MS7_OF_23:
       val = (val >> 16) & 0x7F;
       /* Fall through.  */
@@ -5317,93 +5143,78 @@ md_apply_fix (fixP, valP)
     case BFD_RELOC_16:
       bfd_put_16 (stdoutput, val, buf);
       /* Indicate what we're actually writing, so that we don't get warnings
-         about exceeding available space.  */
+        about exceeding available space.  */
       *valP = val & 0xFFFF;
       break;
     case BFD_RELOC_TIC54X_PARTLS7:
       bfd_put_16 (stdoutput,
-                  (bfd_get_16 (stdoutput, buf) & 0xFF80) | (val & 0x7F),
-                  buf);
+                 (bfd_get_16 (stdoutput, buf) & 0xFF80) | (val & 0x7F),
+                 buf);
       /* Indicate what we're actually writing, so that we don't get warnings
-         about exceeding available space.  */
+        about exceeding available space.  */
       *valP = val & 0x7F;
       break;
     case BFD_RELOC_TIC54X_PARTMS9:
       /* TI assembler doesn't shift its encoding for relocatable files, and is
-         thus incompatible with this implementation's relocatable files.  */ 
-      bfd_put_16 (stdoutput, 
-                  (bfd_get_16 (stdoutput, buf) & 0xFE00) | (val >> 7), 
-                  buf);
+        thus incompatible with this implementation's relocatable files.  */
+      bfd_put_16 (stdoutput,
+                 (bfd_get_16 (stdoutput, buf) & 0xFE00) | (val >> 7),
+                 buf);
       break;
     case BFD_RELOC_32:
     case BFD_RELOC_TIC54X_23:
       bfd_put_32 (stdoutput,
-                  (bfd_get_32 (stdoutput, buf) & 0xFF800000) | val,
-                  buf);
+                 (bfd_get_32 (stdoutput, buf) & 0xFF800000) | val,
+                 buf);
       break;
     }
 
-  return 0; /* Return value is ignored.  */
+  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+    fixP->fx_done = 1;
 }
 
-/* This is our chance to record section alignment 
+/* This is our chance to record section alignment
    don't need to do anything here, since BFD does the proper encoding.  */
+
 valueT
-md_section_align (segment, section_size)
-     segT segment ATTRIBUTE_UNUSED;
-     valueT section_size;
+md_section_align (segT segment ATTRIBUTE_UNUSED, valueT section_size)
 {
   return section_size;
 }
 
 long
-md_pcrel_from (fixP)
-     fixS *fixP ATTRIBUTE_UNUSED;
+md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
-#if defined OBJ_COFF
-
-short
-tc_coff_fix2rtype (fixP)
-     fixS *fixP;
-{
-  return (fixP->fx_r_type);
-}
-
-#endif /* OBJ_COFF */
+/* Mostly little-endian, but longwords (4 octets) get MS word stored
+   first.  */
 
-/* Mostly little-endian, but longwords (4 octets) get MS word stored first.  */
 void
-tic54x_number_to_chars (buf, val, n)
-  char *buf;
-  valueT val;
-  int n;
+tic54x_number_to_chars (char *buf, valueT val, int n)
 {
   if (n != 4)
-      number_to_chars_littleendian (buf, val, n);
+    number_to_chars_littleendian (buf, val, n);
   else
     {
-      number_to_chars_littleendian (buf, val>>16, 2);
-      number_to_chars_littleendian (buf+2, val&0xFFFF, 2);
+      number_to_chars_littleendian (buf    , val >> 16   , 2);
+      number_to_chars_littleendian (buf + 2, val & 0xFFFF, 2);
     }
 }
 
-int 
-tic54x_estimate_size_before_relax (frag, seg)
-  fragS *frag ATTRIBUTE_UNUSED;
-  segT seg ATTRIBUTE_UNUSED;
+int
+tic54x_estimate_size_before_relax (fragS *frag ATTRIBUTE_UNUSED,
+                                  segT seg ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 /* We use this to handle bit allocations which we couldn't handle before due
    to symbols being in different frags.  return number of octets added.  */
-int 
-tic54x_relax_frag (frag, stretch)
-  fragS *frag;
-  long stretch ATTRIBUTE_UNUSED;
+
+int
+tic54x_relax_frag (fragS *frag, long stretch ATTRIBUTE_UNUSED)
 {
   symbolS *sym = frag->fr_symbol;
   int growth = 0;
@@ -5411,109 +5222,110 @@ tic54x_relax_frag (frag, stretch)
 
   if (sym != NULL)
     {
-      struct bit_info *bi = (struct bit_info *)frag->fr_opcode;
+      struct bit_info *bi = (struct bit_info *) frag->fr_opcode;
       int bit_offset = frag_bit_offset (frag_prev (frag, bi->seg), bi->seg);
       int size = S_GET_VALUE (sym);
       fragS *prev_frag = bit_offset_frag (frag_prev (frag, bi->seg), bi->seg);
       int available = 16 - bit_offset;
 
       if (symbol_get_frag (sym) != &zero_address_frag
-          || S_IS_COMMON (sym)
-          || !S_IS_DEFINED (sym))
-        as_bad_where (frag->fr_file, frag->fr_line,
-                      _("non-absolute value used with .space/.bes"));
+         || S_IS_COMMON (sym)
+         || !S_IS_DEFINED (sym))
+       as_bad_where (frag->fr_file, frag->fr_line,
+                     _("non-absolute value used with .space/.bes"));
 
       if (size < 0)
-        {
-          as_warn (_("negative value ignored in %s"),
-                   bi->type == TYPE_SPACE ? ".space" :
-                   bi->type == TYPE_BES ? ".bes" : ".field");
-          growth = 0;
-          frag->tc_frag_data = frag->fr_fix = 0;
-          return 0;
-        }
+       {
+         as_warn (_("negative value ignored in %s"),
+                  bi->type == TYPE_SPACE ? ".space" :
+                  bi->type == TYPE_BES ? ".bes" : ".field");
+         growth = 0;
+         frag->tc_frag_data = frag->fr_fix = 0;
+         return 0;
+       }
 
       if (bi->type == TYPE_FIELD)
-        {
-          /* Bit fields of 16 or larger will have already been handled.  */
-          if (bit_offset != 0 && available >= size)
-            {
-              char *p = prev_frag->fr_literal;
-              valueT value = bi->value;
-              value <<= available - size;
-              value |= ((unsigned short)p[1]<<8) | p[0];
-              md_number_to_chars (p, value, 2);
-              if ((prev_frag->tc_frag_data += size) == 16)
-                prev_frag->tc_frag_data = 0;
-              if (bi->sym)
-                symbol_set_frag (bi->sym, prev_frag);
-              /* This frag is no longer used.  */
-              growth = -frag->fr_fix;
-              frag->fr_fix = 0;
-              frag->tc_frag_data = 0;
-            }
-          else
-            {
-              char *p = frag->fr_literal;
-              valueT value = bi->value << (16 - size);
-              md_number_to_chars (p, value, 2);
-              if ((frag->tc_frag_data = size) == 16)
-                frag->tc_frag_data = 0;
-              growth = 0;
-            }
-        }
+       {
+         /* Bit fields of 16 or larger will have already been handled.  */
+         if (bit_offset != 0 && available >= size)
+           {
+             char *p = prev_frag->fr_literal;
+
+             valueT value = bi->value;
+             value <<= available - size;
+             value |= ((unsigned short) p[1] << 8) | p[0];
+             md_number_to_chars (p, value, 2);
+             if ((prev_frag->tc_frag_data += size) == 16)
+               prev_frag->tc_frag_data = 0;
+             if (bi->sym)
+               symbol_set_frag (bi->sym, prev_frag);
+             /* This frag is no longer used.  */
+             growth = -frag->fr_fix;
+             frag->fr_fix = 0;
+             frag->tc_frag_data = 0;
+           }
+         else
+           {
+             char *p = frag->fr_literal;
+
+             valueT value = bi->value << (16 - size);
+             md_number_to_chars (p, value, 2);
+             if ((frag->tc_frag_data = size) == 16)
+               frag->tc_frag_data = 0;
+             growth = 0;
+           }
+       }
       else
-        {
-          if (bit_offset != 0 && bit_offset < 16)
-            {
-              if (available >= size)
-                {
-                  if ((prev_frag->tc_frag_data += size) == 16)
-                    prev_frag->tc_frag_data = 0;
-                  if (bi->sym)
-                    symbol_set_frag (bi->sym, prev_frag);
-                  /* this frag is no longer used */
-                  growth = -frag->fr_fix;
-                  frag->fr_fix = 0;
-                  frag->tc_frag_data = 0;
-                  goto getout;
-                }
-              if (bi->type == TYPE_SPACE && bi->sym)
-                symbol_set_frag (bi->sym, prev_frag);
-              size -= available;
-            }
-          growth = (size + 15) / 16 * OCTETS_PER_BYTE - frag->fr_fix;
-          for (i=0;i < growth;i++)
-            frag->fr_literal[i] = 0;
-          frag->fr_fix = growth;
-          frag->tc_frag_data = size % 16;
-          /* Make sure any BES label points to the LAST word allocated.  */
-          if (bi->type == TYPE_BES && bi->sym)
-            S_SET_VALUE (bi->sym, frag->fr_fix / OCTETS_PER_BYTE - 1);
-        }
+       {
+         if (bit_offset != 0 && bit_offset < 16)
+           {
+             if (available >= size)
+               {
+                 if ((prev_frag->tc_frag_data += size) == 16)
+                   prev_frag->tc_frag_data = 0;
+                 if (bi->sym)
+                   symbol_set_frag (bi->sym, prev_frag);
+                 /* This frag is no longer used.  */
+                 growth = -frag->fr_fix;
+                 frag->fr_fix = 0;
+                 frag->tc_frag_data = 0;
+                 goto getout;
+               }
+             if (bi->type == TYPE_SPACE && bi->sym)
+               symbol_set_frag (bi->sym, prev_frag);
+             size -= available;
+           }
+         growth = (size + 15) / 16 * OCTETS_PER_BYTE - frag->fr_fix;
+         for (i = 0; i < growth; i++)
+           frag->fr_literal[i] = 0;
+         frag->fr_fix = growth;
+         frag->tc_frag_data = size % 16;
+         /* Make sure any BES label points to the LAST word allocated.  */
+         if (bi->type == TYPE_BES && bi->sym)
+           S_SET_VALUE (bi->sym, frag->fr_fix / OCTETS_PER_BYTE - 1);
+       }
     getout:
       frag->fr_symbol = 0;
       frag->fr_opcode = 0;
-      free ((void *)bi);
+      free ((void *) bi);
     }
   return growth;
 }
 
 void
-tic54x_convert_frag (abfd, seg, frag)
-  bfd *abfd ATTRIBUTE_UNUSED;
-  segT seg ATTRIBUTE_UNUSED;
-  fragS *frag;
+tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
+                    segT seg ATTRIBUTE_UNUSED,
+                    fragS *frag)
 {
   /* Offset is in bytes.  */
-  frag->fr_offset = (frag->fr_next->fr_address 
-                     - frag->fr_address
-                     - frag->fr_fix) / frag->fr_var;
+  frag->fr_offset = (frag->fr_next->fr_address
+                    - frag->fr_address
+                    - frag->fr_fix) / frag->fr_var;
   if (frag->fr_offset < 0)
     {
       as_bad_where (frag->fr_file, frag->fr_line,
-                    _("attempt to .space/.bes backwards? (%ld)"),
-                    (long) frag->fr_offset);
+                   _("attempt to .space/.bes backwards? (%ld)"),
+                   (long) frag->fr_offset);
     }
   frag->fr_type = rs_space;
 }
@@ -5523,48 +5335,43 @@ tic54x_convert_frag (abfd, seg, frag)
    syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
    I guess, except I've never seen a definition of MRI syntax).
 
-   C is the character that used to be at *REST, which points to the end of the
-   label. 
-
    Don't allow labels to start with '.'  */
+
 int
-tic54x_start_label (c, rest)
-  int c;
-  char *rest;
+tic54x_start_label (char * label_start, int nul_char, int next_char)
 {
+  char *rest;
+
   /* If within .struct/.union, no auto line labels, please.  */
   if (current_stag != NULL)
     return 0;
 
   /* Disallow labels starting with "."  */
-  if (c != ':')
+  if (next_char != ':')
     {
-      char *label = rest;
-      while (!is_end_of_line[(int)label[-1]])
-        --label;
-      if (*label == '.')
-        {
-          as_bad (_("Invalid label '%s'"), label);
-          return 0;
-        }
+      if (*label_start == '.')
+       {
+         as_bad (_("Invalid label '%s'"), label_start);
+         return 0;
+       }
     }
 
-  if (is_end_of_line[(int)c])
+  if (is_end_of_line[(unsigned char) next_char])
     return 1;
 
-  if (isspace (c))
-    while (isspace (c = *++rest))
-      ;
-  if (c == '.')
-    {
-      /* Don't let colon () define a label for any of these...  */
-      return (strncasecmp (rest, ".tag", 4) != 0 || !isspace (rest[4]))
-        && (strncasecmp (rest, ".struct", 7) != 0 || !isspace (rest[7]))
-        && (strncasecmp (rest, ".union", 6) != 0 || !isspace (rest[6]))
-        && (strncasecmp (rest, ".macro", 6) != 0 || !isspace (rest[6]))
-        && (strncasecmp (rest, ".set", 4) != 0 || !isspace (rest[4]))
-        && (strncasecmp (rest, ".equ", 4) != 0 || !isspace (rest[4]));
-    }
+  rest = input_line_pointer;
+  if (nul_char == '"')
+    ++rest;
+  while (ISSPACE (next_char))
+    next_char = *++rest;
+  if (next_char != '.')
+    return 1;
 
-  return 1;
+  /* Don't let colon () define a label for any of these...  */
+  return ((strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
+         && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
+         && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
+         && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
+         && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
+         && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4])));
 }
This page took 0.140007 seconds and 4 git commands to generate.