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