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