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