Home | History | Annotate | Download | only in config
      1 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
      2    Copyright (C) 1999-2014 Free Software Foundation, Inc.
      3    Contributed by Timothy Wall (twall (at) cygnus.com)
      4 
      5    This file is part of GAS, the GNU Assembler.
      6 
      7    GAS is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    GAS is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GAS; see the file COPYING.  If not, write to the Free
     19    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     20    02110-1301, USA.  */
     21 
     22 /* Texas Instruments TMS320C54X machine specific gas.
     23    Written by Timothy Wall (twall (at) alum.mit.edu).
     24 
     25    Valuable things to do:
     26    Pipeline conflict warnings
     27    We encode/decode "ld #_label, dp" differently in relocatable files
     28      This means we're not compatible with TI output containing those
     29      expressions.  We store the upper nine bits; TI stores the lower nine
     30      bits.  How they recover the original upper nine bits is beyond me.
     31 
     32    Tests to add to expect testsuite:
     33      '=' and '==' with .if, .elseif, and .break
     34 
     35    Incompatibilities (mostly trivial):
     36    We don't allow '''
     37    We fill text section with zeroes instead of "nop"s
     38    We don't convert '' or "" to a single instance
     39    We don't convert '' to '\0'
     40    We don't allow strings with .byte/.half/.short/.long
     41    Probably details of the subsym stuff are different
     42    TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
     43 
     44    COFF1 limits section names to 8 characters.
     45    Some of the default behavior changed from COFF1 to COFF2.  */
     46 
     47 #include "as.h"
     48 #include <limits.h>
     49 #include "safe-ctype.h"
     50 #include "sb.h"
     51 #include "macro.h"
     52 #include "subsegs.h"
     53 #include "struc-symbol.h"
     54 #include "opcode/tic54x.h"
     55 #include "obj-coff.h"
     56 #include <math.h>
     57 
     58 
     59 static struct stag
     60 {
     61   symbolS *sym;		        /* Symbol for this stag; value is offset.  */
     62   const char *name;		/* Shortcut to symbol name.  */
     63   bfd_vma size;		        /* Size of struct/union.  */
     64   int current_bitfield_offset;  /* Temporary for tracking fields.  */
     65   int is_union;
     66   struct stag_field		/* List of fields.  */
     67   {
     68     const char *name;
     69     bfd_vma offset;		/* Of start of this field.  */
     70     int bitfield_offset;	/* Of start of this field.  */
     71     struct stag *stag;	        /* If field is struct/union.  */
     72     struct stag_field *next;
     73   } *field;
     74   /* For nesting; used only in stag construction.  */
     75   struct stag *inner;	        /* Enclosed .struct.  */
     76   struct stag *outer;	        /* Enclosing .struct.  */
     77 } *current_stag = NULL;
     78 
     79 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm.  */
     80 
     81 typedef struct _tic54x_insn
     82 {
     83   const insn_template *tm;	/* Opcode template.  */
     84 
     85   char mnemonic[MAX_LINE];	/* Opcode name/mnemonic.  */
     86   char parmnemonic[MAX_LINE];   /* 2nd mnemonic of parallel insn.  */
     87 
     88   int opcount;
     89   struct opstruct
     90   {
     91     char buf[MAX_LINE];
     92     enum optype type;
     93     expressionS exp;
     94   } operands[MAX_OPERANDS];
     95 
     96   int paropcount;
     97   struct opstruct paroperands[MAX_OPERANDS];
     98 
     99   int is_lkaddr;
    100   int lkoperand;
    101   int words;			/* Size of insn in 16-bit words.  */
    102   int using_default_dst;	/* Do we need to explicitly set an
    103 				   omitted OP_DST operand?  */
    104   struct
    105   {
    106     unsigned short word;	     /* Final encoded opcode data.  */
    107     int unresolved;
    108     int r_nchars;		     /* Relocation size.  */
    109     bfd_reloc_code_real_type r_type; /* Relocation type.  */
    110     expressionS addr_expr;	     /* Storage for unresolved expressions.  */
    111   } opcode[3];
    112 } tic54x_insn;
    113 
    114 enum cpu_version
    115 {
    116   VNONE = 0, V541 = 1, V542 = 2, V543 = 3, V545 = 5, V548 = 8, V549 = 9,
    117   V545LP = 15, V546LP = 16
    118 };
    119 
    120 enum address_mode
    121 {
    122   c_mode,   /* 16-bit addresses.  */
    123   far_mode  /* >16-bit addresses.  */
    124 };
    125 
    126 static segT stag_saved_seg;
    127 static subsegT stag_saved_subseg;
    128 
    129 const char comment_chars[] = ";";
    130 const char line_comment_chars[] = ";*#"; /* At column zero only.  */
    131 const char line_separator_chars[] = ""; /* Not permitted.  */
    132 
    133 int emitting_long = 0;
    134 
    135 /* Characters which indicate that this is a floating point constant.  */
    136 const char FLT_CHARS[] = "fF";
    137 
    138 /* Characters that can be used to separate mantissa from exp in FP
    139    nums.  */
    140 const char EXP_CHARS[] = "eE";
    141 
    142 const char *md_shortopts = "";
    143 
    144 #define OPTION_ADDRESS_MODE     (OPTION_MD_BASE)
    145 #define OPTION_CPU_VERSION      (OPTION_ADDRESS_MODE + 1)
    146 #define OPTION_COFF_VERSION     (OPTION_CPU_VERSION + 1)
    147 #define OPTION_STDERR_TO_FILE   (OPTION_COFF_VERSION + 1)
    148 
    149 struct option md_longopts[] =
    150 {
    151   { "mfar-mode",       no_argument,	    NULL, OPTION_ADDRESS_MODE },
    152   { "mf",	       no_argument,	    NULL, OPTION_ADDRESS_MODE },
    153   { "mcpu",	       required_argument,   NULL, OPTION_CPU_VERSION },
    154   { "merrors-to-file", required_argument,   NULL, OPTION_STDERR_TO_FILE },
    155   { "me",	       required_argument,   NULL, OPTION_STDERR_TO_FILE },
    156   { NULL,              no_argument,         NULL, 0},
    157 };
    158 
    159 size_t md_longopts_size = sizeof (md_longopts);
    160 
    161 static int assembly_begun = 0;
    162 /* Addressing mode is not entirely implemented; the latest rev of the Other
    163    assembler doesn't seem to make any distinction whatsoever; all relocations
    164    are stored as extended relocatiosn.  Older versions used REL16 vs RELEXT16,
    165    but now it seems all relocations are RELEXT16.  We use all RELEXT16.
    166 
    167    The cpu version is kind of a waste of time as well.  There is one
    168    instruction (RND) for LP devices only, and several for devices with
    169    extended addressing only.  We include it for compatibility.  */
    170 static enum address_mode amode = c_mode;
    171 static enum cpu_version cpu = VNONE;
    172 
    173 /* Include string substitutions in listing?  */
    174 static int listing_sslist = 0;
    175 
    176 /* Did we do subsym substitutions on the line?  */
    177 static int substitution_line = 0;
    178 
    179 /* Last label seen.  */
    180 static symbolS *last_label_seen = NULL;
    181 
    182 /* This ensures that all new labels are unique.  */
    183 static int local_label_id;
    184 
    185 static struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse.  */
    186 static struct hash_control *math_hash; /* Built-in math functions.  */
    187 /* Allow maximum levels of macro nesting; level 0 is the main substitution
    188    symbol table.  The other assembler only does 32 levels, so there!  */
    189 static struct hash_control *subsym_hash[100];
    190 
    191 /* Keep track of local labels so we can substitute them before GAS sees them
    192    since macros use their own 'namespace' for local labels, use a separate hash
    193 
    194    We do our own local label handling 'cuz it's subtly different from the
    195    stock GAS handling.
    196 
    197    We use our own macro nesting counter, since GAS overloads it when expanding
    198    other things (like conditionals and repeat loops).  */
    199 static int macro_level = 0;
    200 static struct hash_control *local_label_hash[100];
    201 /* Keep track of struct/union tags.  */
    202 static struct hash_control *stag_hash;
    203 static struct hash_control *op_hash;
    204 static struct hash_control *parop_hash;
    205 static struct hash_control *reg_hash;
    206 static struct hash_control *mmreg_hash;
    207 static struct hash_control *cc_hash;
    208 static struct hash_control *cc2_hash;
    209 static struct hash_control *cc3_hash;
    210 static struct hash_control *sbit_hash;
    211 static struct hash_control *misc_symbol_hash;
    212 
    213 /* Only word (et al.), align, or conditionals are allowed within
    214    .struct/.union.  */
    215 #define ILLEGAL_WITHIN_STRUCT()					\
    216   do								\
    217     if (current_stag != NULL)					\
    218       { 							\
    219 	as_bad (_("pseudo-op illegal within .struct/.union"));	\
    220 	return;							\
    221       }								\
    222   while (0)
    223 
    224 
    225 static void subsym_create_or_replace (char *, char *);
    226 static char *subsym_lookup (char *, int);
    227 static char *subsym_substitute (char *, int);
    228 
    229 
    230 void
    231 md_show_usage (FILE *stream)
    232 {
    233   fprintf (stream, _("C54x-specific command line  options:\n"));
    234   fprintf (stream, _("-mfar-mode | -mf          Use extended addressing\n"));
    235   fprintf (stream, _("-mcpu=<CPU version>       Specify the CPU version\n"));
    236   fprintf (stream, _("-merrors-to-file <filename>\n"));
    237   fprintf (stream, _("-me <filename>            Redirect errors to a file\n"));
    238 }
    239 
    240 /* Output a single character (upper octect is zero).  */
    241 
    242 static void
    243 tic54x_emit_char (char c)
    244 {
    245   expressionS expn;
    246 
    247   expn.X_op = O_constant;
    248   expn.X_add_number = c;
    249   emit_expr (&expn, 2);
    250 }
    251 
    252 /* Walk backwards in the frag chain.  */
    253 
    254 static fragS *
    255 frag_prev (fragS *frag, segT seg)
    256 {
    257   segment_info_type *seginfo = seg_info (seg);
    258   fragS *fragp;
    259 
    260   for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
    261     if (fragp->fr_next == frag)
    262       return fragp;
    263 
    264   return NULL;
    265 }
    266 
    267 static fragS *
    268 bit_offset_frag (fragS *frag, segT seg)
    269 {
    270   while (frag != NULL)
    271     {
    272       if (frag->fr_fix == 0
    273 	  && frag->fr_opcode == NULL
    274 	  && frag->tc_frag_data == 0)
    275 	frag = frag_prev (frag, seg);
    276       else
    277 	return frag;
    278     }
    279   return NULL;
    280 }
    281 
    282 /* Return the number of bits allocated in the most recent word, or zero if
    283    none. .field/.space/.bes may leave words partially allocated.  */
    284 
    285 static int
    286 frag_bit_offset (fragS *frag, segT seg)
    287 {
    288   frag = bit_offset_frag (frag, seg);
    289 
    290   if (frag)
    291     return frag->fr_opcode != NULL ? -1 : frag->tc_frag_data;
    292 
    293   return 0;
    294 }
    295 
    296 /* Read an expression from a C string; returns a pointer past the end of the
    297    expression.  */
    298 
    299 static char *
    300 parse_expression (char *str, expressionS *expn)
    301 {
    302   char *s;
    303   char *tmp;
    304 
    305   tmp = input_line_pointer;	/* Save line pointer.  */
    306   input_line_pointer = str;
    307   expression (expn);
    308   s = input_line_pointer;
    309   input_line_pointer = tmp;	/* Restore line pointer.  */
    310   return s;			/* Return pointer to where parsing stopped.  */
    311 }
    312 
    313 /* .asg "character-string"|character-string, symbol
    314 
    315    .eval is the only pseudo-op allowed to perform arithmetic on substitution
    316    symbols.  all other use of symbols defined with .asg are currently
    317    unsupported.  */
    318 
    319 static void
    320 tic54x_asg (int x ATTRIBUTE_UNUSED)
    321 {
    322   int c;
    323   char *name;
    324   char *str;
    325   char *tmp;
    326   int quoted = *input_line_pointer == '"';
    327 
    328   ILLEGAL_WITHIN_STRUCT ();
    329 
    330   if (quoted)
    331     {
    332       int len;
    333       str = demand_copy_C_string (&len);
    334       c = *input_line_pointer;
    335     }
    336   else
    337     {
    338       str = input_line_pointer;
    339       while ((c = *input_line_pointer) != ',')
    340 	{
    341 	  if (is_end_of_line[(int) *input_line_pointer])
    342 	    break;
    343 	  ++input_line_pointer;
    344 	}
    345       *input_line_pointer = 0;
    346     }
    347   if (c != ',')
    348     {
    349       as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
    350       ignore_rest_of_line ();
    351       return;
    352     }
    353 
    354   name = ++input_line_pointer;
    355   c = get_symbol_end ();	/* Get terminator.  */
    356   if (!ISALPHA (*name))
    357     {
    358       as_bad (_("symbols assigned with .asg must begin with a letter"));
    359       ignore_rest_of_line ();
    360       return;
    361     }
    362 
    363   tmp = xmalloc (strlen (str) + 1);
    364   strcpy (tmp, str);
    365   str = tmp;
    366   tmp = xmalloc (strlen (name) + 1);
    367   strcpy (tmp, name);
    368   name = tmp;
    369   subsym_create_or_replace (name, str);
    370   *input_line_pointer = c;
    371   demand_empty_rest_of_line ();
    372 }
    373 
    374 /* .eval expression, symbol
    375    There's something screwy about this.  The other assembler sometimes does and
    376    sometimes doesn't substitute symbols defined with .eval.
    377    We'll put the symbols into the subsym table as well as the normal symbol
    378    table, since that's what works best.  */
    379 
    380 static void
    381 tic54x_eval (int x ATTRIBUTE_UNUSED)
    382 {
    383   char c;
    384   int value;
    385   char *name;
    386   symbolS *symbolP;
    387   char valuestr[32], *tmp;
    388   int quoted;
    389 
    390   ILLEGAL_WITHIN_STRUCT ();
    391 
    392   SKIP_WHITESPACE ();
    393 
    394   quoted = *input_line_pointer == '"';
    395   if (quoted)
    396     ++input_line_pointer;
    397   value = get_absolute_expression ();
    398   if (quoted)
    399     {
    400       if (*input_line_pointer != '"')
    401 	{
    402 	  as_bad (_("Unterminated string after absolute expression"));
    403 	  ignore_rest_of_line ();
    404 	  return;
    405 	}
    406       ++input_line_pointer;
    407     }
    408   if (*input_line_pointer++ != ',')
    409     {
    410       as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
    411       ignore_rest_of_line ();
    412       return;
    413     }
    414   name = input_line_pointer;
    415   c = get_symbol_end ();	/* Get terminator.  */
    416   tmp = xmalloc (strlen (name) + 1);
    417   name = strcpy (tmp, name);
    418   *input_line_pointer = c;
    419 
    420   if (!ISALPHA (*name))
    421     {
    422       as_bad (_("symbols assigned with .eval must begin with a letter"));
    423       ignore_rest_of_line ();
    424       return;
    425     }
    426   symbolP = symbol_new (name, absolute_section,
    427 			(valueT) value, &zero_address_frag);
    428   SF_SET_LOCAL (symbolP);
    429   symbol_table_insert (symbolP);
    430 
    431   /* The "other" assembler sometimes doesn't put .eval's in the subsym table
    432      But since there's not written rule as to when, don't even bother trying
    433      to match their behavior.  */
    434   sprintf (valuestr, "%d", value);
    435   tmp = xmalloc (strlen (valuestr) + 1);
    436   strcpy (tmp, valuestr);
    437   subsym_create_or_replace (name, tmp);
    438 
    439   demand_empty_rest_of_line ();
    440 }
    441 
    442 /* .bss symbol, size [, [blocking flag] [, alignment flag]
    443 
    444    alignment is to a longword boundary; blocking is to 128-word boundary.
    445 
    446    1) if there is a hole in memory, this directive should attempt to fill it
    447       (not yet implemented).
    448 
    449    2) if the blocking flag is not set, allocate at the current SPC
    450       otherwise, check to see if the current SPC plus the space to be
    451       allocated crosses the page boundary (128 words).
    452       if there's not enough space, create a hole and align with the next page
    453       boundary.
    454       (not yet implemented).  */
    455 
    456 static void
    457 tic54x_bss (int x ATTRIBUTE_UNUSED)
    458 {
    459   char c;
    460   char *name;
    461   char *p;
    462   int words;
    463   segT current_seg;
    464   subsegT current_subseg;
    465   symbolS *symbolP;
    466   int block = 0;
    467   int align = 0;
    468 
    469   ILLEGAL_WITHIN_STRUCT ();
    470 
    471   current_seg = now_seg;	/* Save current seg.  */
    472   current_subseg = now_subseg;	/* Save current subseg.  */
    473 
    474   name = input_line_pointer;
    475   c = get_symbol_end ();	/* Get terminator.  */
    476   if (c != ',')
    477     {
    478       as_bad (_(".bss size argument missing\n"));
    479       ignore_rest_of_line ();
    480       return;
    481     }
    482 
    483   ++input_line_pointer;
    484   words = get_absolute_expression ();
    485   if (words < 0)
    486     {
    487       as_bad (_(".bss size %d < 0!"), words);
    488       ignore_rest_of_line ();
    489       return;
    490     }
    491 
    492   if (*input_line_pointer == ',')
    493     {
    494       /* The blocking flag may be missing.  */
    495       ++input_line_pointer;
    496       if (*input_line_pointer != ',')
    497 	block = get_absolute_expression ();
    498       else
    499 	block = 0;
    500 
    501       if (*input_line_pointer == ',')
    502 	{
    503 	  ++input_line_pointer;
    504 	  align = get_absolute_expression ();
    505 	}
    506       else
    507 	align = 0;
    508     }
    509   else
    510     block = align = 0;
    511 
    512   subseg_set (bss_section, 0);
    513   symbolP = symbol_find_or_make (name);
    514 
    515   if (S_GET_SEGMENT (symbolP) == bss_section)
    516     symbolP->sy_frag->fr_symbol = (symbolS *) NULL;
    517 
    518   symbol_set_frag (symbolP, frag_now);
    519   p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
    520 		(offsetT) (words * OCTETS_PER_BYTE), (char *) 0);
    521   *p = 0;			/* Fill char.  */
    522 
    523   S_SET_SEGMENT (symbolP, bss_section);
    524 
    525   /* The symbol may already have been created with a preceding
    526      ".globl" directive -- be careful not to step on storage class
    527      in that case.  Otherwise, set it to static.  */
    528   if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
    529     S_SET_STORAGE_CLASS (symbolP, C_STAT);
    530 
    531   if (align)
    532     {
    533       /* s_align eats end of line; restore it */
    534       s_align_bytes (4);
    535       --input_line_pointer;
    536     }
    537 
    538   if (block)
    539     bss_section->flags |= SEC_TIC54X_BLOCK;
    540 
    541   subseg_set (current_seg, current_subseg);	/* Restore current seg.  */
    542   demand_empty_rest_of_line ();
    543 }
    544 
    545 static void
    546 stag_add_field_symbols (struct stag *stag,
    547 			const char *path,
    548 			bfd_vma base_offset,
    549 			symbolS *rootsym,
    550 			const char *root_stag_name)
    551 {
    552   char prefix[strlen (path) + 2];
    553   struct stag_field *field = stag->field;
    554 
    555   /* Construct a symbol for every field contained within this structure
    556      including fields within structure fields.  */
    557   strcpy (prefix, path);
    558   if (*path)
    559     strcat (prefix, ".");
    560 
    561   while (field != NULL)
    562     {
    563       int len = strlen (prefix) + strlen (field->name) + 2;
    564       char *name = xmalloc (len);
    565       strcpy (name, prefix);
    566       strcat (name, field->name);
    567 
    568       if (rootsym == NULL)
    569 	{
    570 	  symbolS *sym;
    571 	  sym = symbol_new (name, absolute_section,
    572 			    (field->stag ? field->offset :
    573 			     (valueT) (base_offset + field->offset)),
    574 			    &zero_address_frag);
    575 	  SF_SET_LOCAL (sym);
    576 	  symbol_table_insert (sym);
    577 	}
    578       else
    579 	{
    580 	  char *replacement = xmalloc (strlen (name)
    581 				       + strlen (stag->name) + 2);
    582 	  strcpy (replacement, S_GET_NAME (rootsym));
    583 	  strcat (replacement, "+");
    584 	  strcat (replacement, root_stag_name);
    585 	  strcat (replacement, name + strlen (S_GET_NAME (rootsym)));
    586 	  hash_insert (subsym_hash[0], name, replacement);
    587 	}
    588 
    589       /* Recurse if the field is a structure.
    590 	 Note the field offset is relative to the outermost struct.  */
    591       if (field->stag != NULL)
    592 	stag_add_field_symbols (field->stag, name,
    593 				field->offset,
    594 				rootsym, root_stag_name);
    595       field = field->next;
    596     }
    597 }
    598 
    599 /* Keep track of stag fields so that when structures are nested we can add the
    600    complete dereferencing symbols to the symbol table.  */
    601 
    602 static void
    603 stag_add_field (struct stag *parent,
    604 		const char *name,
    605 		bfd_vma offset,
    606 		struct stag *stag)
    607 {
    608   struct stag_field *sfield = xmalloc (sizeof (struct stag_field));
    609 
    610   memset (sfield, 0, sizeof (*sfield));
    611   sfield->name = strcpy (xmalloc (strlen (name) + 1), name);
    612   sfield->offset = offset;
    613   sfield->bitfield_offset = parent->current_bitfield_offset;
    614   sfield->stag = stag;
    615   if (parent->field == NULL)
    616     parent->field = sfield;
    617   else
    618     {
    619       struct stag_field *sf = parent->field;
    620       while (sf->next != NULL)
    621 	sf = sf->next;
    622       sf->next = sfield;
    623     }
    624   /* Only create a symbol for this field if the parent has no name.  */
    625   if (!strncmp (".fake", parent->name, 5))
    626     {
    627       symbolS *sym = symbol_new (name, absolute_section,
    628 				 (valueT) offset, &zero_address_frag);
    629       SF_SET_LOCAL (sym);
    630       symbol_table_insert (sym);
    631     }
    632 }
    633 
    634 /* [STAG] .struct       [OFFSET]
    635    Start defining structure offsets (symbols in absolute section).  */
    636 
    637 static void
    638 tic54x_struct (int arg)
    639 {
    640   int start_offset = 0;
    641   int is_union = arg;
    642 
    643   if (!current_stag)
    644     {
    645       /* Starting a new struct, switch to absolute section.  */
    646       stag_saved_seg = now_seg;
    647       stag_saved_subseg = now_subseg;
    648       subseg_set (absolute_section, 0);
    649     }
    650   /* Align the current pointer.  */
    651   else if (current_stag->current_bitfield_offset != 0)
    652     {
    653       ++abs_section_offset;
    654       current_stag->current_bitfield_offset = 0;
    655     }
    656 
    657   /* Offset expression is only meaningful for global .structs.  */
    658   if (!is_union)
    659     {
    660       /* Offset is ignored in inner structs.  */
    661       SKIP_WHITESPACE ();
    662       if (!is_end_of_line[(int) *input_line_pointer])
    663 	start_offset = get_absolute_expression ();
    664       else
    665 	start_offset = 0;
    666     }
    667 
    668   if (current_stag)
    669     {
    670       /* Nesting, link to outer one.  */
    671       current_stag->inner = (struct stag *) xmalloc (sizeof (struct stag));
    672       memset (current_stag->inner, 0, sizeof (struct stag));
    673       current_stag->inner->outer = current_stag;
    674       current_stag = current_stag->inner;
    675       if (start_offset)
    676 	as_warn (_("Offset on nested structures is ignored"));
    677       start_offset = abs_section_offset;
    678     }
    679   else
    680     {
    681       current_stag = (struct stag *) xmalloc (sizeof (struct stag));
    682       memset (current_stag, 0, sizeof (struct stag));
    683       abs_section_offset = start_offset;
    684     }
    685   current_stag->is_union = is_union;
    686 
    687   if (line_label == NULL)
    688     {
    689       static int struct_count = 0;
    690       char fake[] = ".fake_stagNNNNNNN";
    691       sprintf (fake, ".fake_stag%d", struct_count++);
    692       current_stag->sym = symbol_new (fake, absolute_section,
    693 				      (valueT) abs_section_offset,
    694 				      &zero_address_frag);
    695     }
    696   else
    697     {
    698       char label[strlen (S_GET_NAME (line_label)) + 1];
    699       strcpy (label, S_GET_NAME (line_label));
    700       current_stag->sym = symbol_new (label, absolute_section,
    701 				      (valueT) abs_section_offset,
    702 				      &zero_address_frag);
    703     }
    704   current_stag->name = S_GET_NAME (current_stag->sym);
    705   SF_SET_LOCAL (current_stag->sym);
    706   /* Nested .structs don't go into the symbol table.  */
    707   if (current_stag->outer == NULL)
    708     symbol_table_insert (current_stag->sym);
    709 
    710   line_label = NULL;
    711 }
    712 
    713 /* [LABEL] .endstruct
    714    finish defining structure offsets; optional LABEL's value will be the size
    715    of the structure.  */
    716 
    717 static void
    718 tic54x_endstruct (int is_union)
    719 {
    720   int size;
    721   const char *path =
    722     !strncmp (current_stag->name, ".fake", 5) ? "" : current_stag->name;
    723 
    724   if (!current_stag || current_stag->is_union != is_union)
    725     {
    726       as_bad (_(".end%s without preceding .%s"),
    727 	      is_union ? "union" : "struct",
    728 	      is_union ? "union" : "struct");
    729       ignore_rest_of_line ();
    730       return;
    731     }
    732 
    733   /* Align end of structures.  */
    734   if (current_stag->current_bitfield_offset)
    735     {
    736       ++abs_section_offset;
    737       current_stag->current_bitfield_offset = 0;
    738     }
    739 
    740   if (current_stag->is_union)
    741     size = current_stag->size;
    742   else
    743     size = abs_section_offset - S_GET_VALUE (current_stag->sym);
    744   if (line_label != NULL)
    745     {
    746       S_SET_VALUE (line_label, size);
    747       symbol_table_insert (line_label);
    748       line_label = NULL;
    749     }
    750 
    751   /* Union size has already been calculated.  */
    752   if (!current_stag->is_union)
    753     current_stag->size = size;
    754   /* Nested .structs don't get put in the stag table.  */
    755   if (current_stag->outer == NULL)
    756     {
    757       hash_insert (stag_hash, current_stag->name, current_stag);
    758       stag_add_field_symbols (current_stag, path,
    759 			      S_GET_VALUE (current_stag->sym),
    760 			      NULL, NULL);
    761     }
    762   current_stag = current_stag->outer;
    763 
    764   /* If this is a nested .struct/.union, add it as a field to the enclosing
    765      one.  otherwise, restore the section we were in.  */
    766   if (current_stag != NULL)
    767     {
    768       stag_add_field (current_stag, current_stag->inner->name,
    769 		      S_GET_VALUE (current_stag->inner->sym),
    770 		      current_stag->inner);
    771     }
    772   else
    773     subseg_set (stag_saved_seg, stag_saved_subseg);
    774 }
    775 
    776 /* [LABEL]      .tag    STAG
    777    Reference a structure within a structure, as a sized field with an optional
    778    label.
    779    If used outside of a .struct/.endstruct, overlays the given structure
    780    format on the existing allocated space.  */
    781 
    782 static void
    783 tic54x_tag (int ignore ATTRIBUTE_UNUSED)
    784 {
    785   char *name = input_line_pointer;
    786   int c = get_symbol_end ();
    787   struct stag *stag = (struct stag *) hash_find (stag_hash, name);
    788 
    789   if (!stag)
    790     {
    791       if (*name)
    792 	as_bad (_("Unrecognized struct/union tag '%s'"), name);
    793       else
    794 	as_bad (_(".tag requires a structure tag"));
    795       ignore_rest_of_line ();
    796       return;
    797     }
    798   if (line_label == NULL)
    799     {
    800       as_bad (_("Label required for .tag"));
    801       ignore_rest_of_line ();
    802       return;
    803     }
    804   else
    805     {
    806       char label[strlen (S_GET_NAME (line_label)) + 1];
    807 
    808       strcpy (label, S_GET_NAME (line_label));
    809       if (current_stag != NULL)
    810 	stag_add_field (current_stag, label,
    811 			abs_section_offset - S_GET_VALUE (current_stag->sym),
    812 			stag);
    813       else
    814 	{
    815 	  symbolS *sym = symbol_find (label);
    816 
    817 	  if (!sym)
    818 	    {
    819 	      as_bad (_(".tag target '%s' undefined"), label);
    820 	      ignore_rest_of_line ();
    821 	      return;
    822 	    }
    823 	  stag_add_field_symbols (stag, S_GET_NAME (sym),
    824 				  S_GET_VALUE (stag->sym), sym, stag->name);
    825 	}
    826     }
    827 
    828   /* Bump by the struct size, but only if we're within a .struct section.  */
    829   if (current_stag != NULL && !current_stag->is_union)
    830     abs_section_offset += stag->size;
    831 
    832   *input_line_pointer = c;
    833   demand_empty_rest_of_line ();
    834   line_label = NULL;
    835 }
    836 
    837 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
    838    .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
    839    and .word.  */
    840 
    841 static void
    842 tic54x_struct_field (int type)
    843 {
    844   int size;
    845   int count = 1;
    846   int new_bitfield_offset = 0;
    847   int field_align = current_stag->current_bitfield_offset != 0;
    848   int longword_align = 0;
    849 
    850   SKIP_WHITESPACE ();
    851   if (!is_end_of_line[(int) *input_line_pointer])
    852     count = get_absolute_expression ();
    853 
    854   switch (type)
    855     {
    856     case 'b':
    857     case 'B':
    858     case 'c':
    859     case 'C':
    860     case 'h':
    861     case 'H':
    862     case 'i':
    863     case 'I':
    864     case 's':
    865     case 'S':
    866     case 'w':
    867     case 'W':
    868     case '*': /* String.  */
    869       size = 1;
    870       break;
    871     case 'f':
    872     case 'l':
    873     case 'L':
    874       longword_align = 1;
    875       size = 2;
    876       break;
    877     case '.': /* Bitfield.  */
    878       size = 0;
    879       if (count < 1 || count > 32)
    880 	{
    881 	  as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count);
    882 	  ignore_rest_of_line ();
    883 	  return;
    884 	}
    885       if (current_stag->current_bitfield_offset + count > 16)
    886 	{
    887 	  /* Set the appropriate size and new field offset.  */
    888 	  if (count == 32)
    889 	    {
    890 	      size = 2;
    891 	      count = 1;
    892 	    }
    893 	  else if (count > 16)
    894 	    {
    895 	      size = 1;
    896 	      count = 1;
    897 	      new_bitfield_offset = count - 16;
    898 	    }
    899 	  else
    900 	    new_bitfield_offset = count;
    901 	}
    902       else
    903 	{
    904 	  field_align = 0;
    905 	  new_bitfield_offset = current_stag->current_bitfield_offset + count;
    906 	}
    907       break;
    908     default:
    909       as_bad (_("Unrecognized field type '%c'"), type);
    910       ignore_rest_of_line ();
    911       return;
    912     }
    913 
    914   if (field_align)
    915     {
    916       /* Align to the actual starting position of the field.  */
    917       current_stag->current_bitfield_offset = 0;
    918       ++abs_section_offset;
    919     }
    920   /* Align to longword boundary.  */
    921   if (longword_align && (abs_section_offset & 0x1))
    922     ++abs_section_offset;
    923 
    924   if (line_label == NULL)
    925     {
    926       static int fieldno = 0;
    927       char fake[] = ".fake_fieldNNNNN";
    928 
    929       sprintf (fake, ".fake_field%d", fieldno++);
    930       stag_add_field (current_stag, fake,
    931 		      abs_section_offset - S_GET_VALUE (current_stag->sym),
    932 		      NULL);
    933     }
    934   else
    935     {
    936       char label[strlen (S_GET_NAME (line_label) + 1)];
    937 
    938       strcpy (label, S_GET_NAME (line_label));
    939       stag_add_field (current_stag, label,
    940 		      abs_section_offset - S_GET_VALUE (current_stag->sym),
    941 		      NULL);
    942     }
    943 
    944   if (current_stag->is_union)
    945     {
    946       /* Note we treat the element as if it were an array of COUNT.  */
    947       if (current_stag->size < (unsigned) size * count)
    948 	current_stag->size = size * count;
    949     }
    950   else
    951     {
    952       abs_section_offset += (unsigned) size * count;
    953       current_stag->current_bitfield_offset = new_bitfield_offset;
    954     }
    955   line_label = NULL;
    956 }
    957 
    958 /* Handle .byte, .word. .int, .long and all variants.  */
    959 
    960 static void
    961 tic54x_cons (int type)
    962 {
    963   unsigned int c;
    964   int octets;
    965 
    966   /* If we're within a .struct construct, don't actually allocate space.  */
    967   if (current_stag != NULL)
    968     {
    969       tic54x_struct_field (type);
    970       return;
    971     }
    972 
    973 #ifdef md_flush_pending_output
    974   md_flush_pending_output ();
    975 #endif
    976 
    977   generate_lineno_debug ();
    978 
    979   /* Align long words to long word boundaries (4 octets).  */
    980   if (type == 'l' || type == 'L')
    981     {
    982       frag_align (2, 0, 2);
    983       /* If there's a label, assign it to the first allocated word.  */
    984       if (line_label != NULL)
    985 	{
    986 	  symbol_set_frag (line_label, frag_now);
    987 	  S_SET_VALUE (line_label, frag_now_fix ());
    988 	}
    989     }
    990 
    991   switch (type)
    992     {
    993     case 'l':
    994     case 'L':
    995     case 'x':
    996       octets = 4;
    997       break;
    998     case 'b':
    999     case 'B':
   1000     case 'c':
   1001     case 'C':
   1002       octets = 1;
   1003       break;
   1004     default:
   1005       octets = 2;
   1006       break;
   1007     }
   1008 
   1009   do
   1010     {
   1011       if (*input_line_pointer == '"')
   1012 	{
   1013 	  input_line_pointer++;
   1014 	  while (is_a_char (c = next_char_of_string ()))
   1015 	    tic54x_emit_char (c);
   1016 	  know (input_line_pointer[-1] == '\"');
   1017 	}
   1018       else
   1019 	{
   1020 	  expressionS expn;
   1021 
   1022 	  input_line_pointer = parse_expression (input_line_pointer, &expn);
   1023 	  if (expn.X_op == O_constant)
   1024 	    {
   1025 	      offsetT value = expn.X_add_number;
   1026 	      /* Truncate overflows.  */
   1027 	      switch (octets)
   1028 		{
   1029 		case 1:
   1030 		  if ((value > 0 && value > 0xFF)
   1031 		      || (value < 0 && value < - 0x100))
   1032 		    as_warn (_("Overflow in expression, truncated to 8 bits"));
   1033 		  break;
   1034 		case 2:
   1035 		  if ((value > 0 && value > 0xFFFF)
   1036 		      || (value < 0 && value < - 0x10000))
   1037 		    as_warn (_("Overflow in expression, truncated to 16 bits"));
   1038 		  break;
   1039 		}
   1040 	    }
   1041 	  if (expn.X_op != O_constant && octets < 2)
   1042 	    {
   1043 	      /* Disallow .byte with a non constant expression that will
   1044 		 require relocation.  */
   1045 	      as_bad (_("Relocatable values require at least WORD storage"));
   1046 	      ignore_rest_of_line ();
   1047 	      return;
   1048 	    }
   1049 
   1050 	  if (expn.X_op != O_constant
   1051 	      && amode == c_mode
   1052 	      && octets == 4)
   1053 	    {
   1054 	      /* FIXME -- at one point TI tools used to output REL16
   1055 		 relocations, but I don't think the latest tools do at all
   1056 		 The current tools output extended relocations regardless of
   1057 		 the addressing mode (I actually think that ".c_mode" is
   1058 		 totally ignored in the latest tools).  */
   1059 	      amode = far_mode;
   1060 	      emitting_long = 1;
   1061 	      emit_expr (&expn, 4);
   1062 	      emitting_long = 0;
   1063 	      amode = c_mode;
   1064 	    }
   1065 	  else
   1066 	    {
   1067 	      emitting_long = octets == 4;
   1068 	      emit_expr (&expn, (octets == 1) ? 2 : octets);
   1069 	      emitting_long = 0;
   1070 	    }
   1071 	}
   1072     }
   1073   while (*input_line_pointer++ == ',');
   1074 
   1075   input_line_pointer--;		/* Put terminator back into stream.  */
   1076   demand_empty_rest_of_line ();
   1077 }
   1078 
   1079 /* .global <symbol>[,...,<symbolN>]
   1080    .def    <symbol>[,...,<symbolN>]
   1081    .ref    <symbol>[,...,<symbolN>]
   1082 
   1083    These all identify global symbols.
   1084 
   1085    .def means the symbol is defined in the current module and can be accessed
   1086    by other files.  The symbol should be placed in the symbol table.
   1087 
   1088    .ref means the symbol is used in the current module but defined in another
   1089    module.  The linker is to resolve this symbol's definition at link time.
   1090 
   1091    .global should act as a .ref or .def, as needed.
   1092 
   1093    global, def and ref all have symbol storage classes of C_EXT.
   1094 
   1095    I can't identify any difference in how the "other" c54x assembler treats
   1096    these, so we ignore the type here.  */
   1097 
   1098 void
   1099 tic54x_global (int type)
   1100 {
   1101   char *name;
   1102   int c;
   1103   symbolS *symbolP;
   1104 
   1105   if (type == 'r')
   1106     as_warn (_("Use of .def/.ref is deprecated.  Use .global instead"));
   1107 
   1108   ILLEGAL_WITHIN_STRUCT ();
   1109 
   1110   do
   1111     {
   1112       name = input_line_pointer;
   1113       c = get_symbol_end ();
   1114       symbolP = symbol_find_or_make (name);
   1115 
   1116       *input_line_pointer = c;
   1117       S_SET_STORAGE_CLASS (symbolP, C_EXT);
   1118       if (c == ',')
   1119 	{
   1120 	  input_line_pointer++;
   1121 	  if (is_end_of_line[(int) *input_line_pointer])
   1122 	    c = *input_line_pointer;
   1123 	}
   1124     }
   1125   while (c == ',');
   1126 
   1127   demand_empty_rest_of_line ();
   1128 }
   1129 
   1130 /* Remove the symbol from the local label hash lookup.  */
   1131 
   1132 static void
   1133 tic54x_remove_local_label (const char *key, void *value ATTRIBUTE_UNUSED)
   1134 {
   1135   void *elem = hash_delete (local_label_hash[macro_level], key, FALSE);
   1136   free (elem);
   1137 }
   1138 
   1139 /* Reset all local labels.  */
   1140 
   1141 static void
   1142 tic54x_clear_local_labels (int ignored ATTRIBUTE_UNUSED)
   1143 {
   1144   hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label);
   1145 }
   1146 
   1147 /* .text
   1148    .data
   1149    .sect "section name"
   1150 
   1151    Initialized section
   1152    make sure local labels get cleared when changing sections
   1153 
   1154    ARG is 't' for text, 'd' for data, or '*' for a named section
   1155 
   1156    For compatibility, '*' sections are SEC_CODE if instructions are
   1157    encountered, or SEC_DATA if not.
   1158 */
   1159 
   1160 static void
   1161 tic54x_sect (int arg)
   1162 {
   1163   ILLEGAL_WITHIN_STRUCT ();
   1164 
   1165   /* Local labels are cleared when changing sections.  */
   1166   tic54x_clear_local_labels (0);
   1167 
   1168   if (arg == 't')
   1169     s_text (0);
   1170   else if (arg == 'd')
   1171     s_data (0);
   1172   else
   1173     {
   1174       char *name = NULL;
   1175       int len;
   1176 
   1177       /* If there are quotes, remove them.  */
   1178       if (*input_line_pointer == '"')
   1179 	{
   1180 	  name = demand_copy_C_string (&len);
   1181 	  demand_empty_rest_of_line ();
   1182 	  name = strcpy (xmalloc (len + 10), name);
   1183 	}
   1184       else
   1185 	{
   1186 	  int c;
   1187 	  name = input_line_pointer;
   1188 	  c = get_symbol_end ();
   1189           len = strlen(name);
   1190 	  name = strcpy (xmalloc (len + 10), name);
   1191 	  *input_line_pointer = c;
   1192 	  demand_empty_rest_of_line ();
   1193 	}
   1194       /* Make sure all named initialized sections flagged properly.  If we
   1195          encounter instructions, we'll flag it with SEC_CODE as well.  */
   1196       strcat (name, ",\"w\"\n");
   1197       input_scrub_insert_line (name);
   1198       obj_coff_section (0);
   1199 
   1200       /* If there was a line label, make sure that it gets assigned the proper
   1201 	 section.  This is for compatibility, even though the actual behavior
   1202 	 is not explicitly defined.  For consistency, we make .sect behave
   1203 	 like .usect, since that is probably what people expect.  */
   1204       if (line_label != NULL)
   1205 	{
   1206 	  S_SET_SEGMENT (line_label, now_seg);
   1207 	  symbol_set_frag (line_label, frag_now);
   1208 	  S_SET_VALUE (line_label, frag_now_fix ());
   1209 	  if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
   1210 	    S_SET_STORAGE_CLASS (line_label, C_LABEL);
   1211 	}
   1212     }
   1213 }
   1214 
   1215 /* [symbol] .space space_in_bits
   1216    [symbol] .bes space_in_bits
   1217    BES puts the symbol at the *last* word allocated
   1218 
   1219    cribbed from s_space.  */
   1220 
   1221 static void
   1222 tic54x_space (int arg)
   1223 {
   1224   expressionS expn;
   1225   char *p = 0;
   1226   int octets = 0;
   1227   long words;
   1228   int bits_per_byte = (OCTETS_PER_BYTE * 8);
   1229   int bit_offset = 0;
   1230   symbolS *label = line_label;
   1231   int bes = arg;
   1232 
   1233   ILLEGAL_WITHIN_STRUCT ();
   1234 
   1235 #ifdef md_flush_pending_output
   1236   md_flush_pending_output ();
   1237 #endif
   1238 
   1239   /* Read the bit count.  */
   1240   expression (&expn);
   1241 
   1242   /* Some expressions are unresolvable until later in the assembly pass;
   1243      postpone until relaxation/fixup.  we also have to postpone if a previous
   1244      partial allocation has not been completed yet.  */
   1245   if (expn.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
   1246     {
   1247       struct bit_info *bi = xmalloc (sizeof (struct bit_info));
   1248 
   1249       bi->seg = now_seg;
   1250       bi->type = bes;
   1251       bi->sym = label;
   1252       p = frag_var (rs_machine_dependent,
   1253 		    65536 * 2, 1, (relax_substateT) 0,
   1254 		    make_expr_symbol (&expn), (offsetT) 0,
   1255 		    (char *) bi);
   1256       if (p)
   1257 	*p = 0;
   1258 
   1259       return;
   1260     }
   1261 
   1262   /* Reduce the required size by any bit offsets currently left over
   1263      from a previous .space/.bes/.field directive.  */
   1264   bit_offset = frag_now->tc_frag_data;
   1265   if (bit_offset != 0 && bit_offset < 16)
   1266     {
   1267       int spare_bits = bits_per_byte - bit_offset;
   1268 
   1269       if (spare_bits >= expn.X_add_number)
   1270 	{
   1271 	  /* Don't have to do anything; sufficient bits have already been
   1272 	     allocated; just point the label to the right place.  */
   1273 	  if (label != NULL)
   1274 	    {
   1275 	      symbol_set_frag (label, frag_now);
   1276 	      S_SET_VALUE (label, frag_now_fix () - 1);
   1277 	      label = NULL;
   1278 	    }
   1279 	  frag_now->tc_frag_data += expn.X_add_number;
   1280 	  goto getout;
   1281 	}
   1282       expn.X_add_number -= spare_bits;
   1283       /* Set the label to point to the first word allocated, which in this
   1284 	 case is the previous word, which was only partially filled.  */
   1285       if (!bes && label != NULL)
   1286 	{
   1287 	  symbol_set_frag (label, frag_now);
   1288 	  S_SET_VALUE (label, frag_now_fix () - 1);
   1289 	  label = NULL;
   1290 	}
   1291     }
   1292   /* Convert bits to bytes/words and octets, rounding up.  */
   1293   words = ((expn.X_add_number + bits_per_byte - 1) / bits_per_byte);
   1294   /* How many do we have left over?  */
   1295   bit_offset = expn.X_add_number % bits_per_byte;
   1296   octets = words * OCTETS_PER_BYTE;
   1297   if (octets < 0)
   1298     {
   1299       as_warn (_(".space/.bes repeat count is negative, ignored"));
   1300       goto getout;
   1301     }
   1302   else if (octets == 0)
   1303     {
   1304       as_warn (_(".space/.bes repeat count is zero, ignored"));
   1305       goto getout;
   1306     }
   1307 
   1308   /* If we are in the absolute section, just bump the offset.  */
   1309   if (now_seg == absolute_section)
   1310     {
   1311       abs_section_offset += words;
   1312       if (bes && label != NULL)
   1313 	S_SET_VALUE (label, abs_section_offset - 1);
   1314       frag_now->tc_frag_data = bit_offset;
   1315       goto getout;
   1316     }
   1317 
   1318   if (!need_pass_2)
   1319     p = frag_var (rs_fill, 1, 1,
   1320 		  (relax_substateT) 0, (symbolS *) 0,
   1321 		  (offsetT) octets, (char *) 0);
   1322 
   1323   /* Make note of how many bits of this word we've allocated so far.  */
   1324   frag_now->tc_frag_data = bit_offset;
   1325 
   1326   /* .bes puts label at *last* word allocated.  */
   1327   if (bes && label != NULL)
   1328     {
   1329       symbol_set_frag (label, frag_now);
   1330       S_SET_VALUE (label, frag_now_fix () - 1);
   1331     }
   1332 
   1333   if (p)
   1334     *p = 0;
   1335 
   1336  getout:
   1337 
   1338   demand_empty_rest_of_line ();
   1339 }
   1340 
   1341 /* [symbol] .usect "section-name", size-in-words
   1342 		   [, [blocking-flag] [, alignment-flag]]
   1343 
   1344    Uninitialized section.
   1345    Non-zero blocking means that if the section would cross a page (128-word)
   1346    boundary, it will be page-aligned.
   1347    Non-zero alignment aligns on a longword boundary.
   1348 
   1349    Has no effect on the current section.  */
   1350 
   1351 static void
   1352 tic54x_usect (int x ATTRIBUTE_UNUSED)
   1353 {
   1354   char c;
   1355   char *name;
   1356   char *section_name;
   1357   char *p;
   1358   segT seg;
   1359   int size, blocking_flag, alignment_flag;
   1360   segT current_seg;
   1361   subsegT current_subseg;
   1362   flagword flags;
   1363 
   1364   ILLEGAL_WITHIN_STRUCT ();
   1365 
   1366   current_seg = now_seg;	/* Save current seg.  */
   1367   current_subseg = now_subseg;	/* Save current subseg.  */
   1368 
   1369   if (*input_line_pointer == '"')
   1370     input_line_pointer++;
   1371   section_name = input_line_pointer;
   1372   c = get_symbol_end ();	/* Get terminator.  */
   1373   input_line_pointer++;		/* Skip null symbol terminator.  */
   1374   name = xmalloc (input_line_pointer - section_name + 1);
   1375   strcpy (name, section_name);
   1376 
   1377   if (*input_line_pointer == ',')
   1378     ++input_line_pointer;
   1379   else if (c != ',')
   1380     {
   1381       as_bad (_("Missing size argument"));
   1382       ignore_rest_of_line ();
   1383       return;
   1384     }
   1385 
   1386   size = get_absolute_expression ();
   1387 
   1388   /* Read a possibly present third argument (blocking flag).  */
   1389   if (*input_line_pointer == ',')
   1390     {
   1391       ++input_line_pointer;
   1392       if (*input_line_pointer != ',')
   1393 	blocking_flag = get_absolute_expression ();
   1394       else
   1395 	blocking_flag = 0;
   1396 
   1397       /* Read a possibly present fourth argument (alignment flag).  */
   1398       if (*input_line_pointer == ',')
   1399 	{
   1400 	  ++input_line_pointer;
   1401 	  alignment_flag = get_absolute_expression ();
   1402 	}
   1403       else
   1404 	alignment_flag = 0;
   1405     }
   1406   else
   1407     blocking_flag = alignment_flag = 0;
   1408 
   1409   seg = subseg_new (name, 0);
   1410   flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC;
   1411 
   1412   if (alignment_flag)
   1413     {
   1414       /* s_align eats end of line; restore it.  */
   1415       s_align_bytes (4);
   1416       --input_line_pointer;
   1417     }
   1418 
   1419   if (line_label != NULL)
   1420     {
   1421       S_SET_SEGMENT (line_label, seg);
   1422       symbol_set_frag (line_label, frag_now);
   1423       S_SET_VALUE (line_label, frag_now_fix ());
   1424       /* Set scl to label, since that's what TI does.  */
   1425       if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
   1426 	S_SET_STORAGE_CLASS (line_label, C_LABEL);
   1427     }
   1428 
   1429   seg_info (seg)->bss = 1;	/* Uninitialized data.  */
   1430 
   1431   p = frag_var (rs_fill, 1, 1,
   1432 		(relax_substateT) 0, (symbolS *) line_label,
   1433 		size * OCTETS_PER_BYTE, (char *) 0);
   1434   *p = 0;
   1435 
   1436   if (blocking_flag)
   1437     flags |= SEC_TIC54X_BLOCK;
   1438 
   1439   if (!bfd_set_section_flags (stdoutput, seg, flags))
   1440     as_warn (_("Error setting flags for \"%s\": %s"), name,
   1441 	     bfd_errmsg (bfd_get_error ()));
   1442 
   1443   subseg_set (current_seg, current_subseg);	/* Restore current seg.  */
   1444   demand_empty_rest_of_line ();
   1445 }
   1446 
   1447 static enum cpu_version
   1448 lookup_version (const char *ver)
   1449 {
   1450   enum cpu_version version = VNONE;
   1451 
   1452   if (ver[0] == '5' && ver[1] == '4')
   1453     {
   1454       if (strlen (ver) == 3
   1455 	  && (ver[2] == '1' || ver[2] == '2' || ver[2] == '3'
   1456 	      || ver[2] == '5' || ver[2] == '8' || ver[2] == '9'))
   1457 	version = ver[2] - '0';
   1458       else if (strlen (ver) == 5
   1459 	       && TOUPPER (ver[3]) == 'L'
   1460 	       && TOUPPER (ver[4]) == 'P'
   1461 	       && (ver[2] == '5' || ver[2] == '6'))
   1462 	version = ver[2] - '0' + 10;
   1463     }
   1464 
   1465   return version;
   1466 }
   1467 
   1468 static void
   1469 set_cpu (enum cpu_version version)
   1470 {
   1471   cpu = version;
   1472   if (version == V545LP || version == V546LP)
   1473     {
   1474       symbolS *symbolP = symbol_new ("__allow_lp", absolute_section,
   1475 				     (valueT) 1, &zero_address_frag);
   1476       SF_SET_LOCAL (symbolP);
   1477       symbol_table_insert (symbolP);
   1478     }
   1479 }
   1480 
   1481 /* .version cpu-version
   1482    cpu-version may be one of the following:
   1483    541
   1484    542
   1485    543
   1486    545
   1487    545LP
   1488    546LP
   1489    548
   1490    549
   1491 
   1492    This is for compatibility only.  It currently has no affect on assembly.  */
   1493 static int cpu_needs_set = 1;
   1494 
   1495 static void
   1496 tic54x_version (int x ATTRIBUTE_UNUSED)
   1497 {
   1498   enum cpu_version version = VNONE;
   1499   enum cpu_version old_version = cpu;
   1500   int c;
   1501   char *ver;
   1502 
   1503   ILLEGAL_WITHIN_STRUCT ();
   1504 
   1505   SKIP_WHITESPACE ();
   1506   ver = input_line_pointer;
   1507   while (!is_end_of_line[(int) *input_line_pointer])
   1508     ++input_line_pointer;
   1509   c = *input_line_pointer;
   1510   *input_line_pointer = 0;
   1511 
   1512   version = lookup_version (ver);
   1513 
   1514   if (cpu != VNONE && cpu != version)
   1515     as_warn (_("CPU version has already been set"));
   1516 
   1517   if (version == VNONE)
   1518     {
   1519       as_bad (_("Unrecognized version '%s'"), ver);
   1520       ignore_rest_of_line ();
   1521       return;
   1522     }
   1523   else if (assembly_begun && version != old_version)
   1524     {
   1525       as_bad (_("Changing of CPU version on the fly not supported"));
   1526       ignore_rest_of_line ();
   1527       return;
   1528     }
   1529 
   1530   set_cpu (version);
   1531 
   1532   *input_line_pointer = c;
   1533   demand_empty_rest_of_line ();
   1534 }
   1535 
   1536 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble.  */
   1537 
   1538 static void
   1539 tic54x_float_cons (int type)
   1540 {
   1541   if (current_stag != 0)
   1542     tic54x_struct_field ('f');
   1543 
   1544 #ifdef md_flush_pending_output
   1545   md_flush_pending_output ();
   1546 #endif
   1547 
   1548   /* Align to long word boundary (4 octets) unless it's ".xfloat".  */
   1549   if (type != 'x')
   1550     {
   1551       frag_align (2, 0, 2);
   1552       /* If there's a label, assign it to the first allocated word.  */
   1553       if (line_label != NULL)
   1554 	{
   1555 	  symbol_set_frag (line_label, frag_now);
   1556 	  S_SET_VALUE (line_label, frag_now_fix ());
   1557 	}
   1558     }
   1559 
   1560   float_cons ('f');
   1561 }
   1562 
   1563 /* The argument is capitalized if it should be zero-terminated
   1564    's' is normal string with upper 8-bits zero-filled, 'p' is packed.
   1565    Code copied from stringer, and slightly modified so that strings are packed
   1566    and encoded into the correct octets.  */
   1567 
   1568 static void
   1569 tic54x_stringer (int type)
   1570 {
   1571   unsigned int c;
   1572   int append_zero = type == 'S' || type == 'P';
   1573   int packed = type == 'p' || type == 'P';
   1574   int last_char = -1; /* Packed strings need two bytes at a time to encode.  */
   1575 
   1576   if (current_stag != NULL)
   1577     {
   1578       tic54x_struct_field ('*');
   1579       return;
   1580     }
   1581 
   1582 #ifdef md_flush_pending_output
   1583   md_flush_pending_output ();
   1584 #endif
   1585 
   1586   c = ',';			/* Do loop.  */
   1587   while (c == ',')
   1588     {
   1589       SKIP_WHITESPACE ();
   1590       switch (*input_line_pointer)
   1591 	{
   1592 	default:
   1593 	  {
   1594 	    unsigned short value = get_absolute_expression ();
   1595 	    FRAG_APPEND_1_CHAR ( value       & 0xFF);
   1596 	    FRAG_APPEND_1_CHAR ((value >> 8) & 0xFF);
   1597 	    break;
   1598 	  }
   1599 	case '\"':
   1600 	  ++input_line_pointer;	/* -> 1st char of string.  */
   1601 	  while (is_a_char (c = next_char_of_string ()))
   1602 	    {
   1603 	      if (!packed)
   1604 		{
   1605 		  FRAG_APPEND_1_CHAR (c);
   1606 		  FRAG_APPEND_1_CHAR (0);
   1607 		}
   1608 	      else
   1609 		{
   1610 		  /* Packed strings are filled MS octet first.  */
   1611 		  if (last_char == -1)
   1612 		    last_char = c;
   1613 		  else
   1614 		    {
   1615 		      FRAG_APPEND_1_CHAR (c);
   1616 		      FRAG_APPEND_1_CHAR (last_char);
   1617 		      last_char = -1;
   1618 		    }
   1619 		}
   1620 	    }
   1621 	  if (append_zero)
   1622 	    {
   1623 	      if (packed && last_char != -1)
   1624 		{
   1625 		  FRAG_APPEND_1_CHAR (0);
   1626 		  FRAG_APPEND_1_CHAR (last_char);
   1627 		  last_char = -1;
   1628 		}
   1629 	      else
   1630 		{
   1631 		  FRAG_APPEND_1_CHAR (0);
   1632 		  FRAG_APPEND_1_CHAR (0);
   1633 		}
   1634 	    }
   1635 	  know (input_line_pointer[-1] == '\"');
   1636 	  break;
   1637 	}
   1638       SKIP_WHITESPACE ();
   1639       c = *input_line_pointer;
   1640       if (!is_end_of_line[c])
   1641 	++input_line_pointer;
   1642     }
   1643 
   1644   /* Finish up any leftover packed string.  */
   1645   if (packed && last_char != -1)
   1646     {
   1647       FRAG_APPEND_1_CHAR (0);
   1648       FRAG_APPEND_1_CHAR (last_char);
   1649     }
   1650   demand_empty_rest_of_line ();
   1651 }
   1652 
   1653 static void
   1654 tic54x_p2align (int arg ATTRIBUTE_UNUSED)
   1655 {
   1656   as_bad (_("p2align not supported on this target"));
   1657 }
   1658 
   1659 static void
   1660 tic54x_align_words (int arg)
   1661 {
   1662   /* Only ".align" with no argument is allowed within .struct/.union.  */
   1663   int count = arg;
   1664 
   1665   if (!is_end_of_line[(int) *input_line_pointer])
   1666     {
   1667       if (arg == 2)
   1668 	as_warn (_("Argument to .even ignored"));
   1669       else
   1670 	count = get_absolute_expression ();
   1671     }
   1672 
   1673   if (current_stag != NULL && arg == 128)
   1674     {
   1675       if (current_stag->current_bitfield_offset != 0)
   1676 	{
   1677 	  current_stag->current_bitfield_offset = 0;
   1678 	  ++abs_section_offset;
   1679 	}
   1680       demand_empty_rest_of_line ();
   1681       return;
   1682     }
   1683 
   1684   ILLEGAL_WITHIN_STRUCT ();
   1685 
   1686   s_align_bytes (count << 1);
   1687 }
   1688 
   1689 /* Initialize multiple-bit fields withing a single word of memory.  */
   1690 
   1691 static void
   1692 tic54x_field (int ignore ATTRIBUTE_UNUSED)
   1693 {
   1694   expressionS expn;
   1695   int size = 16;
   1696   char *p;
   1697   valueT value;
   1698   symbolS *label = line_label;
   1699 
   1700   if (current_stag != NULL)
   1701     {
   1702       tic54x_struct_field ('.');
   1703       return;
   1704     }
   1705 
   1706   input_line_pointer = parse_expression (input_line_pointer, &expn);
   1707 
   1708   if (*input_line_pointer == ',')
   1709     {
   1710       ++input_line_pointer;
   1711       size = get_absolute_expression ();
   1712       if (size < 1 || size > 32)
   1713 	{
   1714 	  as_bad (_("Invalid field size, must be from 1 to 32"));
   1715 	  ignore_rest_of_line ();
   1716 	  return;
   1717 	}
   1718     }
   1719 
   1720   /* Truncate values to the field width.  */
   1721   if (expn.X_op != O_constant)
   1722     {
   1723       /* If the expression value is relocatable, the field size *must*
   1724          be 16.  */
   1725       if (size != 16)
   1726 	{
   1727 	  as_bad (_("field size must be 16 when value is relocatable"));
   1728 	  ignore_rest_of_line ();
   1729 	  return;
   1730 	}
   1731 
   1732       frag_now->tc_frag_data = 0;
   1733       emit_expr (&expn, 2);
   1734     }
   1735   else
   1736     {
   1737       unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1;
   1738 
   1739       value = expn.X_add_number;
   1740       expn.X_add_number &= fmask;
   1741       if (value != (valueT) expn.X_add_number)
   1742 	as_warn (_("field value truncated"));
   1743       value = expn.X_add_number;
   1744       /* Bits are stored MS first.  */
   1745       while (size >= 16)
   1746 	{
   1747 	  frag_now->tc_frag_data = 0;
   1748 	  p = frag_more (2);
   1749 	  md_number_to_chars (p, (value >> (size - 16)) & 0xFFFF, 2);
   1750 	  size -= 16;
   1751 	}
   1752       if (size > 0)
   1753 	{
   1754 	  int bit_offset = frag_bit_offset (frag_now, now_seg);
   1755 
   1756 	  fragS *alloc_frag = bit_offset_frag (frag_now, now_seg);
   1757 	  if (bit_offset == -1)
   1758 	    {
   1759 	      struct bit_info *bi = xmalloc (sizeof (struct bit_info));
   1760 	      /* We don't know the previous offset at this time, so store the
   1761 		 info we need and figure it out later.  */
   1762 	      expressionS size_exp;
   1763 
   1764 	      size_exp.X_op = O_constant;
   1765 	      size_exp.X_add_number = size;
   1766 	      bi->seg = now_seg;
   1767 	      bi->type = TYPE_FIELD;
   1768 	      bi->value = value;
   1769 	      p = frag_var (rs_machine_dependent,
   1770 			    4, 1, (relax_substateT) 0,
   1771 			    make_expr_symbol (&size_exp), (offsetT) 0,
   1772 			    (char *) bi);
   1773 	      goto getout;
   1774 	    }
   1775 	  else if (bit_offset == 0 || bit_offset + size > 16)
   1776 	    {
   1777 	      /* Align a new field.  */
   1778 	      p = frag_more (2);
   1779 	      frag_now->tc_frag_data = 0;
   1780 	      alloc_frag = frag_now;
   1781 	    }
   1782 	  else
   1783 	    {
   1784 	      /* Put the new value entirely within the existing one.  */
   1785 	      p = alloc_frag == frag_now ?
   1786 		frag_now->fr_literal + frag_now_fix_octets () - 2 :
   1787 		alloc_frag->fr_literal;
   1788 	      if (label != NULL)
   1789 		{
   1790 		  symbol_set_frag (label, alloc_frag);
   1791 		  if (alloc_frag == frag_now)
   1792 		    S_SET_VALUE (label, frag_now_fix () - 1);
   1793 		  label = NULL;
   1794 		}
   1795 	    }
   1796 	  value <<= 16 - alloc_frag->tc_frag_data - size;
   1797 
   1798 	  /* OR in existing value.  */
   1799 	  if (alloc_frag->tc_frag_data)
   1800 	    value |= ((unsigned short) p[1] << 8) | p[0];
   1801 	  md_number_to_chars (p, value, 2);
   1802 	  alloc_frag->tc_frag_data += size;
   1803 	  if (alloc_frag->tc_frag_data == 16)
   1804 	    alloc_frag->tc_frag_data = 0;
   1805 	}
   1806     }
   1807  getout:
   1808   demand_empty_rest_of_line ();
   1809 }
   1810 
   1811 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
   1812    available yet.  seg_info ()->bss is the next best thing.  */
   1813 
   1814 static int
   1815 tic54x_initialized_section (segT seg)
   1816 {
   1817   return !seg_info (seg)->bss;
   1818 }
   1819 
   1820 /* .clink ["section name"]
   1821 
   1822    Marks the section as conditionally linked (link only if contents are
   1823    referenced elsewhere.
   1824    Without a name, refers to the current initialized section.
   1825    Name is required for uninitialized sections.  */
   1826 
   1827 static void
   1828 tic54x_clink (int ignored ATTRIBUTE_UNUSED)
   1829 {
   1830   segT seg = now_seg;
   1831 
   1832   ILLEGAL_WITHIN_STRUCT ();
   1833 
   1834   if (*input_line_pointer == '\"')
   1835     {
   1836       char *section_name = ++input_line_pointer;
   1837       char *name;
   1838 
   1839       while (is_a_char (next_char_of_string ()))
   1840 	;
   1841       know (input_line_pointer[-1] == '\"');
   1842       input_line_pointer[-1] = 0;
   1843       name = xmalloc (input_line_pointer - section_name + 1);
   1844       strcpy (name, section_name);
   1845 
   1846       seg = bfd_get_section_by_name (stdoutput, name);
   1847       if (seg == NULL)
   1848 	{
   1849 	  as_bad (_("Unrecognized section '%s'"), section_name);
   1850 	  ignore_rest_of_line ();
   1851 	  return;
   1852 	}
   1853     }
   1854   else
   1855     {
   1856       if (!tic54x_initialized_section (seg))
   1857 	{
   1858 	  as_bad (_("Current section is unitialized, "
   1859 		    "section name required for .clink"));
   1860 	  ignore_rest_of_line ();
   1861 	  return;
   1862 	}
   1863     }
   1864 
   1865   seg->flags |= SEC_TIC54X_CLINK;
   1866 
   1867   demand_empty_rest_of_line ();
   1868 }
   1869 
   1870 /* Change the default include directory to be the current source file's
   1871    directory, instead of the current working directory.  If DOT is non-zero,
   1872    set to "." instead.  */
   1873 
   1874 static void
   1875 tic54x_set_default_include (int dot)
   1876 {
   1877   char *dir = ".";
   1878   char *tmp = NULL;
   1879 
   1880   if (!dot)
   1881     {
   1882       char *curfile;
   1883       unsigned lineno;
   1884 
   1885       as_where (&curfile, &lineno);
   1886       dir = strcpy (xmalloc (strlen (curfile) + 1), curfile);
   1887       tmp = strrchr (dir, '/');
   1888     }
   1889   if (tmp != NULL)
   1890     {
   1891       int len;
   1892 
   1893       *tmp = '\0';
   1894       len = strlen (dir);
   1895       if (include_dir_count == 0)
   1896 	{
   1897 	  include_dirs = (char **) xmalloc (sizeof (*include_dirs));
   1898 	  include_dir_count = 1;
   1899 	}
   1900       include_dirs[0] = dir;
   1901       if (len > include_dir_maxlen)
   1902 	include_dir_maxlen = len;
   1903     }
   1904   else if (include_dirs != NULL)
   1905     include_dirs[0] = ".";
   1906 }
   1907 
   1908 /* .include "filename" | filename
   1909    .copy    "filename" | filename
   1910 
   1911    FIXME 'include' file should be omitted from any output listing,
   1912      'copy' should be included in any output listing
   1913    FIXME -- prevent any included files from changing listing (compat only)
   1914    FIXME -- need to include source file directory in search path; what's a
   1915       good way to do this?
   1916 
   1917    Entering/exiting included/copied file clears all local labels.  */
   1918 
   1919 static void
   1920 tic54x_include (int ignored ATTRIBUTE_UNUSED)
   1921 {
   1922   char newblock[] = " .newblock\n";
   1923   char *filename;
   1924   char *input;
   1925   int len, c = -1;
   1926 
   1927   ILLEGAL_WITHIN_STRUCT ();
   1928 
   1929   SKIP_WHITESPACE ();
   1930 
   1931   if (*input_line_pointer == '"')
   1932     {
   1933       filename = demand_copy_C_string (&len);
   1934       demand_empty_rest_of_line ();
   1935     }
   1936   else
   1937     {
   1938       filename = input_line_pointer;
   1939       while (!is_end_of_line[(int) *input_line_pointer])
   1940 	++input_line_pointer;
   1941       c = *input_line_pointer;
   1942       *input_line_pointer = '\0';
   1943       filename = strcpy (xmalloc (strlen (filename) + 1), filename);
   1944       *input_line_pointer = c;
   1945       demand_empty_rest_of_line ();
   1946     }
   1947   /* Insert a partial line with the filename (for the sake of s_include)
   1948      and a .newblock.
   1949      The included file will be inserted before the newblock, so that the
   1950      newblock is executed after the included file is processed.  */
   1951   input = xmalloc (sizeof (newblock) + strlen (filename) + 4);
   1952   sprintf (input, "\"%s\"\n%s", filename, newblock);
   1953   input_scrub_insert_line (input);
   1954 
   1955   tic54x_clear_local_labels (0);
   1956 
   1957   tic54x_set_default_include (0);
   1958 
   1959   s_include (0);
   1960 }
   1961 
   1962 static void
   1963 tic54x_message (int type)
   1964 {
   1965   char *msg;
   1966   char c;
   1967   int len;
   1968 
   1969   ILLEGAL_WITHIN_STRUCT ();
   1970 
   1971   if (*input_line_pointer == '"')
   1972     msg = demand_copy_C_string (&len);
   1973   else
   1974     {
   1975       msg = input_line_pointer;
   1976       while (!is_end_of_line[(int) *input_line_pointer])
   1977 	++input_line_pointer;
   1978       c = *input_line_pointer;
   1979       *input_line_pointer = 0;
   1980       msg = strcpy (xmalloc (strlen (msg) + 1), msg);
   1981       *input_line_pointer = c;
   1982     }
   1983 
   1984   switch (type)
   1985     {
   1986     case 'm':
   1987       as_tsktsk ("%s", msg);
   1988       break;
   1989     case 'w':
   1990       as_warn ("%s", msg);
   1991       break;
   1992     case 'e':
   1993       as_bad ("%s", msg);
   1994       break;
   1995     }
   1996 
   1997   demand_empty_rest_of_line ();
   1998 }
   1999 
   2000 /* .label <symbol>
   2001    Define a special symbol that refers to the loadtime address rather than the
   2002    runtime address within the current section.
   2003 
   2004    This symbol gets a special storage class so that when it is resolved, it is
   2005    resolved relative to the load address (lma) of the section rather than the
   2006    run address (vma).  */
   2007 
   2008 static void
   2009 tic54x_label (int ignored ATTRIBUTE_UNUSED)
   2010 {
   2011   char *name = input_line_pointer;
   2012   symbolS *symbolP;
   2013   int c;
   2014 
   2015   ILLEGAL_WITHIN_STRUCT ();
   2016 
   2017   c = get_symbol_end ();
   2018   symbolP = colon (name);
   2019   S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
   2020 
   2021   *input_line_pointer = c;
   2022   demand_empty_rest_of_line ();
   2023 }
   2024 
   2025 /* .mmregs
   2026    Install all memory-mapped register names into the symbol table as
   2027    absolute local symbols.  */
   2028 
   2029 static void
   2030 tic54x_mmregs (int ignored ATTRIBUTE_UNUSED)
   2031 {
   2032   symbol *sym;
   2033 
   2034   ILLEGAL_WITHIN_STRUCT ();
   2035 
   2036   for (sym = (symbol *) mmregs; sym->name; sym++)
   2037     {
   2038       symbolS *symbolP = symbol_new (sym->name, absolute_section,
   2039 				     (valueT) sym->value, &zero_address_frag);
   2040       SF_SET_LOCAL (symbolP);
   2041       symbol_table_insert (symbolP);
   2042     }
   2043 }
   2044 
   2045 /* .loop [count]
   2046    Count defaults to 1024.  */
   2047 
   2048 static void
   2049 tic54x_loop (int count)
   2050 {
   2051   ILLEGAL_WITHIN_STRUCT ();
   2052 
   2053   SKIP_WHITESPACE ();
   2054   if (!is_end_of_line[(int) *input_line_pointer])
   2055     count = get_absolute_expression ();
   2056 
   2057   do_repeat (count, "LOOP", "ENDLOOP");
   2058 }
   2059 
   2060 /* Normally, endloop gets eaten by the preceding loop.  */
   2061 
   2062 static void
   2063 tic54x_endloop (int ignore ATTRIBUTE_UNUSED)
   2064 {
   2065   as_bad (_("ENDLOOP without corresponding LOOP"));
   2066   ignore_rest_of_line ();
   2067 }
   2068 
   2069 /* .break [condition].  */
   2070 
   2071 static void
   2072 tic54x_break (int ignore ATTRIBUTE_UNUSED)
   2073 {
   2074   int cond = 1;
   2075 
   2076   ILLEGAL_WITHIN_STRUCT ();
   2077 
   2078   SKIP_WHITESPACE ();
   2079   if (!is_end_of_line[(int) *input_line_pointer])
   2080     cond = get_absolute_expression ();
   2081 
   2082   if (cond)
   2083     end_repeat (substitution_line ? 1 : 0);
   2084 }
   2085 
   2086 static void
   2087 set_address_mode (int mode)
   2088 {
   2089   amode = mode;
   2090   if (mode == far_mode)
   2091     {
   2092       symbolS *symbolP = symbol_new ("__allow_far", absolute_section,
   2093 				     (valueT) 1, &zero_address_frag);
   2094       SF_SET_LOCAL (symbolP);
   2095       symbol_table_insert (symbolP);
   2096     }
   2097 }
   2098 
   2099 static int address_mode_needs_set = 1;
   2100 
   2101 static void
   2102 tic54x_address_mode (int mode)
   2103 {
   2104   if (assembly_begun && amode != (unsigned) mode)
   2105     {
   2106       as_bad (_("Mixing of normal and extended addressing not supported"));
   2107       ignore_rest_of_line ();
   2108       return;
   2109     }
   2110   if (mode == far_mode && cpu != VNONE && cpu != V548 && cpu != V549)
   2111     {
   2112       as_bad (_("Extended addressing not supported on the specified CPU"));
   2113       ignore_rest_of_line ();
   2114       return;
   2115     }
   2116 
   2117   set_address_mode (mode);
   2118   demand_empty_rest_of_line ();
   2119 }
   2120 
   2121 /* .sblock "section"|section [,...,"section"|section]
   2122    Designate initialized sections for blocking.  */
   2123 
   2124 static void
   2125 tic54x_sblock (int ignore ATTRIBUTE_UNUSED)
   2126 {
   2127   int c = ',';
   2128 
   2129   ILLEGAL_WITHIN_STRUCT ();
   2130 
   2131   while (c == ',')
   2132     {
   2133       segT seg;
   2134       char *name;
   2135 
   2136       if (*input_line_pointer == '"')
   2137 	{
   2138 	  int len;
   2139 
   2140 	  name = demand_copy_C_string (&len);
   2141 	}
   2142       else
   2143 	{
   2144 	  char *section_name = input_line_pointer;
   2145 
   2146 	  c = get_symbol_end ();
   2147 	  name = xmalloc (strlen (section_name) + 1);
   2148 	  strcpy (name, section_name);
   2149 	  *input_line_pointer = c;
   2150 	}
   2151 
   2152       seg = bfd_get_section_by_name (stdoutput, name);
   2153       if (seg == NULL)
   2154 	{
   2155 	  as_bad (_("Unrecognized section '%s'"), name);
   2156 	  ignore_rest_of_line ();
   2157 	  return;
   2158 	}
   2159       else if (!tic54x_initialized_section (seg))
   2160 	{
   2161 	  as_bad (_(".sblock may be used for initialized sections only"));
   2162 	  ignore_rest_of_line ();
   2163 	  return;
   2164 	}
   2165       seg->flags |= SEC_TIC54X_BLOCK;
   2166 
   2167       c = *input_line_pointer;
   2168       if (!is_end_of_line[(int) c])
   2169 	++input_line_pointer;
   2170     }
   2171 
   2172   demand_empty_rest_of_line ();
   2173 }
   2174 
   2175 /* symbol .set value
   2176    symbol .equ value
   2177 
   2178    value must be defined externals; no forward-referencing allowed
   2179    symbols assigned with .set/.equ may not be redefined.  */
   2180 
   2181 static void
   2182 tic54x_set (int ignore ATTRIBUTE_UNUSED)
   2183 {
   2184   symbolS *symbolP;
   2185   char *name;
   2186 
   2187   ILLEGAL_WITHIN_STRUCT ();
   2188 
   2189   if (!line_label)
   2190     {
   2191       as_bad (_("Symbol missing for .set/.equ"));
   2192       ignore_rest_of_line ();
   2193       return;
   2194     }
   2195   name = xstrdup (S_GET_NAME (line_label));
   2196   line_label = NULL;
   2197   if ((symbolP = symbol_find (name)) == NULL
   2198       && (symbolP = md_undefined_symbol (name)) == NULL)
   2199     {
   2200       symbolP = symbol_new (name, absolute_section, 0, &zero_address_frag);
   2201       S_SET_STORAGE_CLASS (symbolP, C_STAT);
   2202     }
   2203   free (name);
   2204   S_SET_DATA_TYPE (symbolP, T_INT);
   2205   S_SET_SEGMENT (symbolP, absolute_section);
   2206   symbol_table_insert (symbolP);
   2207   pseudo_set (symbolP);
   2208   demand_empty_rest_of_line ();
   2209 }
   2210 
   2211 /* .fclist
   2212    .fcnolist
   2213    List false conditional blocks.  */
   2214 
   2215 static void
   2216 tic54x_fclist (int show)
   2217 {
   2218   if (show)
   2219     listing &= ~LISTING_NOCOND;
   2220   else
   2221     listing |= LISTING_NOCOND;
   2222   demand_empty_rest_of_line ();
   2223 }
   2224 
   2225 static void
   2226 tic54x_sslist (int show)
   2227 {
   2228   ILLEGAL_WITHIN_STRUCT ();
   2229 
   2230   listing_sslist = show;
   2231 }
   2232 
   2233 /* .var SYM[,...,SYMN]
   2234    Define a substitution string to be local to a macro.  */
   2235 
   2236 static void
   2237 tic54x_var (int ignore ATTRIBUTE_UNUSED)
   2238 {
   2239   static char empty[] = "";
   2240   char *name;
   2241   int c;
   2242 
   2243   ILLEGAL_WITHIN_STRUCT ();
   2244 
   2245   if (macro_level == 0)
   2246     {
   2247       as_bad (_(".var may only be used within a macro definition"));
   2248       ignore_rest_of_line ();
   2249       return;
   2250     }
   2251   do
   2252     {
   2253       if (!ISALPHA (*input_line_pointer))
   2254 	{
   2255 	  as_bad (_("Substitution symbols must begin with a letter"));
   2256 	  ignore_rest_of_line ();
   2257 	  return;
   2258 	}
   2259       name = input_line_pointer;
   2260       c = get_symbol_end ();
   2261       /* .var symbols start out with a null string.  */
   2262       name = strcpy (xmalloc (strlen (name) + 1), name);
   2263       hash_insert (subsym_hash[macro_level], name, empty);
   2264       *input_line_pointer = c;
   2265       if (c == ',')
   2266 	{
   2267 	  ++input_line_pointer;
   2268 	  if (is_end_of_line[(int) *input_line_pointer])
   2269 	    c = *input_line_pointer;
   2270 	}
   2271     }
   2272   while (c == ',');
   2273 
   2274   demand_empty_rest_of_line ();
   2275 }
   2276 
   2277 /* .mlib <macro library filename>
   2278 
   2279    Macro libraries are archived (standard AR-format) text macro definitions
   2280    Expand the file and include it.
   2281 
   2282    FIXME need to try the source file directory as well.  */
   2283 
   2284 static void
   2285 tic54x_mlib (int ignore ATTRIBUTE_UNUSED)
   2286 {
   2287   char *filename;
   2288   char *path;
   2289   int len, i;
   2290   bfd *abfd, *mbfd;
   2291 
   2292   ILLEGAL_WITHIN_STRUCT ();
   2293 
   2294   /* Parse the filename.  */
   2295   if (*input_line_pointer == '"')
   2296     {
   2297       if ((filename = demand_copy_C_string (&len)) == NULL)
   2298 	return;
   2299     }
   2300   else
   2301     {
   2302       SKIP_WHITESPACE ();
   2303       len = 0;
   2304       while (!is_end_of_line[(int) *input_line_pointer]
   2305 	     && !ISSPACE (*input_line_pointer))
   2306 	{
   2307 	  obstack_1grow (&notes, *input_line_pointer);
   2308 	  ++input_line_pointer;
   2309 	  ++len;
   2310 	}
   2311       obstack_1grow (&notes, '\0');
   2312       filename = obstack_finish (&notes);
   2313     }
   2314   demand_empty_rest_of_line ();
   2315 
   2316   tic54x_set_default_include (0);
   2317   path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
   2318 
   2319   for (i = 0; i < include_dir_count; i++)
   2320     {
   2321       FILE *try;
   2322 
   2323       strcpy (path, include_dirs[i]);
   2324       strcat (path, "/");
   2325       strcat (path, filename);
   2326       if ((try = fopen (path, "r")) != NULL)
   2327 	{
   2328 	  fclose (try);
   2329 	  break;
   2330 	}
   2331     }
   2332 
   2333   if (i >= include_dir_count)
   2334     {
   2335       free (path);
   2336       path = filename;
   2337     }
   2338 
   2339   /* FIXME: if path is found, malloc'd storage is not freed.  Of course, this
   2340      happens all over the place, and since the assembler doesn't usually keep
   2341      running for a very long time, it really doesn't matter.  */
   2342   register_dependency (path);
   2343 
   2344   /* Expand all archive entries to temporary files and include them.  */
   2345   abfd = bfd_openr (path, NULL);
   2346   if (!abfd)
   2347     {
   2348       as_bad (_("can't open macro library file '%s' for reading: %s"),
   2349 	      path, bfd_errmsg (bfd_get_error ()));
   2350       ignore_rest_of_line ();
   2351       return;
   2352     }
   2353   if (!bfd_check_format (abfd, bfd_archive))
   2354     {
   2355       as_bad (_("File '%s' not in macro archive format"), path);
   2356       ignore_rest_of_line ();
   2357       return;
   2358     }
   2359 
   2360   /* Open each BFD as binary (it should be straight ASCII text).  */
   2361   for (mbfd = bfd_openr_next_archived_file (abfd, NULL);
   2362        mbfd != NULL; mbfd = bfd_openr_next_archived_file (abfd, mbfd))
   2363     {
   2364       /* Get a size at least as big as the archive member.  */
   2365       bfd_size_type size = bfd_get_size (mbfd);
   2366       char *buf = xmalloc (size);
   2367       char *fname = tmpnam (NULL);
   2368       FILE *ftmp;
   2369 
   2370       /* We're not sure how big it is, but it will be smaller than "size".  */
   2371       size = bfd_bread (buf, size, mbfd);
   2372 
   2373       /* Write to a temporary file, then use s_include to include it
   2374 	 a bit of a hack.  */
   2375       ftmp = fopen (fname, "w+b");
   2376       fwrite ((void *) buf, size, 1, ftmp);
   2377       if (size == 0 || buf[size - 1] != '\n')
   2378 	fwrite ("\n", 1, 1, ftmp);
   2379       fclose (ftmp);
   2380       free (buf);
   2381       input_scrub_insert_file (fname);
   2382       unlink (fname);
   2383     }
   2384 }
   2385 
   2386 const pseudo_typeS md_pseudo_table[] =
   2387 {
   2388   { "algebraic", s_ignore                 ,          0 },
   2389   { "align"    , tic54x_align_words       ,        128 },
   2390   { "ascii"    , tic54x_stringer          ,        'p' },
   2391   { "asciz"    , tic54x_stringer          ,        'P' },
   2392   { "even"     , tic54x_align_words       ,          2 },
   2393   { "asg"      , tic54x_asg               ,          0 },
   2394   { "eval"     , tic54x_eval              ,          0 },
   2395   { "bss"      , tic54x_bss               ,          0 },
   2396   { "byte"     , tic54x_cons              ,        'b' },
   2397   { "ubyte"    , tic54x_cons              ,        'B' },
   2398   { "char"     , tic54x_cons              ,        'c' },
   2399   { "uchar"    , tic54x_cons              ,        'C' },
   2400   { "clink"    , tic54x_clink             ,          0 },
   2401   { "c_mode"   , tic54x_address_mode      ,     c_mode },
   2402   { "copy"     , tic54x_include           ,        'c' },
   2403   { "include"  , tic54x_include           ,        'i' },
   2404   { "data"     , tic54x_sect              ,        'd' },
   2405   { "double"   , tic54x_float_cons        ,        'd' },
   2406   { "ldouble"  , tic54x_float_cons        ,        'l' },
   2407   { "drlist"   , s_ignore                 ,          0 },
   2408   { "drnolist" , s_ignore                 ,          0 },
   2409   { "emsg"     , tic54x_message           ,        'e' },
   2410   { "mmsg"     , tic54x_message           ,        'm' },
   2411   { "wmsg"     , tic54x_message           ,        'w' },
   2412   { "far_mode" , tic54x_address_mode      ,   far_mode },
   2413   { "fclist"   , tic54x_fclist            ,          1 },
   2414   { "fcnolist" , tic54x_fclist            ,          0 },
   2415   { "field"    , tic54x_field             ,         -1 },
   2416   { "float"    , tic54x_float_cons        ,        'f' },
   2417   { "xfloat"   , tic54x_float_cons        ,        'x' },
   2418   { "global"   , tic54x_global            ,        'g' },
   2419   { "def"      , tic54x_global            ,        'd' },
   2420   { "ref"      , tic54x_global            ,        'r' },
   2421   { "half"     , tic54x_cons              ,        'h' },
   2422   { "uhalf"    , tic54x_cons              ,        'H' },
   2423   { "short"    , tic54x_cons              ,        's' },
   2424   { "ushort"   , tic54x_cons              ,        'S' },
   2425   { "if"       , s_if                     , (int) O_ne },
   2426   { "elseif"   , s_elseif                 , (int) O_ne },
   2427   { "else"     , s_else                   ,          0 },
   2428   { "endif"    , s_endif                  ,          0 },
   2429   { "int"      , tic54x_cons              ,        'i' },
   2430   { "uint"     , tic54x_cons              ,        'I' },
   2431   { "word"     , tic54x_cons              ,        'w' },
   2432   { "uword"    , tic54x_cons              ,        'W' },
   2433   { "label"    , tic54x_label             ,          0 }, /* Loadtime
   2434                                                              address.  */
   2435   { "length"   , s_ignore                 ,          0 },
   2436   { "width"    , s_ignore                 ,          0 },
   2437   { "long"     , tic54x_cons              ,        'l' },
   2438   { "ulong"    , tic54x_cons              ,        'L' },
   2439   { "xlong"    , tic54x_cons              ,        'x' },
   2440   { "loop"     , tic54x_loop              ,       1024 },
   2441   { "break"    , tic54x_break             ,          0 },
   2442   { "endloop"  , tic54x_endloop           ,          0 },
   2443   { "mlib"     , tic54x_mlib              ,          0 },
   2444   { "mlist"    , s_ignore                 ,          0 },
   2445   { "mnolist"  , s_ignore                 ,          0 },
   2446   { "mmregs"   , tic54x_mmregs            ,          0 },
   2447   { "newblock" , tic54x_clear_local_labels,          0 },
   2448   { "option"   , s_ignore                 ,          0 },
   2449   { "p2align"  , tic54x_p2align           ,          0 },
   2450   { "sblock"   , tic54x_sblock            ,          0 },
   2451   { "sect"     , tic54x_sect              ,        '*' },
   2452   { "set"      , tic54x_set               ,          0 },
   2453   { "equ"      , tic54x_set               ,          0 },
   2454   { "space"    , tic54x_space             ,          0 },
   2455   { "bes"      , tic54x_space             ,          1 },
   2456   { "sslist"   , tic54x_sslist            ,          1 },
   2457   { "ssnolist" , tic54x_sslist            ,          0 },
   2458   { "string"   , tic54x_stringer          ,        's' },
   2459   { "pstring"  , tic54x_stringer          ,        'p' },
   2460   { "struct"   , tic54x_struct            ,          0 },
   2461   { "tag"      , tic54x_tag               ,          0 },
   2462   { "endstruct", tic54x_endstruct         ,          0 },
   2463   { "tab"      , s_ignore                 ,          0 },
   2464   { "text"     , tic54x_sect              ,        't' },
   2465   { "union"    , tic54x_struct            ,          1 },
   2466   { "endunion" , tic54x_endstruct         ,          1 },
   2467   { "usect"    , tic54x_usect             ,          0 },
   2468   { "var"      , tic54x_var               ,          0 },
   2469   { "version"  , tic54x_version           ,          0 },
   2470   {0           , 0                        ,          0 }
   2471 };
   2472 
   2473 int
   2474 md_parse_option (int c, char *arg)
   2475 {
   2476   switch (c)
   2477     {
   2478     default:
   2479       return 0;
   2480     case OPTION_COFF_VERSION:
   2481       {
   2482 	int version = atoi (arg);
   2483 
   2484 	if (version != 0 && version != 1 && version != 2)
   2485 	  as_fatal (_("Bad COFF version '%s'"), arg);
   2486 	/* FIXME -- not yet implemented.  */
   2487 	break;
   2488       }
   2489     case OPTION_CPU_VERSION:
   2490       {
   2491 	cpu = lookup_version (arg);
   2492 	cpu_needs_set = 1;
   2493 	if (cpu == VNONE)
   2494 	  as_fatal (_("Bad CPU version '%s'"), arg);
   2495 	break;
   2496       }
   2497     case OPTION_ADDRESS_MODE:
   2498       amode = far_mode;
   2499       address_mode_needs_set = 1;
   2500       break;
   2501     case OPTION_STDERR_TO_FILE:
   2502       {
   2503 	char *filename = arg;
   2504 	FILE *fp = fopen (filename, "w+");
   2505 
   2506 	if (fp == NULL)
   2507 	  as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
   2508 	fclose (fp);
   2509 	if ((fp = freopen (filename, "w+", stderr)) == NULL)
   2510 	  as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
   2511 	break;
   2512       }
   2513     }
   2514 
   2515   return 1;
   2516 }
   2517 
   2518 /* Create a "local" substitution string hash table for a new macro level
   2519    Some docs imply that macros have to use .newblock in order to be able
   2520    to re-use a local label.  We effectively do an automatic .newblock by
   2521    deleting the local label hash between macro invocations.  */
   2522 
   2523 void
   2524 tic54x_macro_start (void)
   2525 {
   2526   ++macro_level;
   2527   subsym_hash[macro_level] = hash_new ();
   2528   local_label_hash[macro_level] = hash_new ();
   2529 }
   2530 
   2531 void
   2532 tic54x_macro_info (const macro_entry *macro)
   2533 {
   2534   const formal_entry *entry;
   2535 
   2536   /* Put the formal args into the substitution symbol table.  */
   2537   for (entry = macro->formals; entry; entry = entry->next)
   2538     {
   2539       char *name = strncpy (xmalloc (entry->name.len + 1),
   2540 			    entry->name.ptr, entry->name.len);
   2541       char *value = strncpy (xmalloc (entry->actual.len + 1),
   2542 			     entry->actual.ptr, entry->actual.len);
   2543 
   2544       name[entry->name.len] = '\0';
   2545       value[entry->actual.len] = '\0';
   2546       hash_insert (subsym_hash[macro_level], name, value);
   2547     }
   2548 }
   2549 
   2550 /* Get rid of this macro's .var's, arguments, and local labels.  */
   2551 
   2552 void
   2553 tic54x_macro_end (void)
   2554 {
   2555   hash_die (subsym_hash[macro_level]);
   2556   subsym_hash[macro_level] = NULL;
   2557   hash_die (local_label_hash[macro_level]);
   2558   local_label_hash[macro_level] = NULL;
   2559   --macro_level;
   2560 }
   2561 
   2562 static int
   2563 subsym_symlen (char *a, char *ignore ATTRIBUTE_UNUSED)
   2564 {
   2565   return strlen (a);
   2566 }
   2567 
   2568 /* Compare symbol A to string B.  */
   2569 
   2570 static int
   2571 subsym_symcmp (char *a, char *b)
   2572 {
   2573   return strcmp (a, b);
   2574 }
   2575 
   2576 /* Return the index of the first occurrence of B in A, or zero if none
   2577    assumes b is an integer char value as a string.  Index is one-based.  */
   2578 
   2579 static int
   2580 subsym_firstch (char *a, char *b)
   2581 {
   2582   int val = atoi (b);
   2583   char *tmp = strchr (a, val);
   2584 
   2585   return tmp ? tmp - a + 1 : 0;
   2586 }
   2587 
   2588 /* Similar to firstch, but returns index of last occurrence of B in A.  */
   2589 
   2590 static int
   2591 subsym_lastch (char *a, char *b)
   2592 {
   2593   int val = atoi (b);
   2594   char *tmp = strrchr (a, val);
   2595 
   2596   return tmp ? tmp - a + 1 : 0;
   2597 }
   2598 
   2599 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
   2600    symbol table).  */
   2601 
   2602 static int
   2603 subsym_isdefed (char *a, char *ignore ATTRIBUTE_UNUSED)
   2604 {
   2605   symbolS *symbolP = symbol_find (a);
   2606 
   2607   return symbolP != NULL;
   2608 }
   2609 
   2610 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
   2611    A, or zero if B is a null string.  Both arguments *must* be substitution
   2612    symbols, unsubstituted.  */
   2613 
   2614 static int
   2615 subsym_ismember (char *sym, char *list)
   2616 {
   2617   char *elem, *ptr, *listv;
   2618 
   2619   if (!list)
   2620     return 0;
   2621 
   2622   listv = subsym_lookup (list, macro_level);
   2623   if (!listv)
   2624     {
   2625       as_bad (_("Undefined substitution symbol '%s'"), list);
   2626       ignore_rest_of_line ();
   2627       return 0;
   2628     }
   2629 
   2630   ptr = elem = xmalloc (strlen (listv) + 1);
   2631   strcpy (elem, listv);
   2632   while (*ptr && *ptr != ',')
   2633     ++ptr;
   2634   *ptr++ = 0;
   2635 
   2636   subsym_create_or_replace (sym, elem);
   2637 
   2638   /* Reassign the list.  */
   2639   subsym_create_or_replace (list, ptr);
   2640 
   2641   /* Assume this value, docs aren't clear.  */
   2642   return *list != 0;
   2643 }
   2644 
   2645 /* Return zero if not a constant; otherwise:
   2646    1 if binary
   2647    2 if octal
   2648    3 if hexadecimal
   2649    4 if character
   2650    5 if decimal.  */
   2651 
   2652 static int
   2653 subsym_iscons (char *a, char *ignore ATTRIBUTE_UNUSED)
   2654 {
   2655   expressionS expn;
   2656 
   2657   parse_expression (a, &expn);
   2658 
   2659   if (expn.X_op == O_constant)
   2660     {
   2661       int len = strlen (a);
   2662 
   2663       switch (TOUPPER (a[len - 1]))
   2664 	{
   2665 	case 'B':
   2666 	  return 1;
   2667 	case 'Q':
   2668 	  return 2;
   2669 	case 'H':
   2670 	  return 3;
   2671 	case '\'':
   2672 	  return 4;
   2673 	default:
   2674 	  break;
   2675 	}
   2676       /* No suffix; either octal, hex, or decimal.  */
   2677       if (*a == '0' && len > 1)
   2678 	{
   2679 	  if (TOUPPER (a[1]) == 'X')
   2680 	    return 3;
   2681 	  return 2;
   2682 	}
   2683       return 5;
   2684     }
   2685 
   2686   return 0;
   2687 }
   2688 
   2689 /* Return 1 if A is a valid symbol name.  Expects string input.   */
   2690 
   2691 static int
   2692 subsym_isname (char *a, char *ignore ATTRIBUTE_UNUSED)
   2693 {
   2694   if (!is_name_beginner (*a))
   2695     return 0;
   2696   while (*a)
   2697     {
   2698       if (!is_part_of_name (*a))
   2699 	return 0;
   2700       ++a;
   2701     }
   2702   return 1;
   2703 }
   2704 
   2705 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
   2706    been seen; if so, recognize any memory-mapped register.
   2707    Note this does not recognize "A" or "B" accumulators.  */
   2708 
   2709 static int
   2710 subsym_isreg (char *a, char *ignore ATTRIBUTE_UNUSED)
   2711 {
   2712   if (hash_find (reg_hash, a))
   2713     return 1;
   2714   if (hash_find (mmreg_hash, a))
   2715     return 1;
   2716   return 0;
   2717 }
   2718 
   2719 /* Return the structure size, given the stag.  */
   2720 
   2721 static int
   2722 subsym_structsz (char *name, char *ignore ATTRIBUTE_UNUSED)
   2723 {
   2724   struct stag *stag = (struct stag *) hash_find (stag_hash, name);
   2725 
   2726   if (stag)
   2727     return stag->size;
   2728 
   2729   return 0;
   2730 }
   2731 
   2732 /* If anybody actually uses this, they can fix it :)
   2733    FIXME I'm not sure what the "reference point" of a structure is.  It might
   2734    be either the initial offset given .struct, or it may be the offset of the
   2735    structure within another structure, or it might be something else
   2736    altogether.  since the TI assembler doesn't seem to ever do anything but
   2737    return zero, we punt and return zero.  */
   2738 
   2739 static int
   2740 subsym_structacc (char *stag_name ATTRIBUTE_UNUSED,
   2741 		  char *ignore ATTRIBUTE_UNUSED)
   2742 {
   2743   return 0;
   2744 }
   2745 
   2746 static float
   2747 math_ceil (float arg1, float ignore ATTRIBUTE_UNUSED)
   2748 {
   2749   return (float) ceil (arg1);
   2750 }
   2751 
   2752 static float
   2753 math_cvi (float arg1, float ignore ATTRIBUTE_UNUSED)
   2754 {
   2755   return (int) arg1;
   2756 }
   2757 
   2758 static float
   2759 math_floor (float arg1, float ignore ATTRIBUTE_UNUSED)
   2760 {
   2761   return (float) floor (arg1);
   2762 }
   2763 
   2764 static float
   2765 math_fmod (float arg1, float arg2)
   2766 {
   2767   return (int) arg1 % (int) arg2;
   2768 }
   2769 
   2770 static float
   2771 math_int (float arg1, float ignore ATTRIBUTE_UNUSED)
   2772 {
   2773   return ((float) ((int) arg1)) == arg1;
   2774 }
   2775 
   2776 static float
   2777 math_round (float arg1, float ignore ATTRIBUTE_UNUSED)
   2778 {
   2779   return arg1 > 0 ? (int) (arg1 + 0.5) : (int) (arg1 - 0.5);
   2780 }
   2781 
   2782 static float
   2783 math_sgn (float arg1, float ignore ATTRIBUTE_UNUSED)
   2784 {
   2785   return (arg1 < 0) ? -1 : (arg1 ? 1 : 0);
   2786 }
   2787 
   2788 static float
   2789 math_trunc (float arg1, float ignore ATTRIBUTE_UNUSED)
   2790 {
   2791   return (int) arg1;
   2792 }
   2793 
   2794 static float
   2795 math_acos (float arg1, float ignore ATTRIBUTE_UNUSED)
   2796 {
   2797   return (float) acos (arg1);
   2798 }
   2799 
   2800 static float
   2801 math_asin (float arg1, float ignore ATTRIBUTE_UNUSED)
   2802 {
   2803   return (float) asin (arg1);
   2804 }
   2805 
   2806 static float
   2807 math_atan (float arg1, float ignore ATTRIBUTE_UNUSED)
   2808 {
   2809   return (float) atan (arg1);
   2810 }
   2811 
   2812 static float
   2813 math_atan2 (float arg1, float arg2)
   2814 {
   2815   return (float) atan2 (arg1, arg2);
   2816 }
   2817 
   2818 static float
   2819 math_cosh (float arg1, float ignore ATTRIBUTE_UNUSED)
   2820 {
   2821   return (float) cosh (arg1);
   2822 }
   2823 
   2824 static float
   2825 math_cos (float arg1, float ignore ATTRIBUTE_UNUSED)
   2826 {
   2827   return (float) cos (arg1);
   2828 }
   2829 
   2830 static float
   2831 math_cvf (float arg1, float ignore ATTRIBUTE_UNUSED)
   2832 {
   2833   return (float) arg1;
   2834 }
   2835 
   2836 static float
   2837 math_exp (float arg1, float ignore ATTRIBUTE_UNUSED)
   2838 {
   2839   return (float) exp (arg1);
   2840 }
   2841 
   2842 static float
   2843 math_fabs (float arg1, float ignore ATTRIBUTE_UNUSED)
   2844 {
   2845   return (float) fabs (arg1);
   2846 }
   2847 
   2848 /* expr1 * 2^expr2.  */
   2849 
   2850 static float
   2851 math_ldexp (float arg1, float arg2)
   2852 {
   2853   return arg1 * (float) pow (2.0, arg2);
   2854 }
   2855 
   2856 static float
   2857 math_log10 (float arg1, float ignore ATTRIBUTE_UNUSED)
   2858 {
   2859   return (float) log10 (arg1);
   2860 }
   2861 
   2862 static float
   2863 math_log (float arg1, float ignore ATTRIBUTE_UNUSED)
   2864 {
   2865   return (float) log (arg1);
   2866 }
   2867 
   2868 static float
   2869 math_max (float arg1, float arg2)
   2870 {
   2871   return (arg1 > arg2) ? arg1 : arg2;
   2872 }
   2873 
   2874 static float
   2875 math_min (float arg1, float arg2)
   2876 {
   2877   return (arg1 < arg2) ? arg1 : arg2;
   2878 }
   2879 
   2880 static float
   2881 math_pow (float arg1, float arg2)
   2882 {
   2883   return (float) pow (arg1, arg2);
   2884 }
   2885 
   2886 static float
   2887 math_sin (float arg1, float ignore ATTRIBUTE_UNUSED)
   2888 {
   2889   return (float) sin (arg1);
   2890 }
   2891 
   2892 static float
   2893 math_sinh (float arg1, float ignore ATTRIBUTE_UNUSED)
   2894 {
   2895   return (float) sinh (arg1);
   2896 }
   2897 
   2898 static float
   2899 math_sqrt (float arg1, float ignore ATTRIBUTE_UNUSED)
   2900 {
   2901   return (float) sqrt (arg1);
   2902 }
   2903 
   2904 static float
   2905 math_tan (float arg1, float ignore ATTRIBUTE_UNUSED)
   2906 {
   2907   return (float) tan (arg1);
   2908 }
   2909 
   2910 static float
   2911 math_tanh (float arg1, float ignore ATTRIBUTE_UNUSED)
   2912 {
   2913   return (float) tanh (arg1);
   2914 }
   2915 
   2916 /* Built-in substitution symbol functions and math functions.  */
   2917 typedef struct
   2918 {
   2919   char *name;
   2920   int (*proc) (char *, char *);
   2921   int nargs;
   2922 } subsym_proc_entry;
   2923 
   2924 static const subsym_proc_entry subsym_procs[] =
   2925 {
   2926   /* Assembler built-in string substitution functions.  */
   2927   { "$symlen", subsym_symlen, 1,  },
   2928   { "$symcmp", subsym_symcmp, 2,  },
   2929   { "$firstch", subsym_firstch, 2,  },
   2930   { "$lastch", subsym_lastch, 2,  },
   2931   { "$isdefed", subsym_isdefed, 1,  },
   2932   { "$ismember", subsym_ismember, 2,  },
   2933   { "$iscons", subsym_iscons, 1,  },
   2934   { "$isname", subsym_isname, 1,  },
   2935   { "$isreg", subsym_isreg, 1,  },
   2936   { "$structsz", subsym_structsz, 1,  },
   2937   { "$structacc", subsym_structacc, 1,  },
   2938   { NULL, NULL, 0 },
   2939 };
   2940 
   2941 typedef struct
   2942 {
   2943   char *name;
   2944   float (*proc) (float, float);
   2945   int nargs;
   2946   int int_return;
   2947 } math_proc_entry;
   2948 
   2949 static const math_proc_entry math_procs[] =
   2950 {
   2951   /* Integer-returning built-in math functions.  */
   2952   { "$cvi", math_cvi, 1, 1 },
   2953   { "$int", math_int, 1, 1 },
   2954   { "$sgn", math_sgn, 1, 1 },
   2955 
   2956   /* Float-returning built-in math functions.  */
   2957   { "$acos", math_acos, 1, 0 },
   2958   { "$asin", math_asin, 1, 0 },
   2959   { "$atan", math_atan, 1, 0 },
   2960   { "$atan2", math_atan2, 2, 0 },
   2961   { "$ceil", math_ceil, 1, 0 },
   2962   { "$cosh", math_cosh, 1, 0 },
   2963   { "$cos", math_cos, 1, 0 },
   2964   { "$cvf", math_cvf, 1, 0 },
   2965   { "$exp", math_exp, 1, 0 },
   2966   { "$fabs", math_fabs, 1, 0 },
   2967   { "$floor", math_floor, 1, 0 },
   2968   { "$fmod", math_fmod, 2, 0 },
   2969   { "$ldexp", math_ldexp, 2, 0 },
   2970   { "$log10", math_log10, 1, 0 },
   2971   { "$log", math_log, 1, 0 },
   2972   { "$max", math_max, 2, 0 },
   2973   { "$min", math_min, 2, 0 },
   2974   { "$pow", math_pow, 2, 0 },
   2975   { "$round", math_round, 1, 0 },
   2976   { "$sin", math_sin, 1, 0 },
   2977   { "$sinh", math_sinh, 1, 0 },
   2978   { "$sqrt", math_sqrt, 1, 0 },
   2979   { "$tan", math_tan, 1, 0 },
   2980   { "$tanh", math_tanh, 1, 0 },
   2981   { "$trunc", math_trunc, 1, 0 },
   2982   { NULL, NULL, 0, 0 },
   2983 };
   2984 
   2985 void
   2986 md_begin (void)
   2987 {
   2988   insn_template *tm;
   2989   symbol *sym;
   2990   const subsym_proc_entry *subsym_proc;
   2991   const math_proc_entry *math_proc;
   2992   const char *hash_err;
   2993   char **symname;
   2994   char *TIC54X_DIR = getenv ("TIC54X_DIR");
   2995   char *A_DIR = TIC54X_DIR ? TIC54X_DIR : getenv ("A_DIR");
   2996 
   2997   local_label_id = 0;
   2998 
   2999   /* Look for A_DIR and add it to the include list.  */
   3000   if (A_DIR != NULL)
   3001     {
   3002       char *tmp = xstrdup (A_DIR);
   3003 
   3004       do
   3005 	{
   3006 	  char *next = strchr (tmp, ';');
   3007 
   3008 	  if (next)
   3009 	    *next++ = '\0';
   3010 	  add_include_dir (tmp);
   3011 	  tmp = next;
   3012 	}
   3013       while (tmp != NULL);
   3014     }
   3015 
   3016   op_hash = hash_new ();
   3017   for (tm = (insn_template *) tic54x_optab; tm->name; tm++)
   3018     {
   3019       if (hash_find (op_hash, tm->name))
   3020 	continue;
   3021       hash_err = hash_insert (op_hash, tm->name, (char *) tm);
   3022       if (hash_err)
   3023 	as_fatal ("Internal Error: Can't hash %s: %s",
   3024 		  tm->name, hash_err);
   3025     }
   3026   parop_hash = hash_new ();
   3027   for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
   3028     {
   3029       if (hash_find (parop_hash, tm->name))
   3030 	continue;
   3031       hash_err = hash_insert (parop_hash, tm->name, (char *) tm);
   3032       if (hash_err)
   3033 	as_fatal ("Internal Error: Can't hash %s: %s",
   3034 		  tm->name, hash_err);
   3035     }
   3036   reg_hash = hash_new ();
   3037   for (sym = (symbol *) regs; sym->name; sym++)
   3038     {
   3039       /* Add basic registers to the symbol table.  */
   3040       symbolS *symbolP = symbol_new (sym->name, absolute_section,
   3041 				     (valueT) sym->value, &zero_address_frag);
   3042       SF_SET_LOCAL (symbolP);
   3043       symbol_table_insert (symbolP);
   3044       hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
   3045     }
   3046   for (sym = (symbol *) mmregs; sym->name; sym++)
   3047     hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
   3048   mmreg_hash = hash_new ();
   3049   for (sym = (symbol *) mmregs; sym->name; sym++)
   3050     hash_err = hash_insert (mmreg_hash, sym->name, (char *) sym);
   3051 
   3052   cc_hash = hash_new ();
   3053   for (sym = (symbol *) condition_codes; sym->name; sym++)
   3054     hash_err = hash_insert (cc_hash, sym->name, (char *) sym);
   3055 
   3056   cc2_hash = hash_new ();
   3057   for (sym = (symbol *) cc2_codes; sym->name; sym++)
   3058     hash_err = hash_insert (cc2_hash, sym->name, (char *) sym);
   3059 
   3060   cc3_hash = hash_new ();
   3061   for (sym = (symbol *) cc3_codes; sym->name; sym++)
   3062     hash_err = hash_insert (cc3_hash, sym->name, (char *) sym);
   3063 
   3064   sbit_hash = hash_new ();
   3065   for (sym = (symbol *) status_bits; sym->name; sym++)
   3066     hash_err = hash_insert (sbit_hash, sym->name, (char *) sym);
   3067 
   3068   misc_symbol_hash = hash_new ();
   3069   for (symname = (char **) misc_symbols; *symname; symname++)
   3070     hash_err = hash_insert (misc_symbol_hash, *symname, *symname);
   3071 
   3072   /* Only the base substitution table and local label table are initialized;
   3073      the others (for local macro substitution) get instantiated as needed.  */
   3074   local_label_hash[0] = hash_new ();
   3075   subsym_hash[0] = hash_new ();
   3076   for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++)
   3077     hash_err = hash_insert (subsym_hash[0], subsym_proc->name,
   3078 			    (char *) subsym_proc);
   3079 
   3080   math_hash = hash_new ();
   3081   for (math_proc = math_procs; math_proc->name; math_proc++)
   3082     {
   3083       /* Insert into the main subsym hash for recognition; insert into
   3084 	 the math hash to actually store information.  */
   3085       hash_err = hash_insert (subsym_hash[0], math_proc->name,
   3086 			      (char *) math_proc);
   3087       hash_err = hash_insert (math_hash, math_proc->name,
   3088 			      (char *) math_proc);
   3089     }
   3090   subsym_recurse_hash = hash_new ();
   3091   stag_hash = hash_new ();
   3092 }
   3093 
   3094 static int
   3095 is_accumulator (struct opstruct *operand)
   3096 {
   3097   return strcasecmp (operand->buf, "a") == 0
   3098     || strcasecmp (operand->buf, "b") == 0;
   3099 }
   3100 
   3101 /* Return the number of operands found, or -1 on error, copying the
   3102    operands into the given array and the accompanying expressions into
   3103    the next array.  */
   3104 
   3105 static int
   3106 get_operands (struct opstruct operands[], char *line)
   3107 {
   3108   char *lptr = line;
   3109   int numexp = 0;
   3110   int expecting_operand = 0;
   3111   int i;
   3112 
   3113   while (numexp < MAX_OPERANDS && !is_end_of_line[(int) *lptr])
   3114     {
   3115       int paren_not_balanced = 0;
   3116       char *op_start, *op_end;
   3117 
   3118       while (*lptr && ISSPACE (*lptr))
   3119 	++lptr;
   3120       op_start = lptr;
   3121       while (paren_not_balanced || *lptr != ',')
   3122 	{
   3123 	  if (*lptr == '\0')
   3124 	    {
   3125 	      if (paren_not_balanced)
   3126 		{
   3127 		  as_bad (_("Unbalanced parenthesis in operand %d"), numexp);
   3128 		  return -1;
   3129 		}
   3130 	      else
   3131 		break;
   3132 	    }
   3133 	  if (*lptr == '(')
   3134 	    ++paren_not_balanced;
   3135 	  else if (*lptr == ')')
   3136 	    --paren_not_balanced;
   3137 	  ++lptr;
   3138 	}
   3139       op_end = lptr;
   3140       if (op_end != op_start)
   3141 	{
   3142 	  int len = op_end - op_start;
   3143 
   3144 	  strncpy (operands[numexp].buf, op_start, len);
   3145 	  operands[numexp].buf[len] = 0;
   3146 	  /* Trim trailing spaces; while the preprocessor gets rid of most,
   3147 	     there are weird usage patterns that can introduce them
   3148 	     (i.e. using strings for macro args).  */
   3149 	  while (len > 0 && ISSPACE (operands[numexp].buf[len - 1]))
   3150 	    operands[numexp].buf[--len] = 0;
   3151 	  lptr = op_end;
   3152 	  ++numexp;
   3153 	}
   3154       else
   3155 	{
   3156 	  if (expecting_operand || *lptr == ',')
   3157 	    {
   3158 	      as_bad (_("Expecting operand after ','"));
   3159 	      return -1;
   3160 	    }
   3161 	}
   3162       if (*lptr == ',')
   3163 	{
   3164 	  if (*++lptr == '\0')
   3165 	    {
   3166 	      as_bad (_("Expecting operand after ','"));
   3167 	      return -1;
   3168 	    }
   3169 	  expecting_operand = 1;
   3170 	}
   3171     }
   3172 
   3173   while (*lptr && ISSPACE (*lptr++))
   3174     ;
   3175   if (!is_end_of_line[(int) *lptr])
   3176     {
   3177       as_bad (_("Extra junk on line"));
   3178       return -1;
   3179     }
   3180 
   3181   /* OK, now parse them into expressions.  */
   3182   for (i = 0; i < numexp; i++)
   3183     {
   3184       memset (&operands[i].exp, 0, sizeof (operands[i].exp));
   3185       if (operands[i].buf[0] == '#')
   3186 	{
   3187 	  /* Immediate.  */
   3188 	  parse_expression (operands[i].buf + 1, &operands[i].exp);
   3189 	}
   3190       else if (operands[i].buf[0] == '@')
   3191 	{
   3192 	  /* Direct notation.  */
   3193 	  parse_expression (operands[i].buf + 1, &operands[i].exp);
   3194 	}
   3195       else if (operands[i].buf[0] == '*')
   3196 	{
   3197 	  /* Indirect.  */
   3198 	  char *paren = strchr (operands[i].buf, '(');
   3199 
   3200 	  /* Allow immediate syntax in the inner expression.  */
   3201 	  if (paren && paren[1] == '#')
   3202 	    *++paren = '(';
   3203 
   3204 	  /* Pull out the lk expression or SP offset, if present.  */
   3205 	  if (paren != NULL)
   3206 	    {
   3207 	      int len = strlen (paren);
   3208 	      char *end = paren + len;
   3209 	      int c;
   3210 
   3211 	      while (end[-1] != ')')
   3212 		if (--end <= paren)
   3213 		  {
   3214 		    as_bad (_("Badly formed address expression"));
   3215 		    return -1;
   3216 		  }
   3217 	      c = *end;
   3218 	      *end = '\0';
   3219 	      parse_expression (paren, &operands[i].exp);
   3220 	      *end = c;
   3221 	    }
   3222 	  else
   3223 	    operands[i].exp.X_op = O_absent;
   3224 	}
   3225       else
   3226 	parse_expression (operands[i].buf, &operands[i].exp);
   3227     }
   3228 
   3229   return numexp;
   3230 }
   3231 
   3232 /* Predicates for different operand types.  */
   3233 
   3234 static int
   3235 is_immediate (struct opstruct *operand)
   3236 {
   3237   return *operand->buf == '#';
   3238 }
   3239 
   3240 /* This is distinguished from immediate because some numbers must be constants
   3241    and must *not* have the '#' prefix.  */
   3242 
   3243 static int
   3244 is_absolute (struct opstruct *operand)
   3245 {
   3246   return operand->exp.X_op == O_constant && !is_immediate (operand);
   3247 }
   3248 
   3249 /* Is this an indirect operand?  */
   3250 
   3251 static int
   3252 is_indirect (struct opstruct *operand)
   3253 {
   3254   return operand->buf[0] == '*';
   3255 }
   3256 
   3257 /* Is this a valid dual-memory operand?  */
   3258 
   3259 static int
   3260 is_dual (struct opstruct *operand)
   3261 {
   3262   if (is_indirect (operand) && strncasecmp (operand->buf, "*ar", 3) == 0)
   3263     {
   3264       char *tmp = operand->buf + 3;
   3265       int arf;
   3266       int valid_mod;
   3267 
   3268       arf = *tmp++ - '0';
   3269       /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%.  */
   3270       valid_mod = *tmp == '\0' ||
   3271 	strcasecmp (tmp, "-") == 0 ||
   3272 	strcasecmp (tmp, "+") == 0 ||
   3273 	strcasecmp (tmp, "+0%") == 0;
   3274       return arf >= 2 && arf <= 5 && valid_mod;
   3275     }
   3276   return 0;
   3277 }
   3278 
   3279 static int
   3280 is_mmreg (struct opstruct *operand)
   3281 {
   3282   return (is_absolute (operand)
   3283 	  || is_immediate (operand)
   3284 	  || hash_find (mmreg_hash, operand->buf) != 0);
   3285 }
   3286 
   3287 static int
   3288 is_type (struct opstruct *operand, enum optype type)
   3289 {
   3290   switch (type)
   3291     {
   3292     case OP_None:
   3293       return operand->buf[0] == 0;
   3294     case OP_Xmem:
   3295     case OP_Ymem:
   3296       return is_dual (operand);
   3297     case OP_Sind:
   3298       return is_indirect (operand);
   3299     case OP_xpmad_ms7:
   3300       /* This one *must* be immediate.  */
   3301       return is_immediate (operand);
   3302     case OP_xpmad:
   3303     case OP_pmad:
   3304     case OP_PA:
   3305     case OP_dmad:
   3306     case OP_Lmem:
   3307     case OP_MMR:
   3308       return 1;
   3309     case OP_Smem:
   3310       /* Address may be a numeric, indirect, or an expression.  */
   3311       return !is_immediate (operand);
   3312     case OP_MMRY:
   3313     case OP_MMRX:
   3314       return is_mmreg (operand);
   3315     case OP_SRC:
   3316     case OP_SRC1:
   3317     case OP_RND:
   3318     case OP_DST:
   3319       return is_accumulator (operand);
   3320     case OP_B:
   3321       return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'B';
   3322     case OP_A:
   3323       return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'A';
   3324     case OP_ARX:
   3325       return strncasecmp ("ar", operand->buf, 2) == 0
   3326 	&& ISDIGIT (operand->buf[2]);
   3327     case OP_SBIT:
   3328       return hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand);
   3329     case OP_CC:
   3330       return hash_find (cc_hash, operand->buf) != 0;
   3331     case OP_CC2:
   3332       return hash_find (cc2_hash, operand->buf) != 0;
   3333     case OP_CC3:
   3334       return hash_find (cc3_hash, operand->buf) != 0
   3335 	|| is_immediate (operand) || is_absolute (operand);
   3336     case OP_16:
   3337       return (is_immediate (operand) || is_absolute (operand))
   3338 	&& operand->exp.X_add_number == 16;
   3339     case OP_N:
   3340       /* Allow st0 or st1 instead of a numeric.  */
   3341       return is_absolute (operand) || is_immediate (operand) ||
   3342 	strcasecmp ("st0", operand->buf) == 0 ||
   3343 	strcasecmp ("st1", operand->buf) == 0;
   3344     case OP_12:
   3345     case OP_123:
   3346       return is_absolute (operand) || is_immediate (operand);
   3347     case OP_SHFT:
   3348       return (is_immediate (operand) || is_absolute (operand))
   3349 	&& operand->exp.X_add_number >= 0 && operand->exp.X_add_number < 16;
   3350     case OP_SHIFT:
   3351       /* Let this one catch out-of-range values.  */
   3352       return (is_immediate (operand) || is_absolute (operand))
   3353 	&& operand->exp.X_add_number != 16;
   3354     case OP_BITC:
   3355     case OP_031:
   3356     case OP_k8:
   3357       return is_absolute (operand) || is_immediate (operand);
   3358     case OP_k8u:
   3359       return is_immediate (operand)
   3360 	&& operand->exp.X_op == O_constant
   3361 	&& operand->exp.X_add_number >= 0
   3362 	&& operand->exp.X_add_number < 256;
   3363     case OP_lk:
   3364     case OP_lku:
   3365       /* Allow anything; assumes opcodes are ordered with Smem operands
   3366 	 versions first.  */
   3367       return 1;
   3368     case OP_k5:
   3369     case OP_k3:
   3370     case OP_k9:
   3371       /* Just make sure it's an integer; check range later.  */
   3372       return is_immediate (operand);
   3373     case OP_T:
   3374       return strcasecmp ("t", operand->buf) == 0 ||
   3375 	strcasecmp ("treg", operand->buf) == 0;
   3376     case OP_TS:
   3377       return strcasecmp ("ts", operand->buf) == 0;
   3378     case OP_ASM:
   3379       return strcasecmp ("asm", operand->buf) == 0;
   3380     case OP_TRN:
   3381       return strcasecmp ("trn", operand->buf) == 0;
   3382     case OP_DP:
   3383       return strcasecmp ("dp", operand->buf) == 0;
   3384     case OP_ARP:
   3385       return strcasecmp ("arp", operand->buf) == 0;
   3386     default:
   3387       return 0;
   3388     }
   3389 }
   3390 
   3391 static int
   3392 operands_match (tic54x_insn *insn,
   3393 		struct opstruct *operands,
   3394 		int opcount,
   3395 		const enum optype *refoptype,
   3396 		int minops,
   3397 		int maxops)
   3398 {
   3399   int op = 0, refop = 0;
   3400 
   3401   if (opcount == 0 && minops == 0)
   3402     return 1;
   3403 
   3404   while (op <= maxops && refop <= maxops)
   3405     {
   3406       while (!is_type (&operands[op], OPTYPE (refoptype[refop])))
   3407 	{
   3408 	  /* Skip an optional template operand if it doesn't agree
   3409 	     with the current operand.  */
   3410 	  if (refoptype[refop] & OPT)
   3411 	    {
   3412 	      ++refop;
   3413 	      --maxops;
   3414 	      if (refop > maxops)
   3415 		return 0;
   3416 	    }
   3417 	  else
   3418 	    return 0;
   3419 	}
   3420 
   3421       /* Save the actual operand type for later use.  */
   3422       operands[op].type = OPTYPE (refoptype[refop]);
   3423       ++refop;
   3424       ++op;
   3425       /* Have we matched them all yet?  */
   3426       if (op == opcount)
   3427 	{
   3428 	  while (op < maxops)
   3429 	    {
   3430 	      /* If a later operand is *not* optional, no match.  */
   3431 	      if ((refoptype[refop] & OPT) == 0)
   3432 		return 0;
   3433 	      /* Flag any implicit default OP_DST operands so we know to add
   3434 		 them explicitly when encoding the operand later.  */
   3435 	      if (OPTYPE (refoptype[refop]) == OP_DST)
   3436 		insn->using_default_dst = 1;
   3437 	      ++refop;
   3438 	      ++op;
   3439 	    }
   3440 
   3441 	  return 1;
   3442 	}
   3443     }
   3444 
   3445   return 0;
   3446 }
   3447 
   3448 /* 16-bit direct memory address
   3449    Explicit dmad operands are always in last word of insn (usually second
   3450    word, but bumped to third if lk addressing is used)
   3451 
   3452    We allow *(dmad) notation because the TI assembler allows it.
   3453 
   3454    XPC_CODE:
   3455    0 for 16-bit addresses
   3456    1 for full 23-bit addresses
   3457    2 for the upper 7 bits of a 23-bit address (LDX).  */
   3458 
   3459 static int
   3460 encode_dmad (tic54x_insn *insn, struct opstruct *operand, int xpc_code)
   3461 {
   3462   int op = 1 + insn->is_lkaddr;
   3463 
   3464   /* Only allow *(dmad) expressions; all others are invalid.  */
   3465   if (is_indirect (operand) && operand->buf[strlen (operand->buf) - 1] != ')')
   3466     {
   3467       as_bad (_("Invalid dmad syntax '%s'"), operand->buf);
   3468       return 0;
   3469     }
   3470 
   3471   insn->opcode[op].addr_expr = operand->exp;
   3472 
   3473   if (insn->opcode[op].addr_expr.X_op == O_constant)
   3474     {
   3475       valueT value = insn->opcode[op].addr_expr.X_add_number;
   3476 
   3477       if (xpc_code == 1)
   3478 	{
   3479 	  insn->opcode[0].word &= 0xFF80;
   3480 	  insn->opcode[0].word |= (value >> 16) & 0x7F;
   3481 	  insn->opcode[1].word = value & 0xFFFF;
   3482 	}
   3483       else if (xpc_code == 2)
   3484 	insn->opcode[op].word = (value >> 16) & 0xFFFF;
   3485       else
   3486 	insn->opcode[op].word = value;
   3487     }
   3488   else
   3489     {
   3490       /* Do the fixup later; just store the expression.  */
   3491       insn->opcode[op].word = 0;
   3492       insn->opcode[op].r_nchars = 2;
   3493 
   3494       if (amode == c_mode)
   3495 	insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
   3496       else if (xpc_code == 1)
   3497 	{
   3498 	  /* This relocation spans two words, so adjust accordingly.  */
   3499 	  insn->opcode[0].addr_expr = operand->exp;
   3500 	  insn->opcode[0].r_type = BFD_RELOC_TIC54X_23;
   3501 	  insn->opcode[0].r_nchars = 4;
   3502 	  insn->opcode[0].unresolved = 1;
   3503 	  /* It's really 2 words, but we want to stop encoding after the
   3504 	     first, since we must encode both words at once.  */
   3505 	  insn->words = 1;
   3506 	}
   3507       else if (xpc_code == 2)
   3508 	insn->opcode[op].r_type = BFD_RELOC_TIC54X_MS7_OF_23;
   3509       else
   3510 	insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
   3511 
   3512       insn->opcode[op].unresolved = 1;
   3513     }
   3514 
   3515   return 1;
   3516 }
   3517 
   3518 /* 7-bit direct address encoding.  */
   3519 
   3520 static int
   3521 encode_address (tic54x_insn *insn, struct opstruct *operand)
   3522 {
   3523   /* Assumes that dma addresses are *always* in word 0 of the opcode.  */
   3524   insn->opcode[0].addr_expr = operand->exp;
   3525 
   3526   if (operand->exp.X_op == O_constant)
   3527     insn->opcode[0].word |= (operand->exp.X_add_number & 0x7F);
   3528   else
   3529     {
   3530       if (operand->exp.X_op == O_register)
   3531         as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand->buf);
   3532       /* Do the fixup later; just store the expression.  */
   3533       insn->opcode[0].r_nchars = 1;
   3534       insn->opcode[0].r_type = BFD_RELOC_TIC54X_PARTLS7;
   3535       insn->opcode[0].unresolved = 1;
   3536     }
   3537 
   3538   return 1;
   3539 }
   3540 
   3541 static int
   3542 encode_indirect (tic54x_insn *insn, struct opstruct *operand)
   3543 {
   3544   int arf;
   3545   int mod;
   3546 
   3547   if (insn->is_lkaddr)
   3548     {
   3549       /* lk addresses always go in the second insn word.  */
   3550       mod = ((TOUPPER (operand->buf[1]) == 'A') ? 12 :
   3551 	     (operand->buf[1] == '(') ? 15 :
   3552 	     (strchr (operand->buf, '%') != NULL) ? 14 : 13);
   3553       arf = ((mod == 12) ? operand->buf[3] - '0' :
   3554 	     (mod == 15) ? 0 : operand->buf[4] - '0');
   3555 
   3556       insn->opcode[1].addr_expr = operand->exp;
   3557 
   3558       if (operand->exp.X_op == O_constant)
   3559 	insn->opcode[1].word = operand->exp.X_add_number;
   3560       else
   3561 	{
   3562 	  insn->opcode[1].word = 0;
   3563 	  insn->opcode[1].r_nchars = 2;
   3564 	  insn->opcode[1].r_type = BFD_RELOC_TIC54X_16_OF_23;
   3565 	  insn->opcode[1].unresolved = 1;
   3566 	}
   3567     }
   3568   else if (strncasecmp (operand->buf, "*sp (", 4) == 0)
   3569     {
   3570       /* Stack offsets look the same as 7-bit direct addressing.  */
   3571       return encode_address (insn, operand);
   3572     }
   3573   else
   3574     {
   3575       arf = (TOUPPER (operand->buf[1]) == 'A' ?
   3576 	     operand->buf[3] : operand->buf[4]) - '0';
   3577 
   3578       if (operand->buf[1] == '+')
   3579 	{
   3580 	  mod = 3;		    /* *+ARx  */
   3581 	  if (insn->tm->flags & FL_SMR)
   3582 	    as_warn (_("Address mode *+ARx is write-only. "
   3583 		       "Results of reading are undefined."));
   3584 	}
   3585       else if (operand->buf[4] == '\0')
   3586 	mod = 0;		    /* *ARx  */
   3587       else if (operand->buf[5] == '\0')
   3588 	mod = (operand->buf[4] == '-' ? 1 : 2); /* *ARx+ / *ARx-  */
   3589       else if (operand->buf[6] == '\0')
   3590 	{
   3591 	  if (operand->buf[5] == '0')
   3592 	    mod = (operand->buf[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0  */
   3593 	  else
   3594 	    mod = (operand->buf[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-%  */
   3595 	}
   3596       else if (TOUPPER (operand->buf[6]) == 'B')
   3597 	mod = (operand->buf[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B  */
   3598       else if (TOUPPER (operand->buf[6]) == '%')
   3599 	mod = (operand->buf[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0%  */
   3600       else
   3601 	{
   3602 	  as_bad (_("Unrecognized indirect address format \"%s\""),
   3603 		  operand->buf);
   3604 	  return 0;
   3605 	}
   3606     }
   3607 
   3608   insn->opcode[0].word |= 0x80 | (mod << 3) | arf;
   3609 
   3610   return 1;
   3611 }
   3612 
   3613 static int
   3614 encode_integer (tic54x_insn *insn,
   3615 		struct opstruct *operand,
   3616 		int which,
   3617 		int min,
   3618 		int max,
   3619 		unsigned short mask)
   3620 {
   3621   long parse, integer;
   3622 
   3623   insn->opcode[which].addr_expr = operand->exp;
   3624 
   3625   if (operand->exp.X_op == O_constant)
   3626     {
   3627       parse = operand->exp.X_add_number;
   3628       /* Hack -- fixup for 16-bit hex quantities that get converted positive
   3629 	 instead of negative.  */
   3630       if ((parse & 0x8000) && min == -32768 && max == 32767)
   3631 	integer = (short) parse;
   3632       else
   3633 	integer = parse;
   3634 
   3635       if (integer >= min && integer <= max)
   3636 	{
   3637 	  insn->opcode[which].word |= (integer & mask);
   3638 	  return 1;
   3639 	}
   3640       as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
   3641 	      operand->buf, min, max);
   3642     }
   3643   else
   3644     {
   3645       if (insn->opcode[which].addr_expr.X_op == O_constant)
   3646 	{
   3647 	  insn->opcode[which].word |=
   3648 	    insn->opcode[which].addr_expr.X_add_number & mask;
   3649 	}
   3650       else
   3651 	{
   3652 	  /* Do the fixup later; just store the expression.  */
   3653 	  bfd_reloc_code_real_type rtype =
   3654 	    (mask == 0x1FF ? BFD_RELOC_TIC54X_PARTMS9 :
   3655 	     mask == 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23 :
   3656 	     mask == 0x7F ? BFD_RELOC_TIC54X_PARTLS7 : BFD_RELOC_8);
   3657 	  int size = (mask == 0x1FF || mask == 0xFFFF) ? 2 : 1;
   3658 
   3659 	  if (rtype == BFD_RELOC_8)
   3660 	    as_bad (_("Error in relocation handling"));
   3661 
   3662 	  insn->opcode[which].r_nchars = size;
   3663 	  insn->opcode[which].r_type = rtype;
   3664 	  insn->opcode[which].unresolved = 1;
   3665 	}
   3666 
   3667       return 1;
   3668     }
   3669 
   3670   return 0;
   3671 }
   3672 
   3673 static int
   3674 encode_condition (tic54x_insn *insn, struct opstruct *operand)
   3675 {
   3676   symbol *cc = (symbol *) hash_find (cc_hash, operand->buf);
   3677   if (!cc)
   3678     {
   3679       as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
   3680       return 0;
   3681     }
   3682 #define CC_GROUP 0x40
   3683 #define CC_ACC   0x08
   3684 #define CATG_A1  0x07
   3685 #define CATG_B1  0x30
   3686 #define CATG_A2  0x30
   3687 #define CATG_B2  0x0C
   3688 #define CATG_C2  0x03
   3689   /* Disallow group 1 conditions mixed with group 2 conditions
   3690      if group 1, allow only one category A and one category B
   3691      if group 2, allow only one each of category A, B, and C.  */
   3692   if (((insn->opcode[0].word & 0xFF) != 0))
   3693     {
   3694       if ((insn->opcode[0].word & CC_GROUP) != (cc->value & CC_GROUP))
   3695 	{
   3696 	  as_bad (_("Condition \"%s\" does not match preceding group"),
   3697 		  operand->buf);
   3698 	  return 0;
   3699 	}
   3700       if (insn->opcode[0].word & CC_GROUP)
   3701 	{
   3702 	  if ((insn->opcode[0].word & CC_ACC) != (cc->value & CC_ACC))
   3703 	    {
   3704 	      as_bad (_("Condition \"%s\" uses a different accumulator from "
   3705 			"a preceding condition"),
   3706 		      operand->buf);
   3707 	      return 0;
   3708 	    }
   3709 	  if ((insn->opcode[0].word & CATG_A1) && (cc->value & CATG_A1))
   3710 	    {
   3711 	      as_bad (_("Only one comparison conditional allowed"));
   3712 	      return 0;
   3713 	    }
   3714 	  if ((insn->opcode[0].word & CATG_B1) && (cc->value & CATG_B1))
   3715 	    {
   3716 	      as_bad (_("Only one overflow conditional allowed"));
   3717 	      return 0;
   3718 	    }
   3719 	}
   3720       else if (   ((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2))
   3721 	       || ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2))
   3722 	       || ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
   3723 	{
   3724 	  as_bad (_("Duplicate %s conditional"), operand->buf);
   3725 	  return 0;
   3726 	}
   3727     }
   3728 
   3729   insn->opcode[0].word |= cc->value;
   3730   return 1;
   3731 }
   3732 
   3733 static int
   3734 encode_cc3 (tic54x_insn *insn, struct opstruct *operand)
   3735 {
   3736   symbol *cc3 = (symbol *) hash_find (cc3_hash, operand->buf);
   3737   int value = cc3 ? cc3->value : operand->exp.X_add_number << 8;
   3738 
   3739   if ((value & 0x0300) != value)
   3740     {
   3741       as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
   3742       return 0;
   3743     }
   3744   insn->opcode[0].word |= value;
   3745   return 1;
   3746 }
   3747 
   3748 static int
   3749 encode_arx (tic54x_insn *insn, struct opstruct *operand)
   3750 {
   3751   int arf = strlen (operand->buf) >= 3 ? operand->buf[2] - '0' : -1;
   3752 
   3753   if (strncasecmp ("ar", operand->buf, 2) || arf < 0 || arf > 7)
   3754     {
   3755       as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
   3756       return 0;
   3757     }
   3758   insn->opcode[0].word |= arf;
   3759   return 1;
   3760 }
   3761 
   3762 static int
   3763 encode_cc2 (tic54x_insn *insn, struct opstruct *operand)
   3764 {
   3765   symbol *cc2 = (symbol *) hash_find (cc2_hash, operand->buf);
   3766 
   3767   if (!cc2)
   3768     {
   3769       as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
   3770       return 0;
   3771     }
   3772   insn->opcode[0].word |= cc2->value;
   3773   return 1;
   3774 }
   3775 
   3776 static int
   3777 encode_operand (tic54x_insn *insn, enum optype type, struct opstruct *operand)
   3778 {
   3779   int ext = (insn->tm->flags & FL_EXT) != 0;
   3780 
   3781   if (type == OP_MMR && operand->exp.X_op != O_constant)
   3782     {
   3783       /* Disallow long-constant addressing for memory-mapped addressing.  */
   3784       if (insn->is_lkaddr)
   3785 	{
   3786 	  as_bad (_("lk addressing modes are invalid for memory-mapped "
   3787 		    "register addressing"));
   3788 	  return 0;
   3789 	}
   3790       type = OP_Smem;
   3791       /* Warn about *+ARx when used with MMR operands.  */
   3792       if (strncasecmp (operand->buf, "*+ar", 4) == 0)
   3793 	{
   3794 	  as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
   3795 		     "register addressing.  Resulting behavior is "
   3796 		     "undefined."));
   3797 	}
   3798     }
   3799 
   3800   switch (type)
   3801     {
   3802     case OP_None:
   3803       return 1;
   3804     case OP_dmad:
   3805       /* 16-bit immediate value.  */
   3806       return encode_dmad (insn, operand, 0);
   3807     case OP_SRC:
   3808       if (TOUPPER (*operand->buf) == 'B')
   3809 	{
   3810 	  insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 9);
   3811 	  if (insn->using_default_dst)
   3812 	    insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
   3813 	}
   3814       return 1;
   3815     case OP_RND:
   3816       /* Make sure this agrees with the OP_DST operand.  */
   3817       if (!((TOUPPER (operand->buf[0]) == 'B') ^
   3818 	    ((insn->opcode[0].word & (1 << 8)) != 0)))
   3819 	{
   3820 	  as_bad (_("Destination accumulator for each part of this parallel "
   3821 		    "instruction must be different"));
   3822 	  return 0;
   3823 	}
   3824       return 1;
   3825     case OP_SRC1:
   3826     case OP_DST:
   3827       if (TOUPPER (operand->buf[0]) == 'B')
   3828 	insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
   3829       return 1;
   3830     case OP_Xmem:
   3831     case OP_Ymem:
   3832       {
   3833 	int mod = (operand->buf[4] == '\0' ? 0 : /* *arx  */
   3834 		   operand->buf[4] == '-' ? 1 : /* *arx-  */
   3835 		   operand->buf[5] == '\0' ? 2 : 3); /* *arx+, *arx+0%  */
   3836 	int arf = operand->buf[3] - '0' - 2;
   3837 	int code = (mod << 2) | arf;
   3838 	insn->opcode[0].word |= (code << (type == OP_Xmem ? 4 : 0));
   3839 	return 1;
   3840       }
   3841     case OP_Lmem:
   3842     case OP_Smem:
   3843       if (!is_indirect (operand))
   3844 	return encode_address (insn, operand);
   3845       /* Fall through.  */
   3846     case OP_Sind:
   3847       return encode_indirect (insn, operand);
   3848     case OP_xpmad_ms7:
   3849       return encode_dmad (insn, operand, 2);
   3850     case OP_xpmad:
   3851       return encode_dmad (insn, operand, 1);
   3852     case OP_PA:
   3853     case OP_pmad:
   3854       return encode_dmad (insn, operand, 0);
   3855     case OP_ARX:
   3856       return encode_arx (insn, operand);
   3857     case OP_MMRX:
   3858     case OP_MMRY:
   3859     case OP_MMR:
   3860       {
   3861 	int value = operand->exp.X_add_number;
   3862 
   3863 	if (type == OP_MMR)
   3864 	  insn->opcode[0].word |= value;
   3865 	else
   3866 	  {
   3867 	    if (value < 16 || value > 24)
   3868 	      {
   3869 		as_bad (_("Memory mapped register \"%s\" out of range"),
   3870 			operand->buf);
   3871 		return 0;
   3872 	      }
   3873 	    if (type == OP_MMRX)
   3874 	      insn->opcode[0].word |= (value - 16) << 4;
   3875 	    else
   3876 	      insn->opcode[0].word |= (value - 16);
   3877 	  }
   3878 	return 1;
   3879       }
   3880     case OP_B:
   3881     case OP_A:
   3882       return 1;
   3883     case OP_SHFT:
   3884       return encode_integer (insn, operand, ext + insn->is_lkaddr,
   3885 			     0, 15, 0xF);
   3886     case OP_SHIFT:
   3887       return encode_integer (insn, operand, ext + insn->is_lkaddr,
   3888 			     -16, 15, 0x1F);
   3889     case OP_lk:
   3890       return encode_integer (insn, operand, 1 + insn->is_lkaddr,
   3891 			     -32768, 32767, 0xFFFF);
   3892     case OP_CC:
   3893       return encode_condition (insn, operand);
   3894     case OP_CC2:
   3895       return encode_cc2 (insn, operand);
   3896     case OP_CC3:
   3897       return encode_cc3 (insn, operand);
   3898     case OP_BITC:
   3899       return encode_integer (insn, operand, 0, 0, 15, 0xF);
   3900     case OP_k8:
   3901       return encode_integer (insn, operand, 0, -128, 127, 0xFF);
   3902     case OP_123:
   3903       {
   3904 	int value = operand->exp.X_add_number;
   3905 	int code;
   3906 	if (value < 1 || value > 3)
   3907 	  {
   3908 	    as_bad (_("Invalid operand (use 1, 2, or 3)"));
   3909 	    return 0;
   3910 	  }
   3911 	code = value == 1 ? 0 : value == 2 ? 0x2 : 0x1;
   3912 	insn->opcode[0].word |= (code << 8);
   3913 	return 1;
   3914       }
   3915     case OP_031:
   3916       return encode_integer (insn, operand, 0, 0, 31, 0x1F);
   3917     case OP_k8u:
   3918       return encode_integer (insn, operand, 0, 0, 255, 0xFF);
   3919     case OP_lku:
   3920       return encode_integer (insn, operand, 1 + insn->is_lkaddr,
   3921 			     0, 65535, 0xFFFF);
   3922     case OP_SBIT:
   3923       {
   3924 	symbol *sbit = (symbol *) hash_find (sbit_hash, operand->buf);
   3925 	int value = is_absolute (operand) ?
   3926 	  operand->exp.X_add_number : (sbit ? sbit->value : -1);
   3927 	int reg = 0;
   3928 
   3929 	if (insn->opcount == 1)
   3930 	  {
   3931 	    if (!sbit)
   3932 	      {
   3933 		as_bad (_("A status register or status bit name is required"));
   3934 		return 0;
   3935 	      }
   3936 	    /* Guess the register based on the status bit; "ovb" is the last
   3937 	       status bit defined for st0.  */
   3938 	    if (sbit > (symbol *) hash_find (sbit_hash, "ovb"))
   3939 	      reg = 1;
   3940 	  }
   3941 	if (value == -1)
   3942 	  {
   3943 	    as_bad (_("Unrecognized status bit \"%s\""), operand->buf);
   3944 	    return 0;
   3945 	  }
   3946 	insn->opcode[0].word |= value;
   3947 	insn->opcode[0].word |= (reg << 9);
   3948 	return 1;
   3949       }
   3950     case OP_N:
   3951       if (strcasecmp (operand->buf, "st0") == 0
   3952 	  || strcasecmp (operand->buf, "st1") == 0)
   3953 	{
   3954 	  insn->opcode[0].word |=
   3955 	    ((unsigned short) (operand->buf[2] - '0')) << 9;
   3956 	  return 1;
   3957 	}
   3958       else if (operand->exp.X_op == O_constant
   3959 	       && (operand->exp.X_add_number == 0
   3960 		   || operand->exp.X_add_number == 1))
   3961 	{
   3962 	  insn->opcode[0].word |=
   3963 	    ((unsigned short) (operand->exp.X_add_number)) << 9;
   3964 	  return 1;
   3965 	}
   3966       as_bad (_("Invalid status register \"%s\""), operand->buf);
   3967       return 0;
   3968     case OP_k5:
   3969       return encode_integer (insn, operand, 0, -16, 15, 0x1F);
   3970     case OP_k3:
   3971       return encode_integer (insn, operand, 0, 0, 7, 0x7);
   3972     case OP_k9:
   3973       return encode_integer (insn, operand, 0, 0, 0x1FF, 0x1FF);
   3974     case OP_12:
   3975       if (operand->exp.X_add_number != 1
   3976 	  && operand->exp.X_add_number != 2)
   3977 	{
   3978 	  as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand->buf);
   3979 	  return 0;
   3980 	}
   3981       insn->opcode[0].word |= (operand->exp.X_add_number - 1) << 9;
   3982       return 1;
   3983     case OP_16:
   3984     case OP_T:
   3985     case OP_TS:
   3986     case OP_ASM:
   3987     case OP_TRN:
   3988     case OP_DP:
   3989     case OP_ARP:
   3990       /* No encoding necessary.  */
   3991       return 1;
   3992     default:
   3993       return 0;
   3994     }
   3995 
   3996   return 1;
   3997 }
   3998 
   3999 static void
   4000 emit_insn (tic54x_insn *insn)
   4001 {
   4002   int i;
   4003   flagword oldflags = bfd_get_section_flags (stdoutput, now_seg);
   4004   flagword flags = oldflags | SEC_CODE;
   4005 
   4006   if (! bfd_set_section_flags (stdoutput, now_seg, flags))
   4007         as_warn (_("error setting flags for \"%s\": %s"),
   4008                  bfd_section_name (stdoutput, now_seg),
   4009                  bfd_errmsg (bfd_get_error ()));
   4010 
   4011   for (i = 0; i < insn->words; i++)
   4012     {
   4013       int size = (insn->opcode[i].unresolved
   4014 		  && insn->opcode[i].r_type == BFD_RELOC_TIC54X_23) ? 4 : 2;
   4015       char *p = frag_more (size);
   4016 
   4017       if (size == 2)
   4018 	md_number_to_chars (p, (valueT) insn->opcode[i].word, 2);
   4019       else
   4020 	md_number_to_chars (p, (valueT) insn->opcode[i].word << 16, 4);
   4021 
   4022       if (insn->opcode[i].unresolved)
   4023 	fix_new_exp (frag_now, p - frag_now->fr_literal,
   4024 		     insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr,
   4025 		     FALSE, insn->opcode[i].r_type);
   4026     }
   4027 }
   4028 
   4029 /* Convert the operand strings into appropriate opcode values
   4030    return the total number of words used by the instruction.  */
   4031 
   4032 static int
   4033 build_insn (tic54x_insn *insn)
   4034 {
   4035   int i;
   4036 
   4037   /* Only non-parallel instructions support lk addressing.  */
   4038   if (!(insn->tm->flags & FL_PAR))
   4039     {
   4040       for (i = 0; i < insn->opcount; i++)
   4041 	{
   4042 	  if ((OPTYPE (insn->operands[i].type) == OP_Smem
   4043 	       || OPTYPE (insn->operands[i].type) == OP_Lmem
   4044 	       || OPTYPE (insn->operands[i].type) == OP_Sind)
   4045 	      && strchr (insn->operands[i].buf, '(')
   4046 	      /* Don't mistake stack-relative addressing for lk addressing.  */
   4047 	      && strncasecmp (insn->operands[i].buf, "*sp (", 4) != 0)
   4048 	    {
   4049 	      insn->is_lkaddr = 1;
   4050 	      insn->lkoperand = i;
   4051 	      break;
   4052 	    }
   4053 	}
   4054     }
   4055   insn->words = insn->tm->words + insn->is_lkaddr;
   4056 
   4057   insn->opcode[0].word = insn->tm->opcode;
   4058   if (insn->tm->flags & FL_EXT)
   4059     insn->opcode[1 + insn->is_lkaddr].word = insn->tm->opcode2;
   4060 
   4061   for (i = 0; i < insn->opcount; i++)
   4062     {
   4063       enum optype type = insn->operands[i].type;
   4064 
   4065       if (!encode_operand (insn, type, &insn->operands[i]))
   4066 	return 0;
   4067     }
   4068   if (insn->tm->flags & FL_PAR)
   4069     for (i = 0; i < insn->paropcount; i++)
   4070       {
   4071 	enum optype partype = insn->paroperands[i].type;
   4072 
   4073 	if (!encode_operand (insn, partype, &insn->paroperands[i]))
   4074 	  return 0;
   4075       }
   4076 
   4077   emit_insn (insn);
   4078 
   4079   return insn->words;
   4080 }
   4081 
   4082 static int
   4083 optimize_insn (tic54x_insn *insn)
   4084 {
   4085   /* Optimize some instructions, helping out the brain-dead programmer.  */
   4086 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
   4087   if (strcasecmp (insn->tm->name, "add") == 0)
   4088     {
   4089       if (insn->opcount > 1
   4090 	  && is_accumulator (&insn->operands[insn->opcount - 2])
   4091 	  && is_accumulator (&insn->operands[insn->opcount - 1])
   4092 	  && strcasecmp (insn->operands[insn->opcount - 2].buf,
   4093 			 insn->operands[insn->opcount - 1].buf) == 0)
   4094 	{
   4095 	  --insn->opcount;
   4096 	  insn->using_default_dst = 1;
   4097 	  return 1;
   4098 	}
   4099 
   4100       /* Try to collapse if Xmem and shift count is zero.  */
   4101       if ((OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
   4102 	   && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT
   4103 	   && is_zero (insn->operands[1]))
   4104 	  /* Or if Smem, shift is zero or absent, and SRC == DST.  */
   4105 	  || (OPTYPE (insn->tm->operand_types[0]) == OP_Smem
   4106 	      && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
   4107 	      && is_type (&insn->operands[1], OP_SHIFT)
   4108 	      && is_zero (insn->operands[1]) && insn->opcount == 3))
   4109 	{
   4110 	  insn->operands[1] = insn->operands[2];
   4111 	  insn->opcount = 2;
   4112 	  return 1;
   4113 	}
   4114     }
   4115   else if (strcasecmp (insn->tm->name, "ld") == 0)
   4116     {
   4117       if (insn->opcount == 3 && insn->operands[0].type != OP_SRC)
   4118 	{
   4119 	  if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
   4120 	       || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
   4121 	      && is_zero (insn->operands[1])
   4122 	      && (OPTYPE (insn->tm->operand_types[0]) != OP_lk
   4123 		  || (insn->operands[0].exp.X_op == O_constant
   4124 		      && insn->operands[0].exp.X_add_number <= 255
   4125 		      && insn->operands[0].exp.X_add_number >= 0)))
   4126 	    {
   4127 	      insn->operands[1] = insn->operands[2];
   4128 	      insn->opcount = 2;
   4129 	      return 1;
   4130 	    }
   4131 	}
   4132     }
   4133   else if (strcasecmp (insn->tm->name, "sth") == 0
   4134 	   || strcasecmp (insn->tm->name, "stl") == 0)
   4135     {
   4136       if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
   4137 	   || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
   4138 	  && is_zero (insn->operands[1]))
   4139 	{
   4140 	  insn->operands[1] = insn->operands[2];
   4141 	  insn->opcount = 2;
   4142 	  return 1;
   4143 	}
   4144     }
   4145   else if (strcasecmp (insn->tm->name, "sub") == 0)
   4146     {
   4147       if (insn->opcount > 1
   4148 	  && is_accumulator (&insn->operands[insn->opcount - 2])
   4149 	  && is_accumulator (&insn->operands[insn->opcount - 1])
   4150 	  && strcasecmp (insn->operands[insn->opcount - 2].buf,
   4151 			 insn->operands[insn->opcount - 1].buf) == 0)
   4152 	{
   4153 	  --insn->opcount;
   4154 	  insn->using_default_dst = 1;
   4155 	  return 1;
   4156 	}
   4157 
   4158       if (   ((OPTYPE (insn->tm->operand_types[0]) == OP_Smem
   4159 	    && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT)
   4160 	   || (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
   4161 	    && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT))
   4162 	  && is_zero (insn->operands[1])
   4163 	  && insn->opcount == 3)
   4164 	{
   4165 	  insn->operands[1] = insn->operands[2];
   4166 	  insn->opcount = 2;
   4167 	  return 1;
   4168 	}
   4169     }
   4170   return 0;
   4171 }
   4172 
   4173 /* Find a matching template if possible, and get the operand strings.  */
   4174 
   4175 static int
   4176 tic54x_parse_insn (tic54x_insn *insn, char *line)
   4177 {
   4178   insn->tm = (insn_template *) hash_find (op_hash, insn->mnemonic);
   4179   if (!insn->tm)
   4180     {
   4181       as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic);
   4182       return 0;
   4183     }
   4184 
   4185   insn->opcount = get_operands (insn->operands, line);
   4186   if (insn->opcount < 0)
   4187     return 0;
   4188 
   4189   /* Check each variation of operands for this mnemonic.  */
   4190   while (insn->tm->name && strcasecmp (insn->tm->name, insn->mnemonic) == 0)
   4191     {
   4192       if (insn->opcount >= insn->tm->minops
   4193 	  && insn->opcount <= insn->tm->maxops
   4194 	  && operands_match (insn, &insn->operands[0], insn->opcount,
   4195 			     insn->tm->operand_types,
   4196 			     insn->tm->minops, insn->tm->maxops))
   4197 	{
   4198 	  /* SUCCESS! now try some optimizations.  */
   4199 	  if (optimize_insn (insn))
   4200 	    {
   4201 	      insn->tm = (insn_template *) hash_find (op_hash,
   4202                                                       insn->mnemonic);
   4203 	      continue;
   4204 	    }
   4205 
   4206 	  return 1;
   4207 	}
   4208       ++(insn->tm);
   4209     }
   4210   as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
   4211 	  line, insn->mnemonic);
   4212   return 0;
   4213 }
   4214 
   4215 /* We set this in start_line_hook, 'cause if we do a line replacement, we
   4216    won't be able to see the next line.  */
   4217 static int parallel_on_next_line_hint = 0;
   4218 
   4219 /* See if this is part of a parallel instruction
   4220    Look for a subsequent line starting with "||".  */
   4221 
   4222 static int
   4223 next_line_shows_parallel (char *next_line)
   4224 {
   4225   /* Look for the second half.  */
   4226   while (ISSPACE (*next_line))
   4227     ++next_line;
   4228 
   4229   return (next_line[0] == PARALLEL_SEPARATOR
   4230 	  && next_line[1] == PARALLEL_SEPARATOR);
   4231 }
   4232 
   4233 static int
   4234 tic54x_parse_parallel_insn_firstline (tic54x_insn *insn, char *line)
   4235 {
   4236   insn->tm = (insn_template *) hash_find (parop_hash, insn->mnemonic);
   4237   if (!insn->tm)
   4238     {
   4239       as_bad (_("Unrecognized parallel instruction \"%s\""),
   4240 	      insn->mnemonic);
   4241       return 0;
   4242     }
   4243 
   4244   while (insn->tm->name && strcasecmp (insn->tm->name,
   4245                                        insn->mnemonic) == 0)
   4246     {
   4247       insn->opcount = get_operands (insn->operands, line);
   4248       if (insn->opcount < 0)
   4249 	return 0;
   4250       if (insn->opcount == 2
   4251 	  && operands_match (insn, &insn->operands[0], insn->opcount,
   4252 			     insn->tm->operand_types, 2, 2))
   4253 	{
   4254 	  return 1;
   4255 	}
   4256       ++(insn->tm);
   4257     }
   4258   /* Didn't find a matching parallel; try for a normal insn.  */
   4259   return 0;
   4260 }
   4261 
   4262 /* Parse the second line of a two-line parallel instruction.  */
   4263 
   4264 static int
   4265 tic54x_parse_parallel_insn_lastline (tic54x_insn *insn, char *line)
   4266 {
   4267   int valid_mnemonic = 0;
   4268 
   4269   insn->paropcount = get_operands (insn->paroperands, line);
   4270   while (insn->tm->name && strcasecmp (insn->tm->name,
   4271 				       insn->mnemonic) == 0)
   4272     {
   4273       if (strcasecmp (insn->tm->parname, insn->parmnemonic) == 0)
   4274 	{
   4275 	  valid_mnemonic = 1;
   4276 
   4277 	  if (insn->paropcount >= insn->tm->minops
   4278 	      && insn->paropcount <= insn->tm->maxops
   4279 	      && operands_match (insn, insn->paroperands,
   4280 				 insn->paropcount,
   4281 				 insn->tm->paroperand_types,
   4282 				 insn->tm->minops, insn->tm->maxops))
   4283 	    return 1;
   4284 	}
   4285       ++(insn->tm);
   4286     }
   4287   if (valid_mnemonic)
   4288     as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
   4289 	    insn->parmnemonic);
   4290   else
   4291     as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
   4292 	    insn->mnemonic, insn->parmnemonic);
   4293 
   4294   return 0;
   4295 }
   4296 
   4297 /* If quotes found, return copy of line up to closing quote;
   4298    otherwise up until terminator.
   4299    If it's a string, pass as-is; otherwise attempt substitution symbol
   4300    replacement on the value.  */
   4301 
   4302 static char *
   4303 subsym_get_arg (char *line, char *terminators, char **str, int nosub)
   4304 {
   4305   char *ptr = line;
   4306   char *endp;
   4307   int is_string = *line == '"';
   4308   int is_char = ISDIGIT (*line);
   4309 
   4310   if (is_char)
   4311     {
   4312       while (ISDIGIT (*ptr))
   4313 	++ptr;
   4314       endp = ptr;
   4315       *str = xmalloc (ptr - line + 1);
   4316       strncpy (*str, line, ptr - line);
   4317       (*str)[ptr - line] = 0;
   4318     }
   4319   else if (is_string)
   4320     {
   4321       char *savedp = input_line_pointer;
   4322       int len;
   4323 
   4324       input_line_pointer = ptr;
   4325       *str = demand_copy_C_string (&len);
   4326       endp = input_line_pointer;
   4327       input_line_pointer = savedp;
   4328 
   4329       /* Do forced substitutions if requested.  */
   4330       if (!nosub && **str == ':')
   4331 	*str = subsym_substitute (*str, 1);
   4332     }
   4333   else
   4334     {
   4335       char *term = terminators;
   4336       char *value = NULL;
   4337 
   4338       while (*ptr && *ptr != *term)
   4339 	{
   4340 	  if (!*term)
   4341 	    {
   4342 	      term = terminators;
   4343 	      ++ptr;
   4344 	    }
   4345 	  else
   4346 	    ++term;
   4347 	}
   4348       endp = ptr;
   4349       *str = xmalloc (ptr - line + 1);
   4350       strncpy (*str, line, ptr - line);
   4351       (*str)[ptr - line] = 0;
   4352       /* Do simple substitution, if available.  */
   4353       if (!nosub && (value = subsym_lookup (*str, macro_level)) != NULL)
   4354 	*str = value;
   4355     }
   4356 
   4357   return endp;
   4358 }
   4359 
   4360 /* Replace the given substitution string.
   4361    We start at the innermost macro level, so that existing locals remain local
   4362    Note: we're treating macro args identically to .var's; I don't know if
   4363    that's compatible w/TI's assembler.  */
   4364 
   4365 static void
   4366 subsym_create_or_replace (char *name, char *value)
   4367 {
   4368   int i;
   4369 
   4370   for (i = macro_level; i > 0; i--)
   4371     {
   4372       if (hash_find (subsym_hash[i], name))
   4373 	{
   4374 	  hash_replace (subsym_hash[i], name, value);
   4375 	  return;
   4376 	}
   4377     }
   4378   if (hash_find (subsym_hash[0], name))
   4379     hash_replace (subsym_hash[0], name, value);
   4380   else
   4381     hash_insert (subsym_hash[0], name, value);
   4382 }
   4383 
   4384 /* Look up the substitution string replacement for the given symbol.
   4385    Start with the innermost macro substitution table given and work
   4386    outwards.  */
   4387 
   4388 static char *
   4389 subsym_lookup (char *name, int nest_level)
   4390 {
   4391   char *value = hash_find (subsym_hash[nest_level], name);
   4392 
   4393   if (value || nest_level == 0)
   4394     return value;
   4395 
   4396   return subsym_lookup (name, nest_level - 1);
   4397 }
   4398 
   4399 /* Do substitution-symbol replacement on the given line (recursively).
   4400    return the argument if no substitution was done
   4401 
   4402    Also look for built-in functions ($func (arg)) and local labels.
   4403 
   4404    If FORCED is set, look for forced substitutions of the form ':SYMBOL:'.  */
   4405 
   4406 static char *
   4407 subsym_substitute (char *line, int forced)
   4408 {
   4409   /* For each apparent symbol, see if it's a substitution symbol, and if so,
   4410      replace it in the input.  */
   4411   char *replacement; /* current replacement for LINE.  */
   4412   char *head; /* Start of line.  */
   4413   char *ptr; /* Current examination point.  */
   4414   int changed = 0; /* Did we make a substitution?  */
   4415   int eval_line = 0; /* Is this line a .eval/.asg statement?  */
   4416   int eval_symbol = 0; /* Are we in the middle of the symbol for
   4417                           .eval/.asg?  */
   4418   char *eval_end = NULL;
   4419   int recurse = 1;
   4420   int line_conditional = 0;
   4421   char *tmp;
   4422 
   4423   /* Work with a copy of the input line.  */
   4424   replacement = xmalloc (strlen (line) + 1);
   4425   strcpy (replacement, line);
   4426 
   4427   ptr = head = replacement;
   4428 
   4429   /* Flag lines where we might need to replace a single '=' with two;
   4430      GAS uses single '=' to assign macro args values, and possibly other
   4431      places, so limit what we replace.  */
   4432   if (strstr (line, ".if")
   4433       || strstr (line, ".elseif")
   4434       || strstr (line, ".break"))
   4435     line_conditional = 1;
   4436 
   4437   /* Watch out for .eval, so that we avoid doing substitution on the
   4438      symbol being assigned a value.  */
   4439   if (strstr (line, ".eval") || strstr (line, ".asg"))
   4440     eval_line = 1;
   4441 
   4442   /* If it's a macro definition, don't do substitution on the argument
   4443      names.  */
   4444   if (strstr (line, ".macro"))
   4445     return line;
   4446 
   4447   while (!is_end_of_line[(int) *ptr])
   4448     {
   4449       int current_char = *ptr;
   4450 
   4451       /* Need to update this since LINE may have been modified.  */
   4452       if (eval_line)
   4453 	eval_end = strrchr (ptr, ',');
   4454 
   4455       /* Replace triple double quotes with bounding quote/escapes.  */
   4456       if (current_char == '"' && ptr[1] == '"' && ptr[2] == '"')
   4457 	{
   4458 	  ptr[1] = '\\';
   4459 	  tmp = strstr (ptr + 2, "\"\"\"");
   4460 	  if (tmp)
   4461 	    tmp[0] = '\\';
   4462 	  changed = 1;
   4463 	}
   4464 
   4465       /* Replace a single '=' with a '==';
   4466 	 for compatibility with older code only.  */
   4467       if (line_conditional && current_char == '=')
   4468 	{
   4469 	  if (ptr[1] == '=')
   4470 	    {
   4471 	      ptr += 2;
   4472 	      continue;
   4473 	    }
   4474 	  *ptr++ = '\0';
   4475 	  tmp = xmalloc (strlen (head) + 2 + strlen (ptr) + 1);
   4476 	  sprintf (tmp, "%s==%s", head, ptr);
   4477 	  /* Continue examining after the '=='.  */
   4478 	  ptr = tmp + strlen (head) + 2;
   4479 	  free (replacement);
   4480 	  head = replacement = tmp;
   4481 	  changed = 1;
   4482 	}
   4483 
   4484       /* Flag when we've reached the symbol part of .eval/.asg.  */
   4485       if (eval_line && ptr >= eval_end)
   4486 	eval_symbol = 1;
   4487 
   4488       /* For each apparent symbol, see if it's a substitution symbol, and if
   4489 	 so, replace it in the input.  */
   4490       if ((forced && current_char == ':')
   4491 	  || (!forced && is_name_beginner (current_char)))
   4492 	{
   4493 	  char *name; /* Symbol to be replaced.  */
   4494 	  char *savedp = input_line_pointer;
   4495 	  int c;
   4496 	  char *value = NULL;
   4497 	  char *tail; /* Rest of line after symbol.  */
   4498 
   4499 	  /* Skip the colon.  */
   4500 	  if (forced)
   4501 	    ++ptr;
   4502 
   4503 	  name = input_line_pointer = ptr;
   4504 	  c = get_symbol_end ();
   4505 	  /* '?' is not normally part of a symbol, but it IS part of a local
   4506 	     label.  */
   4507 	  if (c == '?')
   4508 	    {
   4509 	      *input_line_pointer++ = c;
   4510 	      c = *input_line_pointer;
   4511 	      *input_line_pointer = '\0';
   4512 	    }
   4513 	  /* Avoid infinite recursion; if a symbol shows up a second time for
   4514 	     substitution, leave it as is.  */
   4515 	  if (hash_find (subsym_recurse_hash, name) == NULL)
   4516 	    value = subsym_lookup (name, macro_level);
   4517 	  else
   4518 	    as_warn (_("%s symbol recursion stopped at "
   4519 		       "second appearance of '%s'"),
   4520 		     forced ? "Forced substitution" : "Substitution", name);
   4521 	  ptr = tail = input_line_pointer;
   4522 	  input_line_pointer = savedp;
   4523 
   4524 	  /* Check for local labels; replace them with the appropriate
   4525 	     substitution.  */
   4526 	  if ((*name == '$' && ISDIGIT (name[1]) && name[2] == '\0')
   4527 	      || name[strlen (name) - 1] == '?')
   4528 	    {
   4529 	      /* Use an existing identifier for that label if, available, or
   4530 		 create a new, unique identifier.  */
   4531 	      value = hash_find (local_label_hash[macro_level], name);
   4532 	      if (value == NULL)
   4533 		{
   4534 		  char digit[11];
   4535 		  char *namecopy = strcpy (xmalloc (strlen (name) + 1), name);
   4536 
   4537 		  value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
   4538 				  name);
   4539 		  if (*value != '$')
   4540 		    value[strlen (value) - 1] = '\0';
   4541 		  sprintf (digit, ".%d", local_label_id++);
   4542 		  strcat (value, digit);
   4543 		  hash_insert (local_label_hash[macro_level], namecopy, value);
   4544 		}
   4545 	      /* Indicate where to continue looking for substitutions.  */
   4546 	      ptr = tail;
   4547 	    }
   4548 	  /* Check for built-in subsym and math functions.  */
   4549 	  else if (value != NULL && *name == '$')
   4550 	    {
   4551 	      subsym_proc_entry *entry = (subsym_proc_entry *) value;
   4552 	      math_proc_entry *math_entry = hash_find (math_hash, name);
   4553 	      char *arg1, *arg2 = NULL;
   4554 
   4555 	      *ptr = c;
   4556 	      if (entry == NULL)
   4557 		{
   4558 		  as_bad (_("Unrecognized substitution symbol function"));
   4559 		  break;
   4560 		}
   4561 	      else if (*ptr != '(')
   4562 		{
   4563 		  as_bad (_("Missing '(' after substitution symbol function"));
   4564 		  break;
   4565 		}
   4566 	      ++ptr;
   4567 	      if (math_entry != NULL)
   4568 		{
   4569 		  float farg1, farg2 = 0;
   4570 		  volatile float fresult;
   4571 
   4572 		  farg1 = (float) strtod (ptr, &ptr);
   4573 		  if (math_entry->nargs == 2)
   4574 		    {
   4575 		      if (*ptr++ != ',')
   4576 			{
   4577 			  as_bad (_("Expecting second argument"));
   4578 			  break;
   4579 			}
   4580 		      farg2 = (float) strtod (ptr, &ptr);
   4581 		    }
   4582 		  fresult = (*math_entry->proc) (farg1, farg2);
   4583 		  value = xmalloc (128);
   4584 		  if (math_entry->int_return)
   4585 		    sprintf (value, "%d", (int) fresult);
   4586 		  else
   4587 		    sprintf (value, "%f", fresult);
   4588 		  if (*ptr++ != ')')
   4589 		    {
   4590 		      as_bad (_("Extra junk in function call, expecting ')'"));
   4591 		      break;
   4592 		    }
   4593 		  /* Don't bother recursing; the replacement isn't a
   4594                      symbol.  */
   4595 		  recurse = 0;
   4596 		}
   4597 	      else
   4598 		{
   4599 		  int val;
   4600 		  int arg_type[2] = { *ptr == '"' , 0 };
   4601 		  int ismember = !strcmp (entry->name, "$ismember");
   4602 
   4603 		  /* Parse one or two args, which must be a substitution
   4604 		     symbol, string or a character-string constant.  */
   4605 		  /* For all functions, a string or substitution symbol may be
   4606 		     used, with the following exceptions:
   4607 		     firstch/lastch: 2nd arg must be character constant
   4608 		     ismember: both args must be substitution symbols.  */
   4609 		  ptr = subsym_get_arg (ptr, ",)", &arg1, ismember);
   4610 		  if (!arg1)
   4611 		    break;
   4612 		  if (entry->nargs == 2)
   4613 		    {
   4614 		      if (*ptr++ != ',')
   4615 			{
   4616 			  as_bad (_("Function expects two arguments"));
   4617 			  break;
   4618 			}
   4619 		      /* Character constants are converted to numerics
   4620 			 by the preprocessor.  */
   4621 		      arg_type[1] = (ISDIGIT (*ptr)) ? 2 : (*ptr == '"');
   4622 		      ptr = subsym_get_arg (ptr, ")", &arg2, ismember);
   4623 		    }
   4624 		  /* Args checking.  */
   4625 		  if ((!strcmp (entry->name, "$firstch")
   4626 		       || !strcmp (entry->name, "$lastch"))
   4627 		      && arg_type[1] != 2)
   4628 		    {
   4629 		      as_bad (_("Expecting character constant argument"));
   4630 		      break;
   4631 		    }
   4632 		  if (ismember
   4633 		      && (arg_type[0] != 0 || arg_type[1] != 0))
   4634 		    {
   4635 		      as_bad (_("Both arguments must be substitution symbols"));
   4636 		      break;
   4637 		    }
   4638 		  if (*ptr++ != ')')
   4639 		    {
   4640 		      as_bad (_("Extra junk in function call, expecting ')'"));
   4641 		      break;
   4642 		    }
   4643 		  val = (*entry->proc) (arg1, arg2);
   4644 		  value = xmalloc (64);
   4645 		  sprintf (value, "%d", val);
   4646 		}
   4647 	      /* Fix things up to replace the entire expression, not just the
   4648 		 function name.  */
   4649 	      tail = ptr;
   4650 	      c = *tail;
   4651 	    }
   4652 
   4653 	  if (value != NULL && !eval_symbol)
   4654 	    {
   4655 	      /* Replace the symbol with its string replacement and
   4656 		 continue.  Recursively replace VALUE until either no
   4657 		 substitutions are performed, or a substitution that has been
   4658 		 previously made is encountered again.
   4659 
   4660 		 put the symbol into the recursion hash table so we only
   4661 		 try to replace a symbol once.  */
   4662 	      if (recurse)
   4663 		{
   4664 		  hash_insert (subsym_recurse_hash, name, name);
   4665 		  value = subsym_substitute (value, macro_level > 0);
   4666 		  hash_delete (subsym_recurse_hash, name, FALSE);
   4667 		}
   4668 
   4669 	      /* Temporarily zero-terminate where the symbol started.  */
   4670 	      *name = 0;
   4671 	      if (forced)
   4672 		{
   4673 		  if (c == '(')
   4674 		    {
   4675 		      /* Subscripted substitution symbol -- use just the
   4676 			 indicated portion of the string; the description
   4677 			 kinda indicates that forced substitution is not
   4678 			 supposed to be recursive, but I'm not sure.  */
   4679 		      unsigned beg, len = 1; /* default to a single char */
   4680 		      char *newval = strcpy (xmalloc (strlen (value) + 1),
   4681 					     value);
   4682 
   4683 		      savedp = input_line_pointer;
   4684 		      input_line_pointer = tail + 1;
   4685 		      beg = get_absolute_expression ();
   4686 		      if (beg < 1)
   4687 			{
   4688 			  as_bad (_("Invalid subscript (use 1 to %d)"),
   4689 				  (int) strlen (value));
   4690 			  break;
   4691 			}
   4692 		      if (*input_line_pointer == ',')
   4693 			{
   4694 			  ++input_line_pointer;
   4695 			  len = get_absolute_expression ();
   4696 			  if (beg + len > strlen (value))
   4697 			    {
   4698 			      as_bad (_("Invalid length (use 0 to %d"),
   4699 				      (int) strlen (value) - beg);
   4700 			      break;
   4701 			    }
   4702 			}
   4703 		      newval += beg - 1;
   4704 		      newval[len] = 0;
   4705 		      tail = input_line_pointer;
   4706 		      if (*tail++ != ')')
   4707 			{
   4708 			  as_bad (_("Missing ')' in subscripted substitution "
   4709 				    "symbol expression"));
   4710 			  break;
   4711 			}
   4712 		      c = *tail;
   4713 		      input_line_pointer = savedp;
   4714 
   4715 		      value = newval;
   4716 		    }
   4717 		  name[-1] = 0;
   4718 		}
   4719 	      tmp = xmalloc (strlen (head) + strlen (value) +
   4720 			     strlen (tail + 1) + 2);
   4721 	      strcpy (tmp, head);
   4722 	      strcat (tmp, value);
   4723 	      /* Make sure forced substitutions are properly terminated.  */
   4724 	      if (forced)
   4725 		{
   4726 		  if (c != ':')
   4727 		    {
   4728 		      as_bad (_("Missing forced substitution terminator ':'"));
   4729 		      break;
   4730 		    }
   4731 		  ++tail;
   4732 		}
   4733 	      else
   4734 		/* Restore the character after the symbol end.  */
   4735 		*tail = c;
   4736 	      strcat (tmp, tail);
   4737 	      /* Continue examining after the replacement value.  */
   4738 	      ptr = tmp + strlen (head) + strlen (value);
   4739 	      free (replacement);
   4740 	      head = replacement = tmp;
   4741 	      changed = 1;
   4742 	    }
   4743 	  else
   4744 	    *ptr = c;
   4745 	}
   4746       else
   4747 	{
   4748 	  ++ptr;
   4749 	}
   4750     }
   4751 
   4752   if (changed)
   4753     return replacement;
   4754   else
   4755     return line;
   4756 }
   4757 
   4758 /* We use this to handle substitution symbols
   4759    hijack input_line_pointer, replacing it with our substituted string.
   4760 
   4761    .sslist should enable listing the line after replacements are made...
   4762 
   4763    returns the new buffer limit.  */
   4764 
   4765 void
   4766 tic54x_start_line_hook (void)
   4767 {
   4768   char *line, *endp;
   4769   char *replacement = NULL;
   4770 
   4771   /* Work with a copy of the input line, including EOL char.  */
   4772   endp = input_line_pointer;
   4773   while (!is_end_of_line[(int) *endp++])
   4774     ;
   4775   line = xmalloc (endp - input_line_pointer + 1);
   4776   strncpy (line, input_line_pointer, endp - input_line_pointer + 1);
   4777   line[endp - input_line_pointer] = 0;
   4778 
   4779   /* Scan ahead for parallel insns.  */
   4780   parallel_on_next_line_hint = next_line_shows_parallel (endp);
   4781 
   4782   /* If within a macro, first process forced replacements.  */
   4783   if (macro_level > 0)
   4784     replacement = subsym_substitute (line, 1);
   4785   else
   4786     replacement = line;
   4787   replacement = subsym_substitute (replacement, 0);
   4788 
   4789   if (replacement != line)
   4790     {
   4791       char *tmp = replacement;
   4792       char *comment = strchr (replacement, ';');
   4793       char endc = replacement[strlen (replacement) - 1];
   4794 
   4795       /* Clean up the replacement; we'd prefer to have this done by the
   4796 	 standard preprocessing equipment (maybe do_scrub_chars?)
   4797 	 but for now, do a quick-and-dirty.  */
   4798       if (comment != NULL)
   4799 	{
   4800 	  comment[0] = endc;
   4801 	  comment[1] = 0;
   4802 	  --comment;
   4803 	}
   4804       else
   4805 	comment = replacement + strlen (replacement) - 1;
   4806 
   4807       /* Trim trailing whitespace.  */
   4808       while (ISSPACE (*comment))
   4809 	{
   4810 	  comment[0] = endc;
   4811 	  comment[1] = 0;
   4812 	  --comment;
   4813 	}
   4814 
   4815       /* Compact leading whitespace.  */
   4816       while (ISSPACE (tmp[0]) && ISSPACE (tmp[1]))
   4817 	++tmp;
   4818 
   4819       input_line_pointer = endp;
   4820       input_scrub_insert_line (tmp);
   4821       free (replacement);
   4822       free (line);
   4823       /* Keep track of whether we've done a substitution.  */
   4824       substitution_line = 1;
   4825     }
   4826   else
   4827     {
   4828       /* No change.  */
   4829       free (line);
   4830       substitution_line = 0;
   4831     }
   4832 }
   4833 
   4834 /* This is the guts of the machine-dependent assembler.  STR points to a
   4835    machine dependent instruction.  This function is supposed to emit
   4836    the frags/bytes it assembles to.  */
   4837 void
   4838 md_assemble (char *line)
   4839 {
   4840   static int repeat_slot = 0;
   4841   static int delay_slots = 0; /* How many delay slots left to fill?  */
   4842   static int is_parallel = 0;
   4843   static tic54x_insn insn;
   4844   char *lptr;
   4845   char *savedp = input_line_pointer;
   4846   int c;
   4847 
   4848   input_line_pointer = line;
   4849   c = get_symbol_end ();
   4850 
   4851   if (cpu == VNONE)
   4852     cpu = V542;
   4853   if (address_mode_needs_set)
   4854     {
   4855       set_address_mode (amode);
   4856       address_mode_needs_set = 0;
   4857     }
   4858   if (cpu_needs_set)
   4859     {
   4860       set_cpu (cpu);
   4861       cpu_needs_set = 0;
   4862     }
   4863   assembly_begun = 1;
   4864 
   4865   if (is_parallel)
   4866     {
   4867       is_parallel = 0;
   4868 
   4869       strcpy (insn.parmnemonic, line);
   4870       lptr = input_line_pointer;
   4871       *lptr = c;
   4872       input_line_pointer = savedp;
   4873 
   4874       if (tic54x_parse_parallel_insn_lastline (&insn, lptr))
   4875 	{
   4876 	  int words = build_insn (&insn);
   4877 
   4878 	  if (delay_slots != 0)
   4879 	    {
   4880 	      if (words > delay_slots)
   4881 		{
   4882 		  as_bad (_("Instruction does not fit in available delay "
   4883 			    "slots (%d-word insn, %d slots left)"),
   4884 			  words, delay_slots);
   4885 		  delay_slots = 0;
   4886 		  return;
   4887 		}
   4888 	      delay_slots -= words;
   4889 	    }
   4890 	}
   4891       return;
   4892     }
   4893 
   4894   memset (&insn, 0, sizeof (insn));
   4895   strcpy (insn.mnemonic, line);
   4896   lptr = input_line_pointer;
   4897   *lptr = c;
   4898   input_line_pointer = savedp;
   4899 
   4900   /* See if this line is part of a parallel instruction; if so, either this
   4901      line or the next line will have the "||" specifier preceding the
   4902      mnemonic, and we look for it in the parallel insn hash table.  */
   4903   if (strstr (line, "||") != NULL || parallel_on_next_line_hint)
   4904     {
   4905       char *tmp = strstr (line, "||");
   4906       if (tmp != NULL)
   4907 	*tmp = '\0';
   4908 
   4909       if (tic54x_parse_parallel_insn_firstline (&insn, lptr))
   4910 	{
   4911 	  is_parallel = 1;
   4912 	  /* If the parallel part is on the same line, process it now,
   4913 	     otherwise let the assembler pick up the next line for us.  */
   4914 	  if (tmp != NULL)
   4915 	    {
   4916 	      while (ISSPACE (tmp[2]))
   4917 		++tmp;
   4918 	      md_assemble (tmp + 2);
   4919 	    }
   4920 	}
   4921       else
   4922 	{
   4923 	  as_bad (_("Unrecognized parallel instruction '%s'"), line);
   4924 	}
   4925       return;
   4926     }
   4927 
   4928   if (tic54x_parse_insn (&insn, lptr))
   4929     {
   4930       int words;
   4931 
   4932       if ((insn.tm->flags & FL_LP)
   4933 	  && cpu != V545LP && cpu != V546LP)
   4934 	{
   4935 	  as_bad (_("Instruction '%s' requires an LP cpu version"),
   4936 		  insn.tm->name);
   4937 	  return;
   4938 	}
   4939       if ((insn.tm->flags & FL_FAR)
   4940 	  && amode != far_mode)
   4941 	{
   4942 	  as_bad (_("Instruction '%s' requires far mode addressing"),
   4943 		  insn.tm->name);
   4944 	  return;
   4945 	}
   4946 
   4947       words = build_insn (&insn);
   4948 
   4949       /* Is this instruction in a delay slot?  */
   4950       if (delay_slots)
   4951 	{
   4952 	  if (words > delay_slots)
   4953 	    {
   4954 	      as_warn (_("Instruction does not fit in available delay "
   4955 			 "slots (%d-word insn, %d slots left). "
   4956 			 "Resulting behavior is undefined."),
   4957 		       words, delay_slots);
   4958 	      delay_slots = 0;
   4959 	      return;
   4960 	    }
   4961 	  /* Branches in delay slots are not allowed.  */
   4962 	  if (insn.tm->flags & FL_BMASK)
   4963 	    {
   4964 	      as_warn (_("Instructions which cause PC discontinuity are not "
   4965 			 "allowed in a delay slot. "
   4966 			 "Resulting behavior is undefined."));
   4967 	    }
   4968 	  delay_slots -= words;
   4969 	}
   4970 
   4971       /* Is this instruction the target of a repeat?  */
   4972       if (repeat_slot)
   4973 	{
   4974 	  if (insn.tm->flags & FL_NR)
   4975 	    as_warn (_("'%s' is not repeatable. "
   4976 		       "Resulting behavior is undefined."),
   4977 		     insn.tm->name);
   4978 	  else if (insn.is_lkaddr)
   4979 	    as_warn (_("Instructions using long offset modifiers or absolute "
   4980 		       "addresses are not repeatable. "
   4981 		       "Resulting behavior is undefined."));
   4982 	  repeat_slot = 0;
   4983 	}
   4984 
   4985       /* Make sure we check the target of a repeat instruction.  */
   4986       if (insn.tm->flags & B_REPEAT)
   4987 	{
   4988 	  repeat_slot = 1;
   4989 	  /* FIXME -- warn if repeat_slot == 1 at EOF.  */
   4990 	}
   4991       /* Make sure we check our delay slots for validity.  */
   4992       if (insn.tm->flags & FL_DELAY)
   4993 	{
   4994 	  delay_slots = 2;
   4995 	  /* FIXME -- warn if delay_slots != 0 at EOF.  */
   4996 	}
   4997     }
   4998 }
   4999 
   5000 /* Do a final adjustment on the symbol table; in this case, make sure we have
   5001    a ".file" symbol.  */
   5002 
   5003 void
   5004 tic54x_adjust_symtab (void)
   5005 {
   5006   if (symbol_rootP == NULL
   5007       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
   5008     {
   5009       char *filename;
   5010       unsigned lineno;
   5011       as_where (&filename, &lineno);
   5012       c_dot_file_symbol (filename, 0);
   5013     }
   5014 }
   5015 
   5016 /* In order to get gas to ignore any | chars at the start of a line,
   5017    this function returns true if a | is found in a line.
   5018    This lets us process parallel instructions, which span two lines.  */
   5019 
   5020 int
   5021 tic54x_unrecognized_line (int c)
   5022 {
   5023   return c == PARALLEL_SEPARATOR;
   5024 }
   5025 
   5026 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
   5027    Encode their names so that only we see them and can map them to the
   5028    appropriate places.
   5029    FIXME -- obviously this isn't done yet.  These locals still show up in the
   5030    symbol table.  */
   5031 void
   5032 tic54x_define_label (symbolS *sym)
   5033 {
   5034   /* Just in case we need this later; note that this is not necessarily the
   5035      same thing as line_label...
   5036      When aligning or assigning labels to fields, sometimes the label is
   5037      assigned other than the address at which the label appears.
   5038      FIXME -- is this really needed? I think all the proper label assignment
   5039      is done in tic54x_cons.  */
   5040   last_label_seen = sym;
   5041 }
   5042 
   5043 /* Try to parse something that normal parsing failed at.  */
   5044 
   5045 symbolS *
   5046 tic54x_undefined_symbol (char *name)
   5047 {
   5048   symbol *sym;
   5049 
   5050   /* Not sure how to handle predefined symbols.  */
   5051   if ((sym = (symbol *) hash_find (cc_hash, name)) != NULL ||
   5052       (sym = (symbol *) hash_find (cc2_hash, name)) != NULL ||
   5053       (sym = (symbol *) hash_find (cc3_hash, name)) != NULL ||
   5054       (sym = (symbol *) hash_find (misc_symbol_hash, name)) != NULL ||
   5055       (sym = (symbol *) hash_find (sbit_hash, name)) != NULL)
   5056     {
   5057       return symbol_new (name, reg_section,
   5058 			 (valueT) sym->value,
   5059 			 &zero_address_frag);
   5060     }
   5061 
   5062   if ((sym = (symbol *) hash_find (reg_hash, name)) != NULL ||
   5063       (sym = (symbol *) hash_find (mmreg_hash, name)) != NULL ||
   5064       !strcasecmp (name, "a") || !strcasecmp (name, "b"))
   5065     {
   5066       return symbol_new (name, reg_section,
   5067 			 (valueT) sym ? sym->value : 0,
   5068 			 &zero_address_frag);
   5069     }
   5070 
   5071   return NULL;
   5072 }
   5073 
   5074 /* Parse a name in an expression before the expression parser takes a stab at
   5075    it.  */
   5076 
   5077 int
   5078 tic54x_parse_name (char *name ATTRIBUTE_UNUSED,
   5079 		   expressionS *expn ATTRIBUTE_UNUSED)
   5080 {
   5081   return 0;
   5082 }
   5083 
   5084 char *
   5085 md_atof (int type, char *literalP, int *sizeP)
   5086 {
   5087   /* Target data is little-endian, but floats are stored
   5088      big-"word"ian.  ugh.  */
   5089   return ieee_md_atof (type, literalP, sizeP, TRUE);
   5090 }
   5091 
   5092 arelent *
   5093 tc_gen_reloc (asection *section, fixS *fixP)
   5094 {
   5095   arelent *rel;
   5096   bfd_reloc_code_real_type code = fixP->fx_r_type;
   5097   asymbol *sym = symbol_get_bfdsym (fixP->fx_addsy);
   5098 
   5099   rel = (arelent *) xmalloc (sizeof (arelent));
   5100   rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
   5101   *rel->sym_ptr_ptr = sym;
   5102   /* We assume that all rel->address are host byte offsets.  */
   5103   rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
   5104   rel->address /= OCTETS_PER_BYTE;
   5105   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
   5106   if (!strcmp (sym->name, section->name))
   5107     rel->howto += HOWTO_BANK;
   5108 
   5109   if (!rel->howto)
   5110     {
   5111       const char *name = S_GET_NAME (fixP->fx_addsy);
   5112       if (name == NULL)
   5113 	name = "<unknown>";
   5114       as_fatal ("Cannot generate relocation type for symbol %s, code %s",
   5115 		name, bfd_get_reloc_code_name (code));
   5116       return NULL;
   5117     }
   5118   return rel;
   5119 }
   5120 
   5121 /* Handle cons expressions.  */
   5122 
   5123 void
   5124 tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
   5125 		     bfd_reloc_code_real_type r)
   5126 {
   5127   switch (octets)
   5128     {
   5129     default:
   5130       as_bad (_("Unsupported relocation size %d"), octets);
   5131       r = BFD_RELOC_TIC54X_16_OF_23;
   5132       break;
   5133     case 2:
   5134       r = BFD_RELOC_TIC54X_16_OF_23;
   5135       break;
   5136     case 4:
   5137       /* TI assembler always uses this, regardless of addressing mode.  */
   5138       if (emitting_long)
   5139 	r = BFD_RELOC_TIC54X_23;
   5140       else
   5141 	/* We never want to directly generate this; this is provided for
   5142 	   stabs support only.  */
   5143 	r = BFD_RELOC_32;
   5144       break;
   5145     }
   5146   fix_new_exp (frag, where, octets, expn, 0, r);
   5147 }
   5148 
   5149 /* Attempt to simplify or even eliminate a fixup.
   5150    To indicate that a fixup has been eliminated, set fixP->fx_done.
   5151 
   5152    If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry.   */
   5153 
   5154 void
   5155 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   5156 {
   5157   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
   5158   valueT val = * valP;
   5159 
   5160   switch (fixP->fx_r_type)
   5161     {
   5162     default:
   5163       as_fatal ("Bad relocation type: 0x%02x", fixP->fx_r_type);
   5164       return;
   5165     case BFD_RELOC_TIC54X_MS7_OF_23:
   5166       val = (val >> 16) & 0x7F;
   5167       /* Fall through.  */
   5168     case BFD_RELOC_TIC54X_16_OF_23:
   5169     case BFD_RELOC_16:
   5170       bfd_put_16 (stdoutput, val, buf);
   5171       /* Indicate what we're actually writing, so that we don't get warnings
   5172 	 about exceeding available space.  */
   5173       *valP = val & 0xFFFF;
   5174       break;
   5175     case BFD_RELOC_TIC54X_PARTLS7:
   5176       bfd_put_16 (stdoutput,
   5177 		  (bfd_get_16 (stdoutput, buf) & 0xFF80) | (val & 0x7F),
   5178 		  buf);
   5179       /* Indicate what we're actually writing, so that we don't get warnings
   5180 	 about exceeding available space.  */
   5181       *valP = val & 0x7F;
   5182       break;
   5183     case BFD_RELOC_TIC54X_PARTMS9:
   5184       /* TI assembler doesn't shift its encoding for relocatable files, and is
   5185 	 thus incompatible with this implementation's relocatable files.  */
   5186       bfd_put_16 (stdoutput,
   5187 		  (bfd_get_16 (stdoutput, buf) & 0xFE00) | (val >> 7),
   5188 		  buf);
   5189       break;
   5190     case BFD_RELOC_32:
   5191     case BFD_RELOC_TIC54X_23:
   5192       bfd_put_32 (stdoutput,
   5193 		  (bfd_get_32 (stdoutput, buf) & 0xFF800000) | val,
   5194 		  buf);
   5195       break;
   5196     }
   5197 
   5198   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
   5199     fixP->fx_done = 1;
   5200 }
   5201 
   5202 /* This is our chance to record section alignment
   5203    don't need to do anything here, since BFD does the proper encoding.  */
   5204 
   5205 valueT
   5206 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT section_size)
   5207 {
   5208   return section_size;
   5209 }
   5210 
   5211 long
   5212 md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
   5213 {
   5214   return 0;
   5215 }
   5216 
   5217 /* Mostly little-endian, but longwords (4 octets) get MS word stored
   5218    first.  */
   5219 
   5220 void
   5221 tic54x_number_to_chars (char *buf, valueT val, int n)
   5222 {
   5223   if (n != 4)
   5224     number_to_chars_littleendian (buf, val, n);
   5225   else
   5226     {
   5227       number_to_chars_littleendian (buf    , val >> 16   , 2);
   5228       number_to_chars_littleendian (buf + 2, val & 0xFFFF, 2);
   5229     }
   5230 }
   5231 
   5232 int
   5233 tic54x_estimate_size_before_relax (fragS *frag ATTRIBUTE_UNUSED,
   5234 				   segT seg ATTRIBUTE_UNUSED)
   5235 {
   5236   return 0;
   5237 }
   5238 
   5239 /* We use this to handle bit allocations which we couldn't handle before due
   5240    to symbols being in different frags.  return number of octets added.  */
   5241 
   5242 int
   5243 tic54x_relax_frag (fragS *frag, long stretch ATTRIBUTE_UNUSED)
   5244 {
   5245   symbolS *sym = frag->fr_symbol;
   5246   int growth = 0;
   5247   int i;
   5248 
   5249   if (sym != NULL)
   5250     {
   5251       struct bit_info *bi = (struct bit_info *) frag->fr_opcode;
   5252       int bit_offset = frag_bit_offset (frag_prev (frag, bi->seg), bi->seg);
   5253       int size = S_GET_VALUE (sym);
   5254       fragS *prev_frag = bit_offset_frag (frag_prev (frag, bi->seg), bi->seg);
   5255       int available = 16 - bit_offset;
   5256 
   5257       if (symbol_get_frag (sym) != &zero_address_frag
   5258 	  || S_IS_COMMON (sym)
   5259 	  || !S_IS_DEFINED (sym))
   5260 	as_bad_where (frag->fr_file, frag->fr_line,
   5261 		      _("non-absolute value used with .space/.bes"));
   5262 
   5263       if (size < 0)
   5264 	{
   5265 	  as_warn (_("negative value ignored in %s"),
   5266 		   bi->type == TYPE_SPACE ? ".space" :
   5267 		   bi->type == TYPE_BES ? ".bes" : ".field");
   5268 	  growth = 0;
   5269 	  frag->tc_frag_data = frag->fr_fix = 0;
   5270 	  return 0;
   5271 	}
   5272 
   5273       if (bi->type == TYPE_FIELD)
   5274 	{
   5275 	  /* Bit fields of 16 or larger will have already been handled.  */
   5276 	  if (bit_offset != 0 && available >= size)
   5277 	    {
   5278 	      char *p = prev_frag->fr_literal;
   5279 
   5280 	      valueT value = bi->value;
   5281 	      value <<= available - size;
   5282 	      value |= ((unsigned short) p[1] << 8) | p[0];
   5283 	      md_number_to_chars (p, value, 2);
   5284 	      if ((prev_frag->tc_frag_data += size) == 16)
   5285 		prev_frag->tc_frag_data = 0;
   5286 	      if (bi->sym)
   5287 		symbol_set_frag (bi->sym, prev_frag);
   5288 	      /* This frag is no longer used.  */
   5289 	      growth = -frag->fr_fix;
   5290 	      frag->fr_fix = 0;
   5291 	      frag->tc_frag_data = 0;
   5292 	    }
   5293 	  else
   5294 	    {
   5295 	      char *p = frag->fr_literal;
   5296 
   5297 	      valueT value = bi->value << (16 - size);
   5298 	      md_number_to_chars (p, value, 2);
   5299 	      if ((frag->tc_frag_data = size) == 16)
   5300 		frag->tc_frag_data = 0;
   5301 	      growth = 0;
   5302 	    }
   5303 	}
   5304       else
   5305 	{
   5306 	  if (bit_offset != 0 && bit_offset < 16)
   5307 	    {
   5308 	      if (available >= size)
   5309 		{
   5310 		  if ((prev_frag->tc_frag_data += size) == 16)
   5311 		    prev_frag->tc_frag_data = 0;
   5312 		  if (bi->sym)
   5313 		    symbol_set_frag (bi->sym, prev_frag);
   5314 		  /* This frag is no longer used.  */
   5315 		  growth = -frag->fr_fix;
   5316 		  frag->fr_fix = 0;
   5317 		  frag->tc_frag_data = 0;
   5318 		  goto getout;
   5319 		}
   5320 	      if (bi->type == TYPE_SPACE && bi->sym)
   5321 		symbol_set_frag (bi->sym, prev_frag);
   5322 	      size -= available;
   5323 	    }
   5324 	  growth = (size + 15) / 16 * OCTETS_PER_BYTE - frag->fr_fix;
   5325 	  for (i = 0; i < growth; i++)
   5326 	    frag->fr_literal[i] = 0;
   5327 	  frag->fr_fix = growth;
   5328 	  frag->tc_frag_data = size % 16;
   5329 	  /* Make sure any BES label points to the LAST word allocated.  */
   5330 	  if (bi->type == TYPE_BES && bi->sym)
   5331 	    S_SET_VALUE (bi->sym, frag->fr_fix / OCTETS_PER_BYTE - 1);
   5332 	}
   5333     getout:
   5334       frag->fr_symbol = 0;
   5335       frag->fr_opcode = 0;
   5336       free ((void *) bi);
   5337     }
   5338   return growth;
   5339 }
   5340 
   5341 void
   5342 tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   5343 		     segT seg ATTRIBUTE_UNUSED,
   5344 		     fragS *frag)
   5345 {
   5346   /* Offset is in bytes.  */
   5347   frag->fr_offset = (frag->fr_next->fr_address
   5348 		     - frag->fr_address
   5349 		     - frag->fr_fix) / frag->fr_var;
   5350   if (frag->fr_offset < 0)
   5351     {
   5352       as_bad_where (frag->fr_file, frag->fr_line,
   5353 		    _("attempt to .space/.bes backwards? (%ld)"),
   5354 		    (long) frag->fr_offset);
   5355     }
   5356   frag->fr_type = rs_space;
   5357 }
   5358 
   5359 /* We need to avoid having labels defined for certain directives/pseudo-ops
   5360    since once the label is defined, it's in the symbol table for good.  TI
   5361    syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
   5362    I guess, except I've never seen a definition of MRI syntax).
   5363 
   5364    C is the character that used to be at *REST, which points to the end of the
   5365    label.
   5366 
   5367    Don't allow labels to start with '.'  */
   5368 
   5369 int
   5370 tic54x_start_label (int c, char *rest)
   5371 {
   5372   /* If within .struct/.union, no auto line labels, please.  */
   5373   if (current_stag != NULL)
   5374     return 0;
   5375 
   5376   /* Disallow labels starting with "."  */
   5377   if (c != ':')
   5378     {
   5379       char *label = rest;
   5380 
   5381       while (!is_end_of_line[(int) label[-1]])
   5382 	--label;
   5383       if (*label == '.')
   5384 	{
   5385 	  as_bad (_("Invalid label '%s'"), label);
   5386 	  return 0;
   5387 	}
   5388     }
   5389 
   5390   if (is_end_of_line[(int) c])
   5391     return 1;
   5392 
   5393   if (ISSPACE (c))
   5394     while (ISSPACE (c = *++rest))
   5395       ;
   5396   if (c == '.')
   5397     {
   5398       /* Don't let colon () define a label for any of these...  */
   5399       return (strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
   5400 	&& (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
   5401 	&& (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
   5402 	&& (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
   5403 	&& (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
   5404 	&& (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4]));
   5405     }
   5406 
   5407   return 1;
   5408 }
   5409