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