1/* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2   Copyright (C) 1997-2017 Free Software Foundation, Inc.
3
4   Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
5
6   This file is part of GAS, the GNU Assembler.
7
8   GAS is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3, or (at your option)
11   any later version.
12
13   GAS is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with GAS; see the file COPYING.  If not, write to
20   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21   Boston, MA 02110-1301, USA.  */
22/*
23  TODOs:
24  ------
25
26  o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
27    should be possible to define a 32-bits pattern.
28
29  o .align: Implement a 'bu' insn if the number of nop's exceeds 4
30    within the align frag. if(fragsize>4words) insert bu fragend+1
31    first.
32
33  o .usect if has symbol on previous line not implemented
34
35  o .sym, .eos, .stag, .etag, .member not implemented
36
37  o Evaluation of constant floating point expressions (expr.c needs
38    work!)
39
40  o Support 'abc' constants (that is 0x616263).  */
41
42#include "as.h"
43#include "safe-ctype.h"
44#include "opcode/tic4x.h"
45#include "subsegs.h"
46
47/* OK, we accept a syntax similar to the other well known C30
48   assembly tools.  With TIC4X_ALT_SYNTAX defined we are more
49   flexible, allowing a more Unix-like syntax:  `%' in front of
50   register names, `#' in front of immediate constants, and
51   not requiring `@' in front of direct addresses.  */
52
53#define TIC4X_ALT_SYNTAX
54
55/* Equal to MAX_PRECISION in atof-ieee.c.  */
56#define MAX_LITTLENUMS 6	/* (12 bytes) */
57
58/* Handle of the inst mnemonic hash table.  */
59static struct hash_control *tic4x_op_hash = NULL;
60
61/* Handle asg pseudo.  */
62static struct hash_control *tic4x_asg_hash = NULL;
63
64static unsigned int tic4x_cpu = 0;        /* Default to TMS320C40.  */
65static unsigned int tic4x_revision = 0;   /* CPU revision */
66static unsigned int tic4x_idle2 = 0;      /* Idle2 support */
67static unsigned int tic4x_lowpower = 0;   /* Lowpower support */
68static unsigned int tic4x_enhanced = 0;   /* Enhanced opcode support */
69static unsigned int tic4x_big_model = 0;  /* Default to small memory model.  */
70static unsigned int tic4x_reg_args = 0;   /* Default to args passed on stack.  */
71static unsigned long tic4x_oplevel = 0;   /* Opcode level */
72
73#define OPTION_CPU      'm'
74#define OPTION_BIG      (OPTION_MD_BASE + 1)
75#define OPTION_SMALL    (OPTION_MD_BASE + 2)
76#define OPTION_MEMPARM  (OPTION_MD_BASE + 3)
77#define OPTION_REGPARM  (OPTION_MD_BASE + 4)
78#define OPTION_IDLE2    (OPTION_MD_BASE + 5)
79#define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
80#define OPTION_ENHANCED (OPTION_MD_BASE + 7)
81#define OPTION_REV      (OPTION_MD_BASE + 8)
82
83const char *md_shortopts = "bm:prs";
84struct option md_longopts[] =
85{
86  { "mcpu",   required_argument, NULL, OPTION_CPU },
87  { "mdsp",   required_argument, NULL, OPTION_CPU },
88  { "mbig",         no_argument, NULL, OPTION_BIG },
89  { "msmall",       no_argument, NULL, OPTION_SMALL },
90  { "mmemparm",     no_argument, NULL, OPTION_MEMPARM },
91  { "mregparm",     no_argument, NULL, OPTION_REGPARM },
92  { "midle2",       no_argument, NULL, OPTION_IDLE2 },
93  { "mlowpower",    no_argument, NULL, OPTION_LOWPOWER },
94  { "menhanced",    no_argument, NULL, OPTION_ENHANCED },
95  { "mrev",   required_argument, NULL, OPTION_REV },
96  { NULL, no_argument, NULL, 0 }
97};
98
99size_t md_longopts_size = sizeof (md_longopts);
100
101
102typedef enum
103  {
104    M_UNKNOWN, M_IMMED, M_DIRECT, M_REGISTER, M_INDIRECT,
105    M_IMMED_F, M_PARALLEL, M_HI
106  }
107tic4x_addr_mode_t;
108
109typedef struct tic4x_operand
110  {
111    tic4x_addr_mode_t mode;	/* Addressing mode.  */
112    expressionS expr;		/* Expression.  */
113    int disp;			/* Displacement for indirect addressing.  */
114    int aregno;			/* Aux. register number.  */
115    LITTLENUM_TYPE fwords[MAX_LITTLENUMS];	/* Float immed. number.  */
116  }
117tic4x_operand_t;
118
119typedef struct tic4x_insn
120  {
121    char name[TIC4X_NAME_MAX];	/* Mnemonic of instruction.  */
122    unsigned int in_use;	/* True if in_use.  */
123    unsigned int parallel;	/* True if parallel instruction.  */
124    unsigned int nchars;	/* This is always 4 for the C30.  */
125    unsigned long opcode;	/* Opcode number.  */
126    expressionS exp;		/* Expression required for relocation.  */
127    /* Relocation type required.  */
128    bfd_reloc_code_real_type reloc;
129    int pcrel;			/* True if relocation PC relative.  */
130    char *pname;		/* Name of instruction in parallel.  */
131    unsigned int num_operands;	/* Number of operands in total.  */
132    tic4x_inst_t *inst;		/* Pointer to first template.  */
133    tic4x_operand_t operands[TIC4X_OPERANDS_MAX];
134  }
135tic4x_insn_t;
136
137static tic4x_insn_t the_insn;	/* Info about our instruction.  */
138static tic4x_insn_t *insn = &the_insn;
139
140static void tic4x_asg (int);
141static void tic4x_bss (int);
142static void tic4x_globl (int);
143static void tic4x_cons (int);
144static void tic4x_stringer (int);
145static void tic4x_eval (int);
146static void tic4x_newblock (int);
147static void tic4x_sect (int);
148static void tic4x_set (int);
149static void tic4x_usect (int);
150static void tic4x_version (int);
151
152
153const pseudo_typeS
154  md_pseudo_table[] =
155{
156  {"align", s_align_bytes, 32},
157  {"ascii", tic4x_stringer, 1},
158  {"asciz", tic4x_stringer, 0},
159  {"asg", tic4x_asg, 0},
160  {"block", s_space, 4},
161  {"byte", tic4x_cons, 1},
162  {"bss", tic4x_bss, 0},
163  {"copy", s_include, 0},
164  {"def", tic4x_globl, 0},
165  {"equ", tic4x_set, 0},
166  {"eval", tic4x_eval, 0},
167  {"global", tic4x_globl, 0},
168  {"globl", tic4x_globl, 0},
169  {"hword", tic4x_cons, 2},
170  {"ieee", float_cons, 'i'},
171  {"int", tic4x_cons, 4},		 /* .int allocates 4 bytes.  */
172  {"ldouble", float_cons, 'e'},
173  {"newblock", tic4x_newblock, 0},
174  {"ref", s_ignore, 0},	         /* All undefined treated as external.  */
175  {"set", tic4x_set, 0},
176  {"sect", tic4x_sect, 1},	 /* Define named section.  */
177  {"space", s_space, 4},
178  {"string", tic4x_stringer, 0},
179  {"usect", tic4x_usect, 0},       /* Reserve space in uninit. named sect.  */
180  {"version", tic4x_version, 0},
181  {"word", tic4x_cons, 4},	 /* .word allocates 4 bytes.  */
182  {"xdef", tic4x_globl, 0},
183  {NULL, 0, 0},
184};
185
186int md_short_jump_size = 4;
187int md_long_jump_size = 4;
188
189/* This array holds the chars that always start a comment.  If the
190   pre-processor is disabled, these aren't very useful.  */
191#ifdef TIC4X_ALT_SYNTAX
192const char comment_chars[] = ";!";
193#else
194const char comment_chars[] = ";";
195#endif
196
197/* This array holds the chars that only start a comment at the beginning of
198   a line.  If the line seems to have the form '# 123 filename'
199   .line and .file directives will appear in the pre-processed output.
200   Note that input_file.c hand checks for '#' at the beginning of the
201   first line of the input file.  This is because the compiler outputs
202   #NO_APP at the beginning of its output.
203   Also note that comments like this one will always work.  */
204const char line_comment_chars[] = "#*";
205
206/* We needed an unused char for line separation to work around the
207   lack of macros, using sed and such.  */
208const char line_separator_chars[] = "&";
209
210/* Chars that can be used to separate mant from exp in floating point nums.  */
211const char EXP_CHARS[] = "eE";
212
213/* Chars that mean this number is a floating point constant.  */
214/* As in 0f12.456 */
215/* or    0d1.2345e12 */
216const char FLT_CHARS[] = "fFilsS";
217
218/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
219   changed in read.c.  Ideally it shouldn't have to know about it at
220   all, but nothing is ideal around here.  */
221
222/* Flonums returned here.  */
223extern FLONUM_TYPE generic_floating_point_number;
224
225/* Precision in LittleNums.  */
226#define MAX_PRECISION (4)       /* Its a bit overkill for us, but the code
227                                   requires it... */
228#define S_PRECISION (1)		/* Short float constants 16-bit.  */
229#define F_PRECISION (2)		/* Float and double types 32-bit.  */
230#define E_PRECISION (4)         /* Extended precision, 64-bit (real 40-bit). */
231#define GUARD (2)
232
233/* Turn generic_floating_point_number into a real short/float/double.  */
234static int
235tic4x_gen_to_words (FLONUM_TYPE flonum, LITTLENUM_TYPE *words, int precision)
236{
237  int return_value = 0;
238  LITTLENUM_TYPE *p;		/* Littlenum pointer.  */
239  int mantissa_bits;		/* Bits in mantissa field.  */
240  int exponent_bits;		/* Bits in exponent field.  */
241  int exponent;
242  unsigned int sone;		/* Scaled one.  */
243  unsigned int sfract;		/* Scaled fraction.  */
244  unsigned int smant;		/* Scaled mantissa.  */
245  unsigned int tmp;
246  unsigned int mover;           /* Mantissa overflow bits */
247  unsigned int rbit;            /* Round bit. */
248  int shift;			/* Shift count.  */
249
250  /* NOTE: Svein Seldal <Svein@dev.seldal.com>
251     The code in this function is altered slightly to support floats
252     with 31-bits mantissas, thus the documentation below may be a
253     little bit inaccurate.
254
255     By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
256     Here is how a generic floating point number is stored using
257     flonums (an extension of bignums) where p is a pointer to an
258     array of LITTLENUMs.
259
260     For example 2e-3 is stored with exp = -4 and
261     bits[0] = 0x0000
262     bits[1] = 0x0000
263     bits[2] = 0x4fde
264     bits[3] = 0x978d
265     bits[4] = 0x126e
266     bits[5] = 0x0083
267     with low = &bits[2], high = &bits[5], and leader = &bits[5].
268
269     This number can be written as
270     0x0083126e978d4fde.00000000 * 65536**-4  or
271     0x0.0083126e978d4fde        * 65536**0   or
272     0x0.83126e978d4fde          * 2**-8   = 2e-3
273
274     Note that low points to the 65536**0 littlenum (bits[2]) and
275     leader points to the most significant non-zero littlenum
276     (bits[5]).
277
278     TMS320C3X floating point numbers are a bit of a strange beast.
279     The 32-bit flavour has the 8 MSBs representing the exponent in
280     twos complement format (-128 to +127).  There is then a sign bit
281     followed by 23 bits of mantissa.  The mantissa is expressed in
282     twos complement format with the binary point after the most
283     significant non sign bit.  The bit after the binary point is
284     suppressed since it is the complement of the sign bit.  The
285     effective mantissa is thus 24 bits.  Zero is represented by an
286     exponent of -128.
287
288     The 16-bit flavour has the 4 MSBs representing the exponent in
289     twos complement format (-8 to +7).  There is then a sign bit
290     followed by 11 bits of mantissa.  The mantissa is expressed in
291     twos complement format with the binary point after the most
292     significant non sign bit.  The bit after the binary point is
293     suppressed since it is the complement of the sign bit.  The
294     effective mantissa is thus 12 bits.  Zero is represented by an
295     exponent of -8.  For example,
296
297     number       norm mant m  x  e  s  i    fraction f
298     +0.500 =>  1.00000000000 -1 -1  0  1  .00000000000   (1 + 0) * 2^(-1)
299     +0.999 =>  1.11111111111 -1 -1  0  1  .11111111111   (1 + 0.99) * 2^(-1)
300     +1.000 =>  1.00000000000  0  0  0  1  .00000000000   (1 + 0) * 2^(0)
301     +1.500 =>  1.10000000000  0  0  0  1  .10000000000   (1 + 0.5) * 2^(0)
302     +1.999 =>  1.11111111111  0  0  0  1  .11111111111   (1 + 0.9) * 2^(0)
303     +2.000 =>  1.00000000000  1  1  0  1  .00000000000   (1 + 0) * 2^(1)
304     +4.000 =>  1.00000000000  2  2  0  1  .00000000000   (1 + 0) * 2^(2)
305     -0.500 =>  1.00000000000 -1 -1  1  0  .10000000000   (-2 + 0) * 2^(-2)
306     -1.000 =>  1.00000000000  0 -1  1  0  .00000000000   (-2 + 0) * 2^(-1)
307     -1.500 =>  1.10000000000  0  0  1  0  .10000000000   (-2 + 0.5) * 2^(0)
308     -1.999 =>  1.11111111111  0  0  1  0  .00000000001   (-2 + 0.11) * 2^(0)
309     -2.000 =>  1.00000000000  1  1  1  0  .00000000000   (-2 + 0) * 2^(0)
310     -4.000 =>  1.00000000000  2  1  1  0  .00000000000   (-2 + 0) * 2^(1)
311
312     where e is the exponent, s is the sign bit, i is the implied bit,
313     and f is the fraction stored in the mantissa field.
314
315     num = (1 + f) * 2^x   =  m * 2^e if s = 0
316     num = (-2 + f) * 2^x  = -m * 2^e if s = 1
317     where 0 <= f < 1.0  and 1.0 <= m < 2.0
318
319     The fraction (f) and exponent (e) fields for the TMS320C3X format
320     can be derived from the normalised mantissa (m) and exponent (x) using:
321
322     f = m - 1, e = x       if s = 0
323     f = 2 - m, e = x       if s = 1 and m != 1.0
324     f = 0,     e = x - 1   if s = 1 and m = 1.0
325     f = 0,     e = -8      if m = 0
326
327
328     OK, the other issue we have to consider is rounding since the
329     mantissa has a much higher potential precision than what we can
330     represent.  To do this we add half the smallest storable fraction.
331     We then have to renormalise the number to allow for overflow.
332
333     To convert a generic flonum into a TMS320C3X floating point
334     number, here's what we try to do....
335
336     The first thing is to generate a normalised mantissa (m) where
337     1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
338     We desire the binary point to be placed after the most significant
339     non zero bit.  This process is done in two steps: firstly, the
340     littlenum with the most significant non zero bit is located (this
341     is done for us since leader points to this littlenum) and the
342     binary point (which is currently after the LSB of the littlenum
343     pointed to by low) is moved to before the MSB of the littlenum
344     pointed to by leader.  This requires the exponent to be adjusted
345     by leader - low + 1.  In the earlier example, the new exponent is
346     thus -4 + (5 - 2 + 1) = 0 (base 65536).  We now need to convert
347     the exponent to base 2 by multiplying the exponent by 16 (log2
348     65536).  The exponent base 2 is thus also zero.
349
350     The second step is to hunt for the most significant non zero bit
351     in the leader littlenum.  We do this by left shifting a copy of
352     the leader littlenum until bit 16 is set (0x10000) and counting
353     the number of shifts, S, required.  The number of shifts then has to
354     be added to correct the exponent (base 2).  For our example, this
355     will require 9 shifts and thus our normalised exponent (base 2) is
356     0 + 9 = 9.  Note that the worst case scenario is when the leader
357     littlenum is 1, thus requiring 16 shifts.
358
359     We now have to left shift the other littlenums by the same amount,
360     propagating the shifted bits into the more significant littlenums.
361     To save a lot of unnecessary shifting we only have to consider
362     two or three littlenums, since the greatest number of mantissa
363     bits required is 24 + 1 rounding bit.  While two littlenums
364     provide 32 bits of precision, the most significant littlenum
365     may only contain a single significant bit  and thus an extra
366     littlenum is required.
367
368     Denoting the number of bits in the fraction field as F, we require
369     G = F + 2 bits (one extra bit is for rounding, the other gets
370     suppressed).  Say we required S shifts to find the most
371     significant bit in the leader littlenum, the number of left shifts
372     required to move this bit into bit position G - 1 is L = G + S - 17.
373     Note that this shift count may be negative for the short floating
374     point flavour (where F = 11 and thus G = 13 and potentially S < 3).
375     If L > 0 we have to shunt the next littlenum into position.  Bit
376     15 (the MSB) of the next littlenum needs to get moved into position
377     L - 1 (If L > 15 we need all the bits of this littlenum and
378     some more from the next one.).  We subtract 16 from L and use this
379     as the left shift count;  the resultant value we or with the
380     previous result.  If L > 0, we repeat this operation.   */
381
382  if (precision != S_PRECISION)
383    words[1] = 0x0000;
384  if (precision == E_PRECISION)
385    words[2] = words[3] = 0x0000;
386
387  /* 0.0e0 or NaN seen.  */
388  if (flonum.low > flonum.leader  /* = 0.0e0 */
389      || flonum.sign == 0) /* = NaN */
390    {
391      if(flonum.sign == 0)
392        as_bad (_("Nan, using zero."));
393      words[0] = 0x8000;
394      return return_value;
395    }
396
397  if (flonum.sign == 'P')
398    {
399      /* +INF:  Replace with maximum float.  */
400      if (precision == S_PRECISION)
401	words[0] = 0x77ff;
402      else
403	{
404	  words[0] = 0x7f7f;
405	  words[1] = 0xffff;
406	}
407      if (precision == E_PRECISION)
408        {
409          words[2] = 0x7fff;
410          words[3] = 0xffff;
411        }
412      return return_value;
413    }
414  else if (flonum.sign == 'N')
415    {
416      /* -INF:  Replace with maximum float.  */
417      if (precision == S_PRECISION)
418	words[0] = 0x7800;
419      else
420        words[0] = 0x7f80;
421      if (precision == E_PRECISION)
422        words[2] = 0x8000;
423      return return_value;
424    }
425
426  exponent = (flonum.exponent + flonum.leader - flonum.low + 1) * 16;
427
428  if (!(tmp = *flonum.leader))
429    abort ();			/* Hmmm.  */
430  shift = 0;			/* Find position of first sig. bit.  */
431  while (tmp >>= 1)
432    shift++;
433  exponent -= (16 - shift);	/* Adjust exponent.  */
434
435  if (precision == S_PRECISION)	/* Allow 1 rounding bit.  */
436    {
437      exponent_bits = 4;
438      mantissa_bits = 11;
439    }
440  else if(precision == F_PRECISION)
441    {
442      exponent_bits = 8;
443      mantissa_bits = 23;
444    }
445  else /* E_PRECISION */
446    {
447      exponent_bits = 8;
448      mantissa_bits = 31;
449    }
450
451  shift = mantissa_bits - shift;
452
453  smant = 0;
454  mover = 0;
455  rbit = 0;
456  /* Store the mantissa data into smant and the roundbit into rbit */
457  for (p = flonum.leader; p >= flonum.low && shift > -16; p--)
458    {
459      tmp = shift >= 0 ? *p << shift : *p >> -shift;
460      rbit = shift < 0 ? ((*p >> (-shift-1)) & 0x1) : 0;
461      smant |= tmp;
462      shift -= 16;
463    }
464
465  /* OK, we've got our scaled mantissa so let's round it up */
466  if(rbit)
467    {
468      /* If the mantissa is going to overflow when added, lets store
469         the extra bit in mover. -- A special case exists when
470         mantissa_bits is 31 (E_PRECISION). Then the first test cannot
471         be trusted, as result is host-dependent, thus the second
472         test. */
473      if( smant == ((unsigned)(1<<(mantissa_bits+1))-1)
474          || smant == (unsigned)-1 )  /* This is to catch E_PRECISION cases */
475        mover=1;
476      smant++;
477    }
478
479  /* Get the scaled one value */
480  sone = (1 << (mantissa_bits));
481
482  /* The number may be unnormalised so renormalise it...  */
483  if(mover)
484    {
485      smant >>= 1;
486      smant |= sone; /* Insert the bit from mover into smant */
487      exponent++;
488    }
489
490  /* The binary point is now between bit positions 11 and 10 or 23 and 22,
491     i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
492     bit at mantissa_bits - 1 should be set.  */
493  if (!(sone&smant))
494    abort ();                   /* Ooops.  */
495
496  if (flonum.sign == '+')
497    sfract = smant - sone;	/* smant - 1.0.  */
498  else
499    {
500      /* This seems to work.  */
501      if (smant == sone)
502	{
503	  exponent--;
504	  sfract = 0;
505	}
506      else
507        {
508          sfract = -smant & (sone-1);   /* 2.0 - smant.  */
509        }
510      sfract |= sone;		/* Insert sign bit.  */
511    }
512
513  if (abs (exponent) >= (1 << (exponent_bits - 1)))
514    as_bad (_("Cannot represent exponent in %d bits"), exponent_bits);
515
516  /* Force exponent to fit in desired field width.  */
517  exponent &= (1 << (exponent_bits)) - 1;
518
519  if (precision == E_PRECISION)
520    {
521      /* Map the float part first (100% equal format as F_PRECISION) */
522      words[0]  = exponent << (mantissa_bits+1-24);
523      words[0] |= sfract >> 24;
524      words[1]  = sfract >> 8;
525
526      /* Map the mantissa in the next */
527      words[2]  = sfract >> 16;
528      words[3]  = sfract & 0xffff;
529    }
530  else
531    {
532      /* Insert the exponent data into the word */
533      sfract |= exponent << (mantissa_bits+1);
534
535      if (precision == S_PRECISION)
536        words[0] = sfract;
537      else
538        {
539          words[0] = sfract >> 16;
540          words[1] = sfract & 0xffff;
541        }
542    }
543
544  return return_value;
545}
546
547/* Returns pointer past text consumed.  */
548static char *
549tic4x_atof (char *str, char what_kind, LITTLENUM_TYPE *words)
550{
551  /* Extra bits for zeroed low-order bits.  The 1st MAX_PRECISION are
552     zeroed, the last contain flonum bits.  */
553  static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
554  char *return_value;
555  /* Number of 16-bit words in the format.  */
556  int precision;
557  FLONUM_TYPE save_gen_flonum;
558
559  /* We have to save the generic_floating_point_number because it
560     contains storage allocation about the array of LITTLENUMs where
561     the value is actually stored.  We will allocate our own array of
562     littlenums below, but have to restore the global one on exit.  */
563  save_gen_flonum = generic_floating_point_number;
564
565  return_value = str;
566  generic_floating_point_number.low = bits + MAX_PRECISION;
567  generic_floating_point_number.high = NULL;
568  generic_floating_point_number.leader = NULL;
569  generic_floating_point_number.exponent = 0;
570  generic_floating_point_number.sign = '\0';
571
572  /* Use more LittleNums than seems necessary: the highest flonum may
573     have 15 leading 0 bits, so could be useless.  */
574
575  memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
576
577  switch (what_kind)
578    {
579    case 's':
580    case 'S':
581      precision = S_PRECISION;
582      break;
583
584    case 'd':
585    case 'D':
586    case 'f':
587    case 'F':
588      precision = F_PRECISION;
589      break;
590
591    case 'E':
592    case 'e':
593      precision = E_PRECISION;
594      break;
595
596    default:
597      as_bad (_("Invalid floating point number"));
598      return (NULL);
599    }
600
601  generic_floating_point_number.high
602    = generic_floating_point_number.low + precision - 1 + GUARD;
603
604  if (atof_generic (&return_value, ".", EXP_CHARS,
605		    &generic_floating_point_number))
606    {
607      as_bad (_("Invalid floating point number"));
608      return (NULL);
609    }
610
611  tic4x_gen_to_words (generic_floating_point_number,
612		    words, precision);
613
614  /* Restore the generic_floating_point_number's storage alloc (and
615     everything else).  */
616  generic_floating_point_number = save_gen_flonum;
617
618  return return_value;
619}
620
621static void
622tic4x_insert_reg (const char *regname, int regnum)
623{
624  char buf[32];
625  int i;
626
627  symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum,
628				   &zero_address_frag));
629  for (i = 0; regname[i]; i++)
630    buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i];
631  buf[i] = '\0';
632
633  symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
634				   &zero_address_frag));
635}
636
637static void
638tic4x_insert_sym (const char *symname, int value)
639{
640  symbolS *symbolP;
641
642  symbolP = symbol_new (symname, absolute_section,
643			(valueT) value, &zero_address_frag);
644  SF_SET_LOCAL (symbolP);
645  symbol_table_insert (symbolP);
646}
647
648static char *
649tic4x_expression (char *str, expressionS *exp)
650{
651  char *s;
652  char *t;
653
654  t = input_line_pointer;	/* Save line pointer.  */
655  input_line_pointer = str;
656  expression (exp);
657  s = input_line_pointer;
658  input_line_pointer = t;	/* Restore line pointer.  */
659  return s;			/* Return pointer to where parsing stopped.  */
660}
661
662static char *
663tic4x_expression_abs (char *str, offsetT *value)
664{
665  char *s;
666  char *t;
667
668  t = input_line_pointer;	/* Save line pointer.  */
669  input_line_pointer = str;
670  *value = get_absolute_expression ();
671  s = input_line_pointer;
672  input_line_pointer = t;	/* Restore line pointer.  */
673  return s;
674}
675
676static void
677tic4x_emit_char (char c, int b)
678{
679  expressionS exp;
680
681  exp.X_op = O_constant;
682  exp.X_add_number = c;
683  emit_expr (&exp, b);
684}
685
686static void
687tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED,
688		 segT seg ATTRIBUTE_UNUSED,
689		 int size,
690		 symbolS *symbolP)
691{
692  /* Note that the size is in words
693     so we multiply it by 4 to get the number of bytes to allocate.  */
694
695  /* If we have symbol:  .usect  ".fred", size etc.,
696     the symbol needs to point to the first location reserved
697     by the pseudo op.  */
698
699  if (size)
700    {
701      char *p;
702
703      p = frag_var (rs_fill, 1, 1, (relax_substateT) 0,
704		    (symbolS *) symbolP,
705		    size * OCTETS_PER_BYTE, (char *) 0);
706      *p = 0;
707    }
708}
709
710/* .asg ["]character-string["], symbol */
711static void
712tic4x_asg (int x ATTRIBUTE_UNUSED)
713{
714  char c;
715  char *name;
716  char *str;
717
718  SKIP_WHITESPACE ();
719  str = input_line_pointer;
720
721  /* Skip string expression.  */
722  while (*input_line_pointer != ',' && *input_line_pointer)
723    input_line_pointer++;
724  if (*input_line_pointer != ',')
725    {
726      as_bad (_("Comma expected\n"));
727      return;
728    }
729  *input_line_pointer++ = '\0';
730  c = get_symbol_name (&name);	/* Get terminator.  */
731  str = xstrdup (str);
732  name = xstrdup (name);
733  if (hash_find (tic4x_asg_hash, name))
734    hash_replace (tic4x_asg_hash, name, (void *) str);
735  else
736    hash_insert (tic4x_asg_hash, name, (void *) str);
737  (void) restore_line_pointer (c);
738  demand_empty_rest_of_line ();
739}
740
741/* .bss symbol, size  */
742static void
743tic4x_bss (int x ATTRIBUTE_UNUSED)
744{
745  char c;
746  char *name;
747  char *p;
748  offsetT size;
749  segT current_seg;
750  subsegT current_subseg;
751  symbolS *symbolP;
752
753  current_seg = now_seg;	/* Save current seg.  */
754  current_subseg = now_subseg;	/* Save current subseg.  */
755
756  SKIP_WHITESPACE ();
757  c = get_symbol_name (&name);	/* Get terminator.  */
758  if (c == '"')
759    c = * ++ input_line_pointer;
760  if (c != ',')
761    {
762      as_bad (_(".bss size argument missing\n"));
763      return;
764    }
765
766  input_line_pointer =
767    tic4x_expression_abs (++input_line_pointer, &size);
768  if (size < 0)
769    {
770      as_bad (_(".bss size %ld < 0!"), (long) size);
771      return;
772    }
773  subseg_set (bss_section, 0);
774  symbolP = symbol_find_or_make (name);
775
776  if (S_GET_SEGMENT (symbolP) == bss_section)
777    symbol_get_frag (symbolP)->fr_symbol = 0;
778
779  symbol_set_frag (symbolP, frag_now);
780
781  p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
782		size * OCTETS_PER_BYTE, (char *) 0);
783  *p = 0;			/* Fill char.  */
784
785  S_SET_SEGMENT (symbolP, bss_section);
786
787  /* The symbol may already have been created with a preceding
788     ".globl" directive -- be careful not to step on storage class
789     in that case.  Otherwise, set it to static.  */
790  if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
791    S_SET_STORAGE_CLASS (symbolP, C_STAT);
792
793  subseg_set (current_seg, current_subseg); /* Restore current seg.  */
794  demand_empty_rest_of_line ();
795}
796
797static void
798tic4x_globl (int ignore ATTRIBUTE_UNUSED)
799{
800  char *name;
801  int c;
802  symbolS *symbolP;
803
804  do
805    {
806      c = get_symbol_name (&name);
807      symbolP = symbol_find_or_make (name);
808      *input_line_pointer = c;
809      SKIP_WHITESPACE_AFTER_NAME ();
810      S_SET_STORAGE_CLASS (symbolP, C_EXT);
811      S_SET_EXTERNAL (symbolP);
812      if (c == ',')
813	{
814	  input_line_pointer++;
815	  SKIP_WHITESPACE ();
816	  if (*input_line_pointer == '\n')
817	    c = '\n';
818	}
819    }
820  while (c == ',');
821
822  demand_empty_rest_of_line ();
823}
824
825/* Handle .byte, .word. .int, .long */
826static void
827tic4x_cons (int bytes)
828{
829  unsigned int c;
830  do
831    {
832      SKIP_WHITESPACE ();
833      if (*input_line_pointer == '"')
834	{
835	  input_line_pointer++;
836	  while (is_a_char (c = next_char_of_string ()))
837	    tic4x_emit_char (c, 4);
838	  know (input_line_pointer[-1] == '\"');
839	}
840      else
841	{
842	  expressionS exp;
843
844	  input_line_pointer = tic4x_expression (input_line_pointer, &exp);
845	  if (exp.X_op == O_constant)
846	    {
847	      switch (bytes)
848		{
849		case 1:
850		  exp.X_add_number &= 255;
851		  break;
852		case 2:
853		  exp.X_add_number &= 65535;
854		  break;
855		}
856	    }
857	  /* Perhaps we should disallow .byte and .hword with
858	     a non constant expression that will require relocation.  */
859	  emit_expr (&exp, 4);
860	}
861    }
862  while (*input_line_pointer++ == ',');
863
864  input_line_pointer--;		/* Put terminator back into stream.  */
865  demand_empty_rest_of_line ();
866}
867
868/* Handle .ascii, .asciz, .string */
869static void
870tic4x_stringer (int append_zero)
871{
872  int bytes;
873  unsigned int c;
874
875  bytes = 0;
876  do
877    {
878      SKIP_WHITESPACE ();
879      if (*input_line_pointer == '"')
880	{
881	  input_line_pointer++;
882	  while (is_a_char (c = next_char_of_string ()))
883            {
884              tic4x_emit_char (c, 1);
885              bytes++;
886            }
887
888          if (append_zero)
889            {
890              tic4x_emit_char (c, 1);
891              bytes++;
892            }
893
894	  know (input_line_pointer[-1] == '\"');
895	}
896      else
897	{
898	  expressionS exp;
899
900	  input_line_pointer = tic4x_expression (input_line_pointer, &exp);
901	  if (exp.X_op != O_constant)
902            {
903              as_bad (_("Non-constant symbols not allowed\n"));
904              return;
905            }
906          exp.X_add_number &= 255; /* Limit numeber to 8-bit */
907	  emit_expr (&exp, 1);
908          bytes++;
909	}
910    }
911  while (*input_line_pointer++ == ',');
912
913  /* Fill out the rest of the expression with 0's to fill up a full word */
914  if ( bytes&0x3 )
915    tic4x_emit_char (0, 4-(bytes&0x3));
916
917  input_line_pointer--;		/* Put terminator back into stream.  */
918  demand_empty_rest_of_line ();
919}
920
921/* .eval expression, symbol */
922static void
923tic4x_eval (int x ATTRIBUTE_UNUSED)
924{
925  char c;
926  offsetT value;
927  char *name;
928
929  SKIP_WHITESPACE ();
930  input_line_pointer =
931    tic4x_expression_abs (input_line_pointer, &value);
932  if (*input_line_pointer++ != ',')
933    {
934      as_bad (_("Symbol missing\n"));
935      return;
936    }
937  c = get_symbol_name (&name);	/* Get terminator.  */
938  tic4x_insert_sym (name, value);
939  (void) restore_line_pointer (c);
940  demand_empty_rest_of_line ();
941}
942
943/* Reset local labels.  */
944static void
945tic4x_newblock (int x ATTRIBUTE_UNUSED)
946{
947  dollar_label_clear ();
948}
949
950/* .sect "section-name" [, value] */
951/* .sect ["]section-name[:subsection-name]["] [, value] */
952static void
953tic4x_sect (int x ATTRIBUTE_UNUSED)
954{
955  char c;
956  char *section_name;
957  char *name;
958  segT seg;
959  offsetT num;
960
961  SKIP_WHITESPACE ();
962  if (*input_line_pointer == '"')
963    input_line_pointer++;
964  c = get_symbol_name (&section_name);	/* Get terminator.  */
965  if (c == '"')
966    c = * ++ input_line_pointer;
967  input_line_pointer++;		/* Skip null symbol terminator.  */
968  name = xstrdup (section_name);
969
970  /* TI C from version 5.0 allows a section name to contain a
971     subsection name as well. The subsection name is separated by a
972     ':' from the section name.  Currently we scan the subsection
973     name and discard it.
974     Volker Kuhlmann  <v.kuhlmann@elec.canterbury.ac.nz>.  */
975  if (c == ':')
976    {
977      char *subname;
978      c = get_symbol_name (&subname);	/* Get terminator.  */
979      if (c == '"')
980	c = * ++ input_line_pointer;
981      input_line_pointer++;	/* Skip null symbol terminator.  */
982      as_warn (_(".sect: subsection name ignored"));
983    }
984
985  /* We might still have a '"' to discard, but the character after a
986     symbol name will be overwritten with a \0 by get_symbol_name()
987     [VK].  */
988
989  if (c == ',')
990    input_line_pointer =
991      tic4x_expression_abs (input_line_pointer, &num);
992  else if (*input_line_pointer == ',')
993    {
994      input_line_pointer =
995	tic4x_expression_abs (++input_line_pointer, &num);
996    }
997  else
998    num = 0;
999
1000  seg = subseg_new (name, num);
1001  if (line_label != NULL)
1002    {
1003      S_SET_SEGMENT (line_label, seg);
1004      symbol_set_frag (line_label, frag_now);
1005    }
1006
1007  if (bfd_get_section_flags (stdoutput, seg) == SEC_NO_FLAGS)
1008    {
1009      if (!bfd_set_section_flags (stdoutput, seg, SEC_DATA))
1010	as_warn (_("Error setting flags for \"%s\": %s"), name,
1011		 bfd_errmsg (bfd_get_error ()));
1012    }
1013
1014  /* If the last character overwritten by get_symbol_name() was an
1015     end-of-line, we must restore it or the end of the line will not be
1016     recognised and scanning extends into the next line, stopping with
1017     an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1018     if this is not true).  */
1019  if (is_end_of_line[(unsigned char) c])
1020    *(--input_line_pointer) = c;
1021
1022  demand_empty_rest_of_line ();
1023}
1024
1025/* symbol[:] .set value  or  .set symbol, value */
1026static void
1027tic4x_set (int x ATTRIBUTE_UNUSED)
1028{
1029  symbolS *symbolP;
1030
1031  SKIP_WHITESPACE ();
1032  if ((symbolP = line_label) == NULL)
1033    {
1034      char c;
1035      char *name;
1036
1037      c = get_symbol_name (&name);	/* Get terminator.  */
1038      if (c == '"')
1039	c = * ++ input_line_pointer;
1040      if (c != ',')
1041	{
1042	  as_bad (_(".set syntax invalid\n"));
1043	  ignore_rest_of_line ();
1044	  return;
1045	}
1046      ++input_line_pointer;
1047      symbolP = symbol_find_or_make (name);
1048    }
1049  else
1050    symbol_table_insert (symbolP);
1051
1052  pseudo_set (symbolP);
1053  demand_empty_rest_of_line ();
1054}
1055
1056/* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1057static void
1058tic4x_usect (int x ATTRIBUTE_UNUSED)
1059{
1060  char c;
1061  char *name;
1062  char *section_name;
1063  segT seg;
1064  offsetT size, alignment_flag;
1065  segT current_seg;
1066  subsegT current_subseg;
1067
1068  current_seg = now_seg;	/* save current seg.  */
1069  current_subseg = now_subseg;	/* save current subseg.  */
1070
1071  SKIP_WHITESPACE ();
1072  if (*input_line_pointer == '"')
1073    input_line_pointer++;
1074  c = get_symbol_name (&section_name);	/* Get terminator.  */
1075  if (c == '"')
1076    c = * ++ input_line_pointer;
1077  input_line_pointer++;		/* Skip null symbol terminator.  */
1078  name = xstrdup (section_name);
1079
1080  if (c == ',')
1081    input_line_pointer =
1082      tic4x_expression_abs (input_line_pointer, &size);
1083  else if (*input_line_pointer == ',')
1084    {
1085      input_line_pointer =
1086	tic4x_expression_abs (++input_line_pointer, &size);
1087    }
1088  else
1089    size = 0;
1090
1091  /* Read a possibly present third argument (alignment flag) [VK].  */
1092  if (*input_line_pointer == ',')
1093    {
1094      input_line_pointer =
1095	tic4x_expression_abs (++input_line_pointer, &alignment_flag);
1096    }
1097  else
1098    alignment_flag = 0;
1099  if (alignment_flag)
1100    as_warn (_(".usect: non-zero alignment flag ignored"));
1101
1102  seg = subseg_new (name, 0);
1103  if (line_label != NULL)
1104    {
1105      S_SET_SEGMENT (line_label, seg);
1106      symbol_set_frag (line_label, frag_now);
1107      S_SET_VALUE (line_label, frag_now_fix ());
1108    }
1109  seg_info (seg)->bss = 1;	/* Uninitialised data.  */
1110  if (!bfd_set_section_flags (stdoutput, seg, SEC_ALLOC))
1111    as_warn (_("Error setting flags for \"%s\": %s"), name,
1112	     bfd_errmsg (bfd_get_error ()));
1113  tic4x_seg_alloc (name, seg, size, line_label);
1114
1115  if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1116    S_SET_STORAGE_CLASS (line_label, C_STAT);
1117
1118  subseg_set (current_seg, current_subseg);	/* Restore current seg.  */
1119  demand_empty_rest_of_line ();
1120}
1121
1122/* .version cpu-version.  */
1123static void
1124tic4x_version (int x ATTRIBUTE_UNUSED)
1125{
1126  offsetT temp;
1127
1128  input_line_pointer =
1129    tic4x_expression_abs (input_line_pointer, &temp);
1130  if (!IS_CPU_TIC3X (temp) && !IS_CPU_TIC4X (temp))
1131    as_bad (_("This assembler does not support processor generation %ld"),
1132	    (long) temp);
1133
1134  if (tic4x_cpu && temp != (offsetT) tic4x_cpu)
1135    as_warn (_("Changing processor generation on fly not supported..."));
1136  tic4x_cpu = temp;
1137  demand_empty_rest_of_line ();
1138}
1139
1140static void
1141tic4x_init_regtable (void)
1142{
1143  unsigned int i;
1144
1145  for (i = 0; i < tic3x_num_registers; i++)
1146    tic4x_insert_reg (tic3x_registers[i].name,
1147		    tic3x_registers[i].regno);
1148
1149  if (IS_CPU_TIC4X (tic4x_cpu))
1150    {
1151      /* Add additional Tic4x registers, overriding some C3x ones.  */
1152      for (i = 0; i < tic4x_num_registers; i++)
1153	tic4x_insert_reg (tic4x_registers[i].name,
1154			tic4x_registers[i].regno);
1155    }
1156}
1157
1158static void
1159tic4x_init_symbols (void)
1160{
1161  /* The TI tools accept case insensitive versions of these symbols,
1162     we don't !
1163
1164     For TI C/Asm 5.0
1165
1166     .TMS320xx       30,31,32,40,or 44       set according to -v flag
1167     .C3X or .C3x    1 or 0                  1 if -v30,-v31,or -v32
1168     .C30            1 or 0                  1 if -v30
1169     .C31            1 or 0                  1 if -v31
1170     .C32            1 or 0                  1 if -v32
1171     .C4X or .C4x    1 or 0                  1 if -v40, or -v44
1172     .C40            1 or 0                  1 if -v40
1173     .C44            1 or 0                  1 if -v44
1174
1175     .REGPARM 1 or 0                  1 if -mr option used
1176     .BIGMODEL        1 or 0                  1 if -mb option used
1177
1178     These symbols are currently supported but will be removed in a
1179     later version:
1180     .TMS320C30      1 or 0                  1 if -v30,-v31,or -v32
1181     .TMS320C31      1 or 0                  1 if -v31
1182     .TMS320C32      1 or 0                  1 if -v32
1183     .TMS320C40      1 or 0                  1 if -v40, or -v44
1184     .TMS320C44      1 or 0                  1 if -v44
1185
1186     Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1187     1997, SPRU035C, p. 3-17/3-18.  */
1188  tic4x_insert_sym (".REGPARM", tic4x_reg_args);
1189  tic4x_insert_sym (".MEMPARM", !tic4x_reg_args);
1190  tic4x_insert_sym (".BIGMODEL", tic4x_big_model);
1191  tic4x_insert_sym (".C30INTERRUPT", 0);
1192  tic4x_insert_sym (".TMS320xx", tic4x_cpu == 0 ? 40 : tic4x_cpu);
1193  tic4x_insert_sym (".C3X", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1194  tic4x_insert_sym (".C3x", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1195  tic4x_insert_sym (".C4X", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1196  tic4x_insert_sym (".C4x", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1197  /* Do we need to have the following symbols also in lower case?  */
1198  tic4x_insert_sym (".TMS320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1199  tic4x_insert_sym (".tms320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1200  tic4x_insert_sym (".TMS320C31", tic4x_cpu == 31);
1201  tic4x_insert_sym (".tms320C31", tic4x_cpu == 31);
1202  tic4x_insert_sym (".TMS320C32", tic4x_cpu == 32);
1203  tic4x_insert_sym (".tms320C32", tic4x_cpu == 32);
1204  tic4x_insert_sym (".TMS320C33", tic4x_cpu == 33);
1205  tic4x_insert_sym (".tms320C33", tic4x_cpu == 33);
1206  tic4x_insert_sym (".TMS320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1207  tic4x_insert_sym (".tms320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1208  tic4x_insert_sym (".TMS320C44", tic4x_cpu == 44);
1209  tic4x_insert_sym (".tms320C44", tic4x_cpu == 44);
1210  tic4x_insert_sym (".TMX320C40", 0);	/* C40 first pass silicon ?  */
1211  tic4x_insert_sym (".tmx320C40", 0);
1212}
1213
1214/* Insert a new instruction template into hash table.  */
1215static int
1216tic4x_inst_insert (const tic4x_inst_t *inst)
1217{
1218  static char prev_name[16];
1219  const char *retval = NULL;
1220
1221  /* Only insert the first name if have several similar entries.  */
1222  if (!strcmp (inst->name, prev_name) || inst->name[0] == '\0')
1223    return 1;
1224
1225  retval = hash_insert (tic4x_op_hash, inst->name, (void *) inst);
1226  if (retval != NULL)
1227    fprintf (stderr, "internal error: can't hash `%s': %s\n",
1228	     inst->name, retval);
1229  else
1230    strcpy (prev_name, inst->name);
1231  return retval == NULL;
1232}
1233
1234/* Make a new instruction template.  */
1235static tic4x_inst_t *
1236tic4x_inst_make (const char *name, unsigned long opcode, const char *args)
1237{
1238  static tic4x_inst_t *insts = NULL;
1239  static char *names = NULL;
1240  static int iindex = 0;
1241
1242  if (insts == NULL)
1243    {
1244      /* Allocate memory to store name strings.  */
1245      names = XNEWVEC (char, 8192);
1246      /* Allocate memory for additional insts.  */
1247      insts = XNEWVEC (tic4x_inst_t, 1024);
1248    }
1249  insts[iindex].name = names;
1250  insts[iindex].opcode = opcode;
1251  insts[iindex].opmask = 0xffffffff;
1252  insts[iindex].args = args;
1253  iindex++;
1254
1255  do
1256    *names++ = *name++;
1257  while (*name);
1258  *names++ = '\0';
1259
1260  return &insts[iindex - 1];
1261}
1262
1263/* Add instruction template, creating dynamic templates as required.  */
1264static int
1265tic4x_inst_add (const tic4x_inst_t *insts)
1266{
1267  const char *s = insts->name;
1268  char *d;
1269  unsigned int i;
1270  int ok = 1;
1271  char name[16];
1272
1273  d = name;
1274
1275  /* We do not care about INSNs that is not a part of our
1276     oplevel setting.  */
1277  if ((insts->oplevel & tic4x_oplevel) == 0)
1278    return ok;
1279
1280  while (1)
1281    {
1282      switch (*s)
1283	{
1284	case 'B':
1285	case 'C':
1286	  /* Dynamically create all the conditional insts.  */
1287	  for (i = 0; i < tic4x_num_conds; i++)
1288	    {
1289	      tic4x_inst_t *inst;
1290	      int k = 0;
1291	      const char *c = tic4x_conds[i].name;
1292	      char *e = d;
1293
1294	      while (*c)
1295		*e++ = *c++;
1296	      c = s + 1;
1297	      while (*c)
1298		*e++ = *c++;
1299	      *e = '\0';
1300
1301	      /* If instruction found then have already processed it.  */
1302	      if (hash_find (tic4x_op_hash, name))
1303		return 1;
1304
1305	      do
1306		{
1307		  inst = tic4x_inst_make (name, insts[k].opcode +
1308					(tic4x_conds[i].cond <<
1309					 (*s == 'B' ? 16 : 23)),
1310					insts[k].args);
1311		  if (k == 0)	/* Save strcmp() with following func.  */
1312		    ok &= tic4x_inst_insert (inst);
1313		  k++;
1314		}
1315	      while (!strcmp (insts->name,
1316			      insts[k].name));
1317	    }
1318	  return ok;
1319	  break;
1320
1321	case '\0':
1322	  return tic4x_inst_insert (insts);
1323	  break;
1324
1325	default:
1326	  *d++ = *s++;
1327	  break;
1328	}
1329    }
1330}
1331
1332/* This function is called once, at assembler startup time.  It should
1333   set up all the tables, etc., that the MD part of the assembler will
1334   need.  */
1335void
1336md_begin (void)
1337{
1338  int ok = 1;
1339  unsigned int i;
1340
1341  /* Setup the proper opcode level according to the
1342     commandline parameters */
1343  tic4x_oplevel = OP_C3X;
1344
1345  if ( IS_CPU_TIC4X(tic4x_cpu) )
1346    tic4x_oplevel |= OP_C4X;
1347
1348  if ( (   tic4x_cpu == 31 && tic4x_revision >= 6)
1349       || (tic4x_cpu == 32 && tic4x_revision >= 2)
1350       || (tic4x_cpu == 33)
1351       || tic4x_enhanced )
1352    tic4x_oplevel |= OP_ENH;
1353
1354  if ( (   tic4x_cpu == 30 && tic4x_revision >= 7)
1355       || (tic4x_cpu == 31 && tic4x_revision >= 5)
1356       || (tic4x_cpu == 32)
1357       || tic4x_lowpower )
1358    tic4x_oplevel |= OP_LPWR;
1359
1360  if ( (   tic4x_cpu == 30 && tic4x_revision >= 7)
1361       || (tic4x_cpu == 31 && tic4x_revision >= 5)
1362       || (tic4x_cpu == 32)
1363       || (tic4x_cpu == 33)
1364       || (tic4x_cpu == 40 && tic4x_revision >= 5)
1365       || (tic4x_cpu == 44)
1366       || tic4x_idle2 )
1367    tic4x_oplevel |= OP_IDLE2;
1368
1369  /* Create hash table for mnemonics.  */
1370  tic4x_op_hash = hash_new ();
1371
1372  /* Create hash table for asg pseudo.  */
1373  tic4x_asg_hash = hash_new ();
1374
1375  /* Add mnemonics to hash table, expanding conditional mnemonics on fly.  */
1376  for (i = 0; i < tic4x_num_insts; i++)
1377    ok &= tic4x_inst_add (tic4x_insts + i);
1378
1379  /* Create dummy inst to avoid errors accessing end of table.  */
1380  tic4x_inst_make ("", 0, "");
1381
1382  if (!ok)
1383    as_fatal ("Broken assembler.  No assembly attempted.");
1384
1385  /* Add registers to symbol table.  */
1386  tic4x_init_regtable ();
1387
1388  /* Add predefined symbols to symbol table.  */
1389  tic4x_init_symbols ();
1390}
1391
1392void
1393tic4x_end (void)
1394{
1395  bfd_set_arch_mach (stdoutput, bfd_arch_tic4x,
1396		     IS_CPU_TIC4X (tic4x_cpu) ? bfd_mach_tic4x : bfd_mach_tic3x);
1397}
1398
1399static int
1400tic4x_indirect_parse (tic4x_operand_t *operand,
1401		      const tic4x_indirect_t *indirect)
1402{
1403  const char *n = indirect->name;
1404  char *s = input_line_pointer;
1405  char *b;
1406  symbolS *symbolP;
1407  char name[32];
1408
1409  operand->disp = 0;
1410  for (; *n; n++)
1411    {
1412      switch (*n)
1413	{
1414	case 'a':		/* Need to match aux register.  */
1415	  b = name;
1416#ifdef TIC4X_ALT_SYNTAX
1417	  if (*s == '%')
1418	    s++;
1419#endif
1420	  while (ISALNUM (*s))
1421	    *b++ = *s++;
1422	  *b++ = '\0';
1423	  if (!(symbolP = symbol_find (name)))
1424	    return 0;
1425
1426	  if (S_GET_SEGMENT (symbolP) != reg_section)
1427	    return 0;
1428
1429	  operand->aregno = S_GET_VALUE (symbolP);
1430	  if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7)
1431	    break;
1432
1433	  as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1434	  return -1;
1435
1436	case 'd':		/* Need to match constant for disp.  */
1437#ifdef TIC4X_ALT_SYNTAX
1438	  if (*s == '%')	/* expr() will die if we don't skip this.  */
1439	    s++;
1440#endif
1441	  s = tic4x_expression (s, &operand->expr);
1442	  if (operand->expr.X_op != O_constant)
1443	    return 0;
1444	  operand->disp = operand->expr.X_add_number;
1445	  if (operand->disp < 0 || operand->disp > 255)
1446	    {
1447	      as_bad (_("Bad displacement %d (require 0--255)\n"),
1448		      operand->disp);
1449	      return -1;
1450	    }
1451	  break;
1452
1453	case 'y':		/* Need to match IR0.  */
1454	case 'z':		/* Need to match IR1.  */
1455#ifdef TIC4X_ALT_SYNTAX
1456	  if (*s == '%')
1457	    s++;
1458#endif
1459	  s = tic4x_expression (s, &operand->expr);
1460	  if (operand->expr.X_op != O_register)
1461	    return 0;
1462	  if (operand->expr.X_add_number != REG_IR0
1463	      && operand->expr.X_add_number != REG_IR1)
1464	    {
1465	      as_bad (_("Index register IR0,IR1 required for displacement"));
1466	      return -1;
1467	    }
1468
1469	  if (*n == 'y' && operand->expr.X_add_number == REG_IR0)
1470	    break;
1471	  if (*n == 'z' && operand->expr.X_add_number == REG_IR1)
1472	    break;
1473	  return 0;
1474
1475	case '(':
1476	  if (*s != '(')	/* No displacement, assume to be 1.  */
1477	    {
1478	      operand->disp = 1;
1479	      while (*n != ')')
1480		n++;
1481	    }
1482	  else
1483	    s++;
1484	  break;
1485
1486	default:
1487	  if (TOLOWER (*s) != *n)
1488	    return 0;
1489	  s++;
1490	}
1491    }
1492  if (*s != ' ' && *s != ',' && *s != '\0')
1493    return 0;
1494  input_line_pointer = s;
1495  return 1;
1496}
1497
1498static char *
1499tic4x_operand_parse (char *s, tic4x_operand_t *operand)
1500{
1501  unsigned int i;
1502  char c;
1503  int ret;
1504  expressionS *exp = &operand->expr;
1505  char *save = input_line_pointer;
1506  char *str;
1507  char *new_pointer;
1508  struct hash_entry *entry = NULL;
1509
1510  input_line_pointer = s;
1511  SKIP_WHITESPACE ();
1512
1513  c = get_symbol_name (&str);	/* Get terminator.  */
1514  new_pointer = input_line_pointer;
1515  if (strlen (str) && (entry = hash_find (tic4x_asg_hash, str)) != NULL)
1516    {
1517      (void) restore_line_pointer (c);
1518      input_line_pointer = (char *) entry;
1519    }
1520  else
1521    {
1522      (void) restore_line_pointer (c);
1523      input_line_pointer = str;
1524    }
1525
1526  operand->mode = M_UNKNOWN;
1527  switch (*input_line_pointer)
1528    {
1529#ifdef TIC4X_ALT_SYNTAX
1530    case '%':
1531      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1532      if (exp->X_op != O_register)
1533	as_bad (_("Expecting a register name"));
1534      operand->mode = M_REGISTER;
1535      break;
1536
1537    case '^':
1538      /* Denotes high 16 bits.  */
1539      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1540      if (exp->X_op == O_constant)
1541	operand->mode = M_IMMED;
1542      else if (exp->X_op == O_big)
1543	{
1544	  if (exp->X_add_number)
1545	    as_bad (_("Number too large"));	/* bignum required */
1546	  else
1547	    {
1548	      tic4x_gen_to_words (generic_floating_point_number,
1549				operand->fwords, S_PRECISION);
1550	      operand->mode = M_IMMED_F;
1551	    }
1552	}
1553      /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0  */
1554      /* WARNING : The TI C40 assembler cannot do this.  */
1555      else if (exp->X_op == O_symbol)
1556	operand->mode = M_HI;
1557      else
1558	as_bad (_("Expecting a constant value"));
1559      break;
1560
1561    case '#':
1562      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1563      if (exp->X_op == O_constant)
1564	operand->mode = M_IMMED;
1565      else if (exp->X_op == O_big)
1566	{
1567	  if (exp->X_add_number > 0)
1568	    as_bad (_("Number too large"));	/* bignum required.  */
1569	  else
1570	    {
1571	      tic4x_gen_to_words (generic_floating_point_number,
1572				operand->fwords, S_PRECISION);
1573	      operand->mode = M_IMMED_F;
1574	    }
1575	}
1576      /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0  */
1577      /* WARNING : The TI C40 assembler cannot do this.  */
1578      else if (exp->X_op == O_symbol)
1579	operand->mode = M_IMMED;
1580      else
1581	as_bad (_("Expecting a constant value"));
1582      break;
1583
1584    case '\\':
1585#endif
1586    case '@':
1587      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1588      if (exp->X_op != O_constant && exp->X_op != O_symbol)
1589	as_bad (_("Bad direct addressing construct %s"), s);
1590      if (exp->X_op == O_constant)
1591	{
1592	  if (exp->X_add_number < 0)
1593	    as_bad (_("Direct value of %ld is not suitable"),
1594		    (long) exp->X_add_number);
1595	}
1596      operand->mode = M_DIRECT;
1597      break;
1598
1599    case '*':
1600      ret = -1;
1601      for (i = 0; i < tic4x_num_indirects; i++)
1602	if ((ret = tic4x_indirect_parse (operand, &tic4x_indirects[i])))
1603	  break;
1604      if (ret < 0)
1605	break;
1606      if (i < tic4x_num_indirects)
1607	{
1608	  operand->mode = M_INDIRECT;
1609	  /* Indirect addressing mode number.  */
1610	  operand->expr.X_add_number = tic4x_indirects[i].modn;
1611	  /* Convert *+ARn(0) to *ARn etc.  Maybe we should
1612	     squeal about silly ones?  */
1613	  if (operand->expr.X_add_number < 0x08 && !operand->disp)
1614	    operand->expr.X_add_number = 0x18;
1615	}
1616      else
1617	as_bad (_("Unknown indirect addressing mode"));
1618      break;
1619
1620    default:
1621      operand->mode = M_IMMED;	/* Assume immediate.  */
1622      str = input_line_pointer;
1623      input_line_pointer = tic4x_expression (input_line_pointer, exp);
1624      if (exp->X_op == O_register)
1625	{
1626	  know (exp->X_add_symbol == 0);
1627	  know (exp->X_op_symbol == 0);
1628	  operand->mode = M_REGISTER;
1629	  break;
1630	}
1631      else if (exp->X_op == O_big)
1632	{
1633	  if (exp->X_add_number > 0)
1634	    as_bad (_("Number too large"));	/* bignum required.  */
1635	  else
1636	    {
1637	      tic4x_gen_to_words (generic_floating_point_number,
1638				operand->fwords, S_PRECISION);
1639	      operand->mode = M_IMMED_F;
1640	    }
1641	  break;
1642	}
1643#ifdef TIC4X_ALT_SYNTAX
1644      /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0.  */
1645      else if (exp->X_op == O_symbol)
1646	{
1647	  operand->mode = M_DIRECT;
1648	  break;
1649	}
1650#endif
1651    }
1652  if (entry == NULL)
1653    new_pointer = input_line_pointer;
1654  input_line_pointer = save;
1655  return new_pointer;
1656}
1657
1658static int
1659tic4x_operands_match (tic4x_inst_t *inst, tic4x_insn_t *tinsn, int check)
1660{
1661  const char *args = inst->args;
1662  unsigned long opcode = inst->opcode;
1663  int num_operands = tinsn->num_operands;
1664  tic4x_operand_t *operand = tinsn->operands;
1665  expressionS *exp = &operand->expr;
1666  int ret = 1;
1667  int reg;
1668
1669  /* Build the opcode, checking as we go to make sure that the
1670     operands match.
1671
1672     If an operand matches, we modify insn or opcode appropriately,
1673     and do a "continue".  If an operand fails to match, we "break".  */
1674
1675  tinsn->nchars = 4;		/* Instructions always 4 bytes.  */
1676  tinsn->reloc = NO_RELOC;
1677  tinsn->pcrel = 0;
1678
1679  if (*args == '\0')
1680    {
1681      tinsn->opcode = opcode;
1682      return num_operands == 0;
1683    }
1684
1685  for (;; ++args)
1686    {
1687      switch (*args)
1688	{
1689
1690	case '\0':		/* End of args.  */
1691	  if (num_operands == 1)
1692	    {
1693	      tinsn->opcode = opcode;
1694	      return ret;
1695	    }
1696	  break;		/* Too many operands.  */
1697
1698	case '#':		/* This is only used for ldp.  */
1699	  if (operand->mode != M_DIRECT && operand->mode != M_IMMED)
1700	    break;
1701	  /* While this looks like a direct addressing mode, we actually
1702	     use an immediate mode form of ldiu or ldpk instruction.  */
1703	  if (exp->X_op == O_constant)
1704	    {
1705              if( ( IS_CPU_TIC4X (tic4x_cpu) && exp->X_add_number <= 65535 )
1706                  || ( IS_CPU_TIC3X (tic4x_cpu) && exp->X_add_number <= 255 ) )
1707                {
1708                  INSERTS (opcode, exp->X_add_number, 15, 0);
1709                  continue;
1710                }
1711              else
1712                {
1713		  if (!check)
1714                    as_bad (_("Immediate value of %ld is too large for ldf"),
1715                            (long) exp->X_add_number);
1716		  ret = -1;
1717		  continue;
1718                }
1719	    }
1720	  else if (exp->X_op == O_symbol)
1721	    {
1722	      tinsn->reloc = BFD_RELOC_HI16;
1723	      tinsn->exp = *exp;
1724	      continue;
1725	    }
1726	  break;		/* Not direct (dp) addressing.  */
1727
1728	case '@':		/* direct.  */
1729	  if (operand->mode != M_DIRECT)
1730	    break;
1731	  if (exp->X_op == O_constant)
1732            {
1733              /* Store only the 16 LSBs of the number.  */
1734              INSERTS (opcode, exp->X_add_number, 15, 0);
1735              continue;
1736	    }
1737	  else if (exp->X_op == O_symbol)
1738	    {
1739	      tinsn->reloc = BFD_RELOC_LO16;
1740	      tinsn->exp = *exp;
1741	      continue;
1742	    }
1743	  break;		/* Not direct addressing.  */
1744
1745	case 'A':
1746	  if (operand->mode != M_REGISTER)
1747	    break;
1748	  reg = exp->X_add_number;
1749	  if (reg >= REG_AR0 && reg <= REG_AR7)
1750	    INSERTU (opcode, reg - REG_AR0, 24, 22);
1751	  else
1752	    {
1753              if (!check)
1754                as_bad (_("Destination register must be ARn"));
1755	      ret = -1;
1756	    }
1757	  continue;
1758
1759	case 'B':		/* Unsigned integer immediate.  */
1760	  /* Allow br label or br @label.  */
1761	  if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
1762	    break;
1763	  if (exp->X_op == O_constant)
1764	    {
1765	      if (exp->X_add_number < (1 << 24))
1766		{
1767		  INSERTU (opcode, exp->X_add_number, 23, 0);
1768		  continue;
1769		}
1770	      else
1771		{
1772		  if (!check)
1773                    as_bad (_("Immediate value of %ld is too large"),
1774                            (long) exp->X_add_number);
1775		  ret = -1;
1776		  continue;
1777		}
1778	    }
1779	  if (IS_CPU_TIC4X (tic4x_cpu))
1780	    {
1781	      tinsn->reloc = BFD_RELOC_24_PCREL;
1782	      tinsn->pcrel = 1;
1783	    }
1784	  else
1785	    {
1786	      tinsn->reloc = BFD_RELOC_24;
1787	      tinsn->pcrel = 0;
1788	    }
1789	  tinsn->exp = *exp;
1790	  continue;
1791
1792	case 'C':
1793	  if (!IS_CPU_TIC4X (tic4x_cpu))
1794	    break;
1795	  if (operand->mode != M_INDIRECT)
1796	    break;
1797	  /* Require either *+ARn(disp) or *ARn.  */
1798	  if (operand->expr.X_add_number != 0
1799	      && operand->expr.X_add_number != 0x18)
1800	    {
1801              if (!check)
1802                as_bad (_("Invalid indirect addressing mode"));
1803              ret = -1;
1804	      continue;
1805	    }
1806	  INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1807	  INSERTU (opcode, operand->disp, 7, 3);
1808	  continue;
1809
1810	case 'E':
1811	  if (!(operand->mode == M_REGISTER))
1812	    break;
1813	  INSERTU (opcode, exp->X_add_number, 7, 0);
1814	  continue;
1815
1816        case 'e':
1817          if (!(operand->mode == M_REGISTER))
1818            break;
1819	  reg = exp->X_add_number;
1820	  if ( (reg >= REG_R0 && reg <= REG_R7)
1821               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1822	    INSERTU (opcode, reg, 7, 0);
1823	  else
1824	    {
1825              if (!check)
1826                as_bad (_("Register must be Rn"));
1827	      ret = -1;
1828	    }
1829          continue;
1830
1831	case 'F':
1832	  if (operand->mode != M_IMMED_F
1833	      && !(operand->mode == M_IMMED && exp->X_op == O_constant))
1834	    break;
1835
1836	  if (operand->mode != M_IMMED_F)
1837	    {
1838	      /* OK, we 've got something like cmpf 0, r0
1839	         Why can't they stick in a bloody decimal point ?!  */
1840	      char string[16];
1841
1842	      /* Create floating point number string.  */
1843	      sprintf (string, "%d.0", (int) exp->X_add_number);
1844	      tic4x_atof (string, 's', operand->fwords);
1845	    }
1846
1847	  INSERTU (opcode, operand->fwords[0], 15, 0);
1848	  continue;
1849
1850	case 'G':
1851	  if (operand->mode != M_REGISTER)
1852	    break;
1853	  INSERTU (opcode, exp->X_add_number, 15, 8);
1854	  continue;
1855
1856        case 'g':
1857	  if (operand->mode != M_REGISTER)
1858	    break;
1859	  reg = exp->X_add_number;
1860	  if ( (reg >= REG_R0 && reg <= REG_R7)
1861               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1862	    INSERTU (opcode, reg, 15, 8);
1863	  else
1864	    {
1865              if (!check)
1866                as_bad (_("Register must be Rn"));
1867	      ret = -1;
1868	    }
1869          continue;
1870
1871	case 'H':
1872	  if (operand->mode != M_REGISTER)
1873	    break;
1874	  reg = exp->X_add_number;
1875	  if (reg >= REG_R0 && reg <= REG_R7)
1876	    INSERTU (opcode, reg - REG_R0, 18, 16);
1877	  else
1878	    {
1879              if (!check)
1880                as_bad (_("Register must be R0--R7"));
1881	      ret = -1;
1882	    }
1883	  continue;
1884
1885        case 'i':
1886          if ( operand->mode == M_REGISTER
1887               && tic4x_oplevel & OP_ENH )
1888            {
1889              reg = exp->X_add_number;
1890              INSERTU (opcode, reg, 4, 0);
1891              INSERTU (opcode, 7, 7, 5);
1892              continue;
1893            }
1894          /* Fallthrough */
1895
1896	case 'I':
1897	  if (operand->mode != M_INDIRECT)
1898	    break;
1899	  if (operand->disp != 0 && operand->disp != 1)
1900	    {
1901	      if (IS_CPU_TIC4X (tic4x_cpu))
1902		break;
1903              if (!check)
1904                as_bad (_("Invalid indirect addressing mode displacement %d"),
1905                        operand->disp);
1906	      ret = -1;
1907	      continue;
1908	    }
1909	  INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1910	  INSERTU (opcode, operand->expr.X_add_number, 7, 3);
1911	  continue;
1912
1913        case 'j':
1914          if ( operand->mode == M_REGISTER
1915               && tic4x_oplevel & OP_ENH )
1916            {
1917              reg = exp->X_add_number;
1918              INSERTU (opcode, reg, 12, 8);
1919              INSERTU (opcode, 7, 15, 13);
1920              continue;
1921            }
1922          /* Fallthrough */
1923
1924	case 'J':
1925	  if (operand->mode != M_INDIRECT)
1926	    break;
1927	  if (operand->disp != 0 && operand->disp != 1)
1928	    {
1929	      if (IS_CPU_TIC4X (tic4x_cpu))
1930		break;
1931              if (!check)
1932                as_bad (_("Invalid indirect addressing mode displacement %d"),
1933                        operand->disp);
1934	      ret = -1;
1935	      continue;
1936	    }
1937	  INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
1938	  INSERTU (opcode, operand->expr.X_add_number, 15, 11);
1939	  continue;
1940
1941	case 'K':
1942	  if (operand->mode != M_REGISTER)
1943	    break;
1944	  reg = exp->X_add_number;
1945	  if (reg >= REG_R0 && reg <= REG_R7)
1946	    INSERTU (opcode, reg - REG_R0, 21, 19);
1947	  else
1948	    {
1949              if (!check)
1950                as_bad (_("Register must be R0--R7"));
1951	      ret = -1;
1952	    }
1953	  continue;
1954
1955	case 'L':
1956	  if (operand->mode != M_REGISTER)
1957	    break;
1958	  reg = exp->X_add_number;
1959	  if (reg >= REG_R0 && reg <= REG_R7)
1960	    INSERTU (opcode, reg - REG_R0, 24, 22);
1961	  else
1962	    {
1963              if (!check)
1964                as_bad (_("Register must be R0--R7"));
1965	      ret = -1;
1966	    }
1967	  continue;
1968
1969	case 'M':
1970	  if (operand->mode != M_REGISTER)
1971	    break;
1972	  reg = exp->X_add_number;
1973	  if (reg == REG_R2 || reg == REG_R3)
1974	    INSERTU (opcode, reg - REG_R2, 22, 22);
1975	  else
1976	    {
1977              if (!check)
1978                as_bad (_("Destination register must be R2 or R3"));
1979	      ret = -1;
1980	    }
1981	  continue;
1982
1983	case 'N':
1984	  if (operand->mode != M_REGISTER)
1985	    break;
1986	  reg = exp->X_add_number;
1987	  if (reg == REG_R0 || reg == REG_R1)
1988	    INSERTU (opcode, reg - REG_R0, 23, 23);
1989	  else
1990	    {
1991              if (!check)
1992                as_bad (_("Destination register must be R0 or R1"));
1993	      ret = -1;
1994	    }
1995	  continue;
1996
1997	case 'O':
1998	  if (!IS_CPU_TIC4X (tic4x_cpu))
1999	    break;
2000	  if (operand->mode != M_INDIRECT)
2001	    break;
2002	  /* Require either *+ARn(disp) or *ARn.  */
2003	  if (operand->expr.X_add_number != 0
2004	      && operand->expr.X_add_number != 0x18)
2005	    {
2006              if (!check)
2007                as_bad (_("Invalid indirect addressing mode"));
2008	      ret = -1;
2009	      continue;
2010	    }
2011	  INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2012	  INSERTU (opcode, operand->disp, 15, 11);
2013	  continue;
2014
2015	case 'P':		/* PC relative displacement.  */
2016	  /* Allow br label or br @label.  */
2017	  if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
2018	    break;
2019	  if (exp->X_op == O_constant)
2020	    {
2021	      if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767)
2022		{
2023		  INSERTS (opcode, exp->X_add_number, 15, 0);
2024		  continue;
2025		}
2026	      else
2027		{
2028                  if (!check)
2029                    as_bad (_("Displacement value of %ld is too large"),
2030                            (long) exp->X_add_number);
2031		  ret = -1;
2032		  continue;
2033		}
2034	    }
2035	  tinsn->reloc = BFD_RELOC_16_PCREL;
2036	  tinsn->pcrel = 1;
2037	  tinsn->exp = *exp;
2038	  continue;
2039
2040	case 'Q':
2041	  if (operand->mode != M_REGISTER)
2042	    break;
2043	  reg = exp->X_add_number;
2044	  INSERTU (opcode, reg, 15, 0);
2045	  continue;
2046
2047        case 'q':
2048	  if (operand->mode != M_REGISTER)
2049	    break;
2050	  reg = exp->X_add_number;
2051	  if ( (reg >= REG_R0 && reg <= REG_R7)
2052               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2053	    INSERTU (opcode, reg, 15, 0);
2054	  else
2055	    {
2056              if (!check)
2057                as_bad (_("Register must be Rn"));
2058	      ret = -1;
2059	    }
2060          continue;
2061
2062	case 'R':
2063	  if (operand->mode != M_REGISTER)
2064	    break;
2065	  reg = exp->X_add_number;
2066	  INSERTU (opcode, reg, 20, 16);
2067	  continue;
2068
2069        case 'r':
2070	  if (operand->mode != M_REGISTER)
2071	    break;
2072	  reg = exp->X_add_number;
2073	  if ( (reg >= REG_R0 && reg <= REG_R7)
2074               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2075	    INSERTU (opcode, reg, 20, 16);
2076	  else
2077	    {
2078              if (!check)
2079                as_bad (_("Register must be Rn"));
2080	      ret = -1;
2081	    }
2082          continue;
2083
2084	case 'S':		/* Short immediate int.  */
2085	  if (operand->mode != M_IMMED && operand->mode != M_HI)
2086	    break;
2087	  if (exp->X_op == O_big)
2088	    {
2089              if (!check)
2090                as_bad (_("Floating point number not valid in expression"));
2091	      ret = -1;
2092	      continue;
2093	    }
2094	  if (exp->X_op == O_constant)
2095	    {
2096	      if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535)
2097		{
2098		  INSERTS (opcode, exp->X_add_number, 15, 0);
2099		  continue;
2100		}
2101	      else
2102		{
2103		  if (!check)
2104                    as_bad (_("Signed immediate value %ld too large"),
2105                            (long) exp->X_add_number);
2106		  ret = -1;
2107		  continue;
2108		}
2109	    }
2110	  else if (exp->X_op == O_symbol)
2111	    {
2112	      if (operand->mode == M_HI)
2113		{
2114		  tinsn->reloc = BFD_RELOC_HI16;
2115		}
2116	      else
2117		{
2118		  tinsn->reloc = BFD_RELOC_LO16;
2119		}
2120	      tinsn->exp = *exp;
2121	      continue;
2122	    }
2123	  /* Handle cases like ldi foo - $, ar0  where foo
2124	     is a forward reference.  Perhaps we should check
2125	     for X_op == O_symbol and disallow things like
2126	     ldi foo, ar0.  */
2127	  tinsn->reloc = BFD_RELOC_16;
2128	  tinsn->exp = *exp;
2129	  continue;
2130
2131	case 'T':		/* 5-bit immediate value for tic4x stik.  */
2132	  if (!IS_CPU_TIC4X (tic4x_cpu))
2133	    break;
2134	  if (operand->mode != M_IMMED)
2135	    break;
2136	  if (exp->X_op == O_constant)
2137	    {
2138	      if (exp->X_add_number < 16 && exp->X_add_number >= -16)
2139		{
2140		  INSERTS (opcode, exp->X_add_number, 20, 16);
2141		  continue;
2142		}
2143	      else
2144		{
2145                  if (!check)
2146                    as_bad (_("Immediate value of %ld is too large"),
2147                            (long) exp->X_add_number);
2148		  ret = -1;
2149		  continue;
2150		}
2151	    }
2152	  break;		/* No relocations allowed.  */
2153
2154	case 'U':		/* Unsigned integer immediate.  */
2155	  if (operand->mode != M_IMMED && operand->mode != M_HI)
2156	    break;
2157	  if (exp->X_op == O_constant)
2158	    {
2159	      if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0)
2160		{
2161		  INSERTU (opcode, exp->X_add_number, 15, 0);
2162		  continue;
2163		}
2164	      else
2165		{
2166                  if (!check)
2167                    as_bad (_("Unsigned immediate value %ld too large"),
2168                            (long) exp->X_add_number);
2169		  ret = -1;
2170		  continue;
2171		}
2172	    }
2173	  else if (exp->X_op == O_symbol)
2174	    {
2175	      if (operand->mode == M_HI)
2176		tinsn->reloc = BFD_RELOC_HI16;
2177	      else
2178		tinsn->reloc = BFD_RELOC_LO16;
2179
2180	      tinsn->exp = *exp;
2181	      continue;
2182	    }
2183	  tinsn->reloc = BFD_RELOC_16;
2184	  tinsn->exp = *exp;
2185	  continue;
2186
2187	case 'V':		/* Trap numbers (immediate field).  */
2188	  if (operand->mode != M_IMMED)
2189	    break;
2190	  if (exp->X_op == O_constant)
2191	    {
2192	      if (exp->X_add_number < 512 && IS_CPU_TIC4X (tic4x_cpu))
2193		{
2194		  INSERTU (opcode, exp->X_add_number, 8, 0);
2195		  continue;
2196		}
2197	      else if (exp->X_add_number < 32 && IS_CPU_TIC3X (tic4x_cpu))
2198		{
2199		  INSERTU (opcode, exp->X_add_number | 0x20, 4, 0);
2200		  continue;
2201		}
2202	      else
2203		{
2204                  if (!check)
2205                    as_bad (_("Immediate value of %ld is too large"),
2206                            (long) exp->X_add_number);
2207		  ret = -1;
2208		  continue;
2209		}
2210	    }
2211	  break;		/* No relocations allowed.  */
2212
2213	case 'W':		/* Short immediate int (0--7).  */
2214	  if (!IS_CPU_TIC4X (tic4x_cpu))
2215	    break;
2216	  if (operand->mode != M_IMMED)
2217	    break;
2218	  if (exp->X_op == O_big)
2219	    {
2220              if (!check)
2221                as_bad (_("Floating point number not valid in expression"));
2222	      ret = -1;
2223	      continue;
2224	    }
2225	  if (exp->X_op == O_constant)
2226	    {
2227	      if (exp->X_add_number >= -256 && exp->X_add_number <= 127)
2228		{
2229		  INSERTS (opcode, exp->X_add_number, 7, 0);
2230		  continue;
2231		}
2232	      else
2233		{
2234                  if (!check)
2235                    as_bad (_("Immediate value %ld too large"),
2236                            (long) exp->X_add_number);
2237		  ret = -1;
2238		  continue;
2239		}
2240	    }
2241	  tinsn->reloc = BFD_RELOC_16;
2242	  tinsn->exp = *exp;
2243	  continue;
2244
2245	case 'X':		/* Expansion register for tic4x.  */
2246	  if (operand->mode != M_REGISTER)
2247	    break;
2248	  reg = exp->X_add_number;
2249	  if (reg >= REG_IVTP && reg <= REG_TVTP)
2250	    INSERTU (opcode, reg - REG_IVTP, 4, 0);
2251	  else
2252	    {
2253              if (!check)
2254                as_bad (_("Register must be ivtp or tvtp"));
2255	      ret = -1;
2256	    }
2257	  continue;
2258
2259	case 'Y':		/* Address register for tic4x lda.  */
2260	  if (operand->mode != M_REGISTER)
2261	    break;
2262	  reg = exp->X_add_number;
2263	  if (reg >= REG_AR0 && reg <= REG_SP)
2264	    INSERTU (opcode, reg, 20, 16);
2265	  else
2266	    {
2267              if (!check)
2268                as_bad (_("Register must be address register"));
2269	      ret = -1;
2270	    }
2271	  continue;
2272
2273	case 'Z':		/* Expansion register for tic4x.  */
2274	  if (operand->mode != M_REGISTER)
2275	    break;
2276	  reg = exp->X_add_number;
2277	  if (reg >= REG_IVTP && reg <= REG_TVTP)
2278	    INSERTU (opcode, reg - REG_IVTP, 20, 16);
2279	  else
2280	    {
2281              if (!check)
2282                as_bad (_("Register must be ivtp or tvtp"));
2283	      ret = -1;
2284	    }
2285	  continue;
2286
2287	case '*':
2288	  if (operand->mode != M_INDIRECT)
2289	    break;
2290	  INSERTS (opcode, operand->disp, 7, 0);
2291	  INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2292	  INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2293	  continue;
2294
2295	case '|':		/* treat as `,' if have ldi_ldi form.  */
2296	  if (tinsn->parallel)
2297	    {
2298	      if (--num_operands < 0)
2299		break;		/* Too few operands.  */
2300	      operand++;
2301	      if (operand->mode != M_PARALLEL)
2302		break;
2303	    }
2304	  /* Fall through.  */
2305
2306	case ',':		/* Another operand.  */
2307	  if (--num_operands < 0)
2308	    break;		/* Too few operands.  */
2309	  operand++;
2310	  exp = &operand->expr;
2311	  continue;
2312
2313	case ';':		/* Another optional operand.  */
2314	  if (num_operands == 1 || operand[1].mode == M_PARALLEL)
2315	    continue;
2316	  if (--num_operands < 0)
2317	    break;		/* Too few operands.  */
2318	  operand++;
2319	  exp = &operand->expr;
2320	  continue;
2321
2322	default:
2323	  BAD_CASE (*args);
2324	}
2325      return 0;
2326    }
2327}
2328
2329static void
2330tic4x_insn_check (tic4x_insn_t *tinsn)
2331{
2332
2333  if (!strcmp (tinsn->name, "lda"))
2334    {
2335      if (tinsn->num_operands < 2 || tinsn->num_operands > 2)
2336        as_fatal ("Illegal internal LDA insn definition");
2337
2338      if (tinsn->operands[0].mode == M_REGISTER
2339	  && tinsn->operands[1].mode == M_REGISTER
2340	  && tinsn->operands[0].expr.X_add_number == tinsn->operands[1].expr.X_add_number )
2341        as_bad (_("Source and destination register should not be equal"));
2342    }
2343  else if (!strcmp (tinsn->name, "ldi_ldi")
2344           || !strcmp (tinsn->name, "ldi1_ldi2")
2345           || !strcmp (tinsn->name, "ldi2_ldi1")
2346           || !strcmp (tinsn->name, "ldf_ldf")
2347           || !strcmp (tinsn->name, "ldf1_ldf2")
2348           || !strcmp (tinsn->name, "ldf2_ldf1") )
2349    {
2350      if (tinsn->num_operands < 4 || tinsn->num_operands > 5)
2351        as_fatal ("Illegal internal %s insn definition", tinsn->name);
2352
2353      if (tinsn->operands[1].mode == M_REGISTER
2354	  && tinsn->operands[tinsn->num_operands-1].mode == M_REGISTER
2355	  && tinsn->operands[1].expr.X_add_number == tinsn->operands[tinsn->num_operands-1].expr.X_add_number )
2356        as_warn (_("Equal parallell destination registers, one result will be discarded"));
2357    }
2358}
2359
2360static void
2361tic4x_insn_output (tic4x_insn_t *tinsn)
2362{
2363  char *dst;
2364
2365  /* Grab another fragment for opcode.  */
2366  dst = frag_more (tinsn->nchars);
2367
2368  /* Put out opcode word as a series of bytes in little endian order.  */
2369  md_number_to_chars (dst, tinsn->opcode, tinsn->nchars);
2370
2371  /* Put out the symbol-dependent stuff.  */
2372  if (tinsn->reloc != NO_RELOC)
2373    {
2374      /* Where is the offset into the fragment for this instruction.  */
2375      fix_new_exp (frag_now,
2376		   dst - frag_now->fr_literal,	/* where */
2377		   tinsn->nchars,	/* size */
2378		   &tinsn->exp,
2379		   tinsn->pcrel,
2380		   tinsn->reloc);
2381    }
2382}
2383
2384/* Parse the operands.  */
2385static int
2386tic4x_operands_parse (char *s, tic4x_operand_t *operands, int num_operands)
2387{
2388  if (!*s)
2389    return num_operands;
2390
2391  do
2392    s = tic4x_operand_parse (s, &operands[num_operands++]);
2393  while (num_operands < TIC4X_OPERANDS_MAX && *s++ == ',');
2394
2395  if (num_operands > TIC4X_OPERANDS_MAX)
2396    {
2397      as_bad (_("Too many operands scanned"));
2398      return -1;
2399    }
2400  return num_operands;
2401}
2402
2403/* Assemble a single instruction.  Its label has already been handled
2404   by the generic front end.  We just parse mnemonic and operands, and
2405   produce the bytes of data and relocation.  */
2406void
2407md_assemble (char *str)
2408{
2409  int ok = 0;
2410  char *s;
2411  int i;
2412  int parsed = 0;
2413  size_t len;
2414  tic4x_inst_t *inst;		/* Instruction template.  */
2415  tic4x_inst_t *first_inst;
2416
2417  /* Scan for parallel operators */
2418  if (str)
2419    {
2420      s = str;
2421      while (*s && *s != '|')
2422        s++;
2423
2424      if (*s && s[1]=='|')
2425        {
2426          if(insn->parallel)
2427            {
2428              as_bad (_("Parallel opcode cannot contain more than two instructions"));
2429              insn->parallel = 0;
2430              insn->in_use = 0;
2431              return;
2432            }
2433
2434          /* Lets take care of the first part of the parallel insn */
2435          *s++ = 0;
2436          md_assemble(str);
2437          insn->parallel = 1;
2438          str = ++s;
2439          /* .. and let the second run though here */
2440        }
2441    }
2442
2443  if (str && insn->parallel)
2444    {
2445      /* Find mnemonic (second part of parallel instruction).  */
2446      s = str;
2447      /* Skip past instruction mnemonic.  */
2448      while (*s && *s != ' ')
2449	s++;
2450      if (*s)			/* Null terminate for hash_find.  */
2451	*s++ = '\0';		/* and skip past null.  */
2452      len = strlen (insn->name);
2453      snprintf (insn->name + len, TIC4X_NAME_MAX - len, "_%s", str);
2454
2455      insn->operands[insn->num_operands++].mode = M_PARALLEL;
2456
2457      if ((i = tic4x_operands_parse
2458	   (s, insn->operands, insn->num_operands)) < 0)
2459	{
2460	  insn->parallel = 0;
2461	  insn->in_use = 0;
2462	  return;
2463	}
2464      insn->num_operands = i;
2465      parsed = 1;
2466    }
2467
2468  if (insn->in_use)
2469    {
2470      if ((insn->inst = (struct tic4x_inst *)
2471	   hash_find (tic4x_op_hash, insn->name)) == NULL)
2472	{
2473	  as_bad (_("Unknown opcode `%s'."), insn->name);
2474	  insn->parallel = 0;
2475	  insn->in_use = 0;
2476	  return;
2477	}
2478
2479      inst = insn->inst;
2480      first_inst = NULL;
2481      do
2482        {
2483          ok = tic4x_operands_match (inst, insn, 1);
2484          if (ok < 0)
2485            {
2486              if (!first_inst)
2487                first_inst = inst;
2488              ok = 0;
2489            }
2490      } while (!ok && !strcmp (inst->name, inst[1].name) && inst++);
2491
2492      if (ok > 0)
2493        {
2494          tic4x_insn_check (insn);
2495          tic4x_insn_output (insn);
2496        }
2497      else if (!ok)
2498        {
2499          if (first_inst)
2500            tic4x_operands_match (first_inst, insn, 0);
2501          as_bad (_("Invalid operands for %s"), insn->name);
2502        }
2503      else
2504	as_bad (_("Invalid instruction %s"), insn->name);
2505    }
2506
2507  if (str && !parsed)
2508    {
2509      /* Find mnemonic.  */
2510      s = str;
2511      while (*s && *s != ' ')	/* Skip past instruction mnemonic.  */
2512	s++;
2513      if (*s)			/* Null terminate for hash_find.  */
2514	*s++ = '\0';		/* and skip past null.  */
2515      strncpy (insn->name, str, TIC4X_NAME_MAX - 1);
2516      insn->name[TIC4X_NAME_MAX - 1] = '\0';
2517
2518      if ((i = tic4x_operands_parse (s, insn->operands, 0)) < 0)
2519	{
2520	  insn->inst = NULL;	/* Flag that error occurred.  */
2521	  insn->parallel = 0;
2522	  insn->in_use = 0;
2523	  return;
2524	}
2525      insn->num_operands = i;
2526      insn->in_use = 1;
2527    }
2528  else
2529    insn->in_use = 0;
2530  insn->parallel = 0;
2531}
2532
2533void
2534tic4x_cleanup (void)
2535{
2536  if (insn->in_use)
2537    md_assemble (NULL);
2538}
2539
2540/* Turn a string in input_line_pointer into a floating point constant
2541   of type type, and store the appropriate bytes in *litP.  The number
2542   of chars emitted is stored in *sizeP.  An error message is
2543   returned, or NULL on OK.  */
2544
2545const char *
2546md_atof (int type, char *litP, int *sizeP)
2547{
2548  int prec;
2549  int ieee;
2550  LITTLENUM_TYPE words[MAX_LITTLENUMS];
2551  LITTLENUM_TYPE *wordP;
2552  char *t;
2553
2554  switch (type)
2555    {
2556    case 's':		/* .single  */
2557    case 'S':
2558      ieee = 0;
2559      prec = 1;
2560      break;
2561
2562    case 'd':		/* .double  */
2563    case 'D':
2564    case 'f':		/* .float  */
2565    case 'F':
2566      ieee = 0;
2567      prec = 2;		/* 1 32-bit word */
2568      break;
2569
2570    case 'i':		/* .ieee */
2571    case 'I':
2572      prec = 2;
2573      ieee = 1;
2574      type = 'f';  /* Rewrite type to be usable by atof_ieee().  */
2575      break;
2576
2577    case 'e':		/* .ldouble */
2578    case 'E':
2579      prec = 4;		/* 2 32-bit words */
2580      ieee = 0;
2581      break;
2582
2583    default:
2584      *sizeP = 0;
2585      return _("Unrecognized or unsupported floating point constant");
2586    }
2587
2588  if (ieee)
2589    t = atof_ieee (input_line_pointer, type, words);
2590  else
2591    t = tic4x_atof (input_line_pointer, type, words);
2592  if (t)
2593    input_line_pointer = t;
2594  *sizeP = prec * sizeof (LITTLENUM_TYPE);
2595
2596  /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2597     little endian byte order.  */
2598  /* SES: However it is required to put the words (32-bits) out in the
2599     correct order, hence we write 2 and 2 littlenums in little endian
2600     order, while we keep the original order on successive words.  */
2601  for (wordP = words; wordP<(words+prec) ; wordP+=2)
2602    {
2603      if (wordP < (words + prec - 1)) /* Dump wordP[1] (if we have one).  */
2604        {
2605          md_number_to_chars (litP, (valueT) (wordP[1]),
2606                              sizeof (LITTLENUM_TYPE));
2607          litP += sizeof (LITTLENUM_TYPE);
2608        }
2609
2610      /* Dump wordP[0] */
2611      md_number_to_chars (litP, (valueT) (wordP[0]),
2612                          sizeof (LITTLENUM_TYPE));
2613      litP += sizeof (LITTLENUM_TYPE);
2614    }
2615  return NULL;
2616}
2617
2618void
2619md_apply_fix (fixS *fixP, valueT *value, segT seg ATTRIBUTE_UNUSED)
2620{
2621  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2622  valueT val = *value;
2623
2624  switch (fixP->fx_r_type)
2625    {
2626    case BFD_RELOC_HI16:
2627      val >>= 16;
2628      break;
2629
2630    case BFD_RELOC_LO16:
2631      val &= 0xffff;
2632      break;
2633    default:
2634      break;
2635    }
2636
2637  switch (fixP->fx_r_type)
2638    {
2639    case BFD_RELOC_32:
2640      buf[3] = val >> 24;
2641      /* Fall through.  */
2642    case BFD_RELOC_24:
2643    case BFD_RELOC_24_PCREL:
2644      buf[2] = val >> 16;
2645      /* Fall through.  */
2646    case BFD_RELOC_16:
2647    case BFD_RELOC_16_PCREL:
2648    case BFD_RELOC_LO16:
2649    case BFD_RELOC_HI16:
2650      buf[1] = val >> 8;
2651      buf[0] = val;
2652      break;
2653
2654    case NO_RELOC:
2655    default:
2656      as_bad (_("Bad relocation type: 0x%02x"), fixP->fx_r_type);
2657      break;
2658    }
2659
2660  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1;
2661}
2662
2663/* Should never be called for tic4x.  */
2664void
2665md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
2666		 segT sec ATTRIBUTE_UNUSED,
2667		 fragS *fragP ATTRIBUTE_UNUSED)
2668{
2669  as_fatal ("md_convert_frag");
2670}
2671
2672/* Should never be called for tic4x.  */
2673void
2674md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
2675		      addressT from_addr ATTRIBUTE_UNUSED,
2676		      addressT to_addr ATTRIBUTE_UNUSED,
2677		      fragS *frag ATTRIBUTE_UNUSED,
2678		      symbolS *to_symbol ATTRIBUTE_UNUSED)
2679{
2680  as_fatal ("md_create_short_jmp\n");
2681}
2682
2683/* Should never be called for tic4x.  */
2684void
2685md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
2686		     addressT from_addr ATTRIBUTE_UNUSED,
2687		     addressT to_addr ATTRIBUTE_UNUSED,
2688		     fragS *frag ATTRIBUTE_UNUSED,
2689		     symbolS *to_symbol ATTRIBUTE_UNUSED)
2690{
2691  as_fatal ("md_create_long_jump\n");
2692}
2693
2694/* Should never be called for tic4x.  */
2695int
2696md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
2697			       segT segtype ATTRIBUTE_UNUSED)
2698{
2699  as_fatal ("md_estimate_size_before_relax\n");
2700  return 0;
2701}
2702
2703
2704int
2705md_parse_option (int c, const char *arg)
2706{
2707  switch (c)
2708    {
2709    case OPTION_CPU:             /* cpu brand */
2710      if (TOLOWER (*arg) == 'c')
2711	arg++;
2712      tic4x_cpu = atoi (arg);
2713      if (!IS_CPU_TIC3X (tic4x_cpu) && !IS_CPU_TIC4X (tic4x_cpu))
2714	as_warn (_("Unsupported processor generation %d"), tic4x_cpu);
2715      break;
2716
2717    case OPTION_REV:             /* cpu revision */
2718      tic4x_revision = atoi (arg);
2719      break;
2720
2721    case 'b':
2722      as_warn (_("Option -b is depreciated, please use -mbig"));
2723      /* Fall through.  */
2724    case OPTION_BIG:             /* big model */
2725      tic4x_big_model = 1;
2726      break;
2727
2728    case 'p':
2729      as_warn (_("Option -p is depreciated, please use -mmemparm"));
2730      /* Fall through.  */
2731    case OPTION_MEMPARM:         /* push args */
2732      tic4x_reg_args = 0;
2733      break;
2734
2735    case 'r':
2736      as_warn (_("Option -r is depreciated, please use -mregparm"));
2737      /* Fall through.  */
2738    case OPTION_REGPARM:        /* register args */
2739      tic4x_reg_args = 1;
2740      break;
2741
2742    case 's':
2743      as_warn (_("Option -s is depreciated, please use -msmall"));
2744      /* Fall through.  */
2745    case OPTION_SMALL:		/* small model */
2746      tic4x_big_model = 0;
2747      break;
2748
2749    case OPTION_IDLE2:
2750      tic4x_idle2 = 1;
2751      break;
2752
2753    case OPTION_LOWPOWER:
2754      tic4x_lowpower = 1;
2755      break;
2756
2757    case OPTION_ENHANCED:
2758      tic4x_enhanced = 1;
2759      break;
2760
2761    default:
2762      return 0;
2763    }
2764
2765  return 1;
2766}
2767
2768void
2769md_show_usage (FILE *stream)
2770{
2771  fprintf (stream,
2772      _("\nTIC4X options:\n"
2773	"  -mcpu=CPU  -mCPU        select architecture variant. CPU can be:\n"
2774	"                            30 - TMS320C30\n"
2775	"                            31 - TMS320C31, TMS320LC31\n"
2776	"                            32 - TMS320C32\n"
2777        "                            33 - TMS320VC33\n"
2778	"                            40 - TMS320C40\n"
2779	"                            44 - TMS320C44\n"
2780        "  -mrev=REV               set cpu hardware revision (integer numbers).\n"
2781        "                          Combinations of -mcpu and -mrev will enable/disable\n"
2782        "                          the appropriate options (-midle2, -mlowpower and\n"
2783        "                          -menhanced) according to the selected type\n"
2784        "  -mbig                   select big memory model\n"
2785        "  -msmall                 select small memory model (default)\n"
2786        "  -mregparm               select register parameters (default)\n"
2787        "  -mmemparm               select memory parameters\n"
2788        "  -midle2                 enable IDLE2 support\n"
2789        "  -mlowpower              enable LOPOWER and MAXSPEED support\n"
2790        "  -menhanced              enable enhanced opcode support\n"));
2791}
2792
2793/* This is called when a line is unrecognized.  This is used to handle
2794   definitions of TI C3x tools style local labels $n where n is a single
2795   decimal digit.  */
2796int
2797tic4x_unrecognized_line (int c)
2798{
2799  int lab;
2800  char *s;
2801
2802  if (c != '$' || ! ISDIGIT (input_line_pointer[0]))
2803    return 0;
2804
2805  s = input_line_pointer;
2806
2807  /* Let's allow multiple digit local labels.  */
2808  lab = 0;
2809  while (ISDIGIT (*s))
2810    {
2811      lab = lab * 10 + *s - '0';
2812      s++;
2813    }
2814
2815  if (dollar_label_defined (lab))
2816    {
2817      as_bad (_("Label \"$%d\" redefined"), lab);
2818      return 0;
2819    }
2820
2821  define_dollar_label (lab);
2822  colon (dollar_label_name (lab, 0));
2823  input_line_pointer = s + 1;
2824
2825  return 1;
2826}
2827
2828/* Handle local labels peculiar to us referred to in an expression.  */
2829symbolS *
2830md_undefined_symbol (char *name)
2831{
2832  /* Look for local labels of the form $n.  */
2833  if (name[0] == '$' && ISDIGIT (name[1]))
2834    {
2835      symbolS *symbolP;
2836      char *s = name + 1;
2837      int lab = 0;
2838
2839      while (ISDIGIT ((unsigned char) *s))
2840	{
2841	  lab = lab * 10 + *s - '0';
2842	  s++;
2843	}
2844      if (dollar_label_defined (lab))
2845	{
2846	  name = dollar_label_name (lab, 0);
2847	  symbolP = symbol_find (name);
2848	}
2849      else
2850	{
2851	  name = dollar_label_name (lab, 1);
2852	  symbolP = symbol_find_or_make (name);
2853	}
2854
2855      return symbolP;
2856    }
2857  return NULL;
2858}
2859
2860/* Parse an operand that is machine-specific.  */
2861void
2862md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
2863{
2864}
2865
2866/* Round up a section size to the appropriate boundary---do we need this?  */
2867valueT
2868md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2869{
2870  return size;			/* Byte (i.e., 32-bit) alignment is fine?  */
2871}
2872
2873static int
2874tic4x_pc_offset (unsigned int op)
2875{
2876  /* Determine the PC offset for a C[34]x instruction.
2877     This could be simplified using some boolean algebra
2878     but at the expense of readability.  */
2879  switch (op >> 24)
2880    {
2881    case 0x60:			/* br */
2882    case 0x62:			/* call  (C4x) */
2883    case 0x64:			/* rptb  (C4x) */
2884      return 1;
2885    case 0x61:			/* brd */
2886    case 0x63:			/* laj */
2887    case 0x65:			/* rptbd (C4x) */
2888      return 3;
2889    case 0x66:			/* swi */
2890    case 0x67:
2891      return 0;
2892    default:
2893      break;
2894    }
2895
2896  switch ((op & 0xffe00000) >> 20)
2897    {
2898    case 0x6a0:		/* bB */
2899    case 0x720:		/* callB */
2900    case 0x740:		/* trapB */
2901      return 1;
2902
2903    case 0x6a2:		/* bBd */
2904    case 0x6a6:		/* bBat */
2905    case 0x6aa:		/* bBaf */
2906    case 0x722:		/* lajB */
2907    case 0x748:		/* latB */
2908    case 0x798:		/* rptbd */
2909      return 3;
2910
2911    default:
2912      break;
2913    }
2914
2915  switch ((op & 0xfe200000) >> 20)
2916    {
2917    case 0x6e0:		/* dbB */
2918      return 1;
2919
2920    case 0x6e2:		/* dbBd */
2921      return 3;
2922
2923    default:
2924      break;
2925    }
2926
2927  return 0;
2928}
2929
2930/* Exactly what point is a PC-relative offset relative TO?
2931   With the C3x we have the following:
2932   DBcond,  Bcond   disp + PC + 1 => PC
2933   DBcondD, BcondD  disp + PC + 3 => PC
2934 */
2935long
2936md_pcrel_from (fixS *fixP)
2937{
2938  unsigned char *buf;
2939  unsigned int op;
2940
2941  buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
2942  op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2943
2944  return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
2945    tic4x_pc_offset (op);
2946}
2947
2948/* Fill the alignment area with NOP's on .text, unless fill-data
2949   was specified. */
2950int
2951tic4x_do_align (int alignment,
2952		const char *fill,
2953		int len,
2954		int max)
2955{
2956  /* Because we are talking lwords, not bytes, adjust alignment to do words */
2957  alignment += 2;
2958
2959  if (alignment != 0 && !need_pass_2)
2960    {
2961      if (fill == NULL)
2962        {
2963          if (subseg_text_p (now_seg))
2964	    {
2965	      char nop[4];
2966
2967	      md_number_to_chars (nop, TIC_NOP_OPCODE, 4);
2968	      frag_align_pattern (alignment, nop, sizeof (nop), max);
2969	    }
2970          else
2971            frag_align (alignment, 0, max);
2972	}
2973      else if (len <= 1)
2974	frag_align (alignment, *fill, max);
2975      else
2976	frag_align_pattern (alignment, fill, len, max);
2977    }
2978
2979  /* Return 1 to skip the default alignment function */
2980  return 1;
2981}
2982
2983/* Look for and remove parallel instruction operator ||.  */
2984void
2985tic4x_start_line (void)
2986{
2987  char *s = input_line_pointer;
2988
2989  SKIP_WHITESPACE ();
2990
2991  /* If parallel instruction prefix found at start of line, skip it.  */
2992  if (*input_line_pointer == '|' && input_line_pointer[1] == '|')
2993    {
2994      if (insn->in_use)
2995	{
2996	  insn->parallel = 1;
2997	  input_line_pointer ++;
2998          *input_line_pointer = ' ';
2999	  /* So line counters get bumped.  */
3000	  input_line_pointer[-1] = '\n';
3001	}
3002    }
3003  else
3004    {
3005      /* Write out the previous insn here */
3006      if (insn->in_use)
3007	md_assemble (NULL);
3008      input_line_pointer = s;
3009    }
3010}
3011
3012arelent *
3013tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixP)
3014{
3015  arelent *reloc;
3016
3017  reloc = XNEW (arelent);
3018
3019  reloc->sym_ptr_ptr = XNEW (asymbol *);
3020  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3021  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3022  reloc->address /= OCTETS_PER_BYTE;
3023  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
3024  if (reloc->howto == (reloc_howto_type *) NULL)
3025    {
3026      as_bad_where (fixP->fx_file, fixP->fx_line,
3027		    _("Reloc %d not supported by object file format"),
3028		    (int) fixP->fx_r_type);
3029      return NULL;
3030    }
3031
3032  if (fixP->fx_r_type == BFD_RELOC_HI16)
3033    reloc->addend = fixP->fx_offset;
3034  else
3035    reloc->addend = fixP->fx_addnumber;
3036
3037  return reloc;
3038}
3039