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