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