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