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