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