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