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