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