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