* coffgen.c (coff_write_symbols): Check to see if a symbol's flags
[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
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   demand_empty_rest_of_line ();
953   tic4x_insert_sym (name, value);
954 }
955
956 /* Reset local labels.  */
957 static void 
958 tic4x_newblock (int x ATTRIBUTE_UNUSED)
959 {
960   dollar_label_clear ();
961 }
962
963 /* .sect "section-name" [, value] */
964 /* .sect ["]section-name[:subsection-name]["] [, value] */
965 static void 
966 tic4x_sect (int x ATTRIBUTE_UNUSED)
967 {
968   char c;
969   char *section_name;
970   char *subsection_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       subsection_name = input_line_pointer;
992       c = get_symbol_end ();    /* Get terminator.  */
993       input_line_pointer++;     /* Skip null symbol terminator.  */
994       as_warn (".sect: subsection name ignored");
995     }
996
997   /* We might still have a '"' to discard, but the character after a
998      symbol name will be overwritten with a \0 by get_symbol_end()
999      [VK].  */
1000
1001   if (c == ',')
1002     input_line_pointer =
1003       tic4x_expression_abs (input_line_pointer, &num);
1004   else if (*input_line_pointer == ',')
1005     {
1006       input_line_pointer =
1007         tic4x_expression_abs (++input_line_pointer, &num);
1008     }
1009   else
1010     num = 0;
1011
1012   seg = subseg_new (name, num);
1013   if (line_label != NULL)
1014     {
1015       S_SET_SEGMENT (line_label, seg);
1016       symbol_set_frag (line_label, frag_now);
1017     }
1018
1019   if (bfd_get_section_flags (stdoutput, seg) == SEC_NO_FLAGS)
1020     {
1021       if (!bfd_set_section_flags (stdoutput, seg, SEC_DATA))
1022         as_warn ("Error setting flags for \"%s\": %s", name,
1023                  bfd_errmsg (bfd_get_error ()));
1024     }
1025
1026   /* If the last character overwritten by get_symbol_end() was an
1027      end-of-line, we must restore it or the end of the line will not be
1028      recognised and scanning extends into the next line, stopping with
1029      an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1030      if this is not true).  */
1031   if (is_end_of_line[(unsigned char) c])
1032     *(--input_line_pointer) = c;
1033
1034   demand_empty_rest_of_line ();
1035 }
1036
1037 /* symbol[:] .set value  or  .set symbol, value */
1038 static void 
1039 tic4x_set (int x ATTRIBUTE_UNUSED)
1040 {
1041   symbolS *symbolP;
1042
1043   SKIP_WHITESPACE ();
1044   if ((symbolP = line_label) == NULL)
1045     {
1046       char c;
1047       char *name;
1048
1049       name = input_line_pointer;
1050       c = get_symbol_end ();    /* Get terminator.  */
1051       if (c != ',')
1052         {
1053           as_bad (".set syntax invalid\n");
1054           ignore_rest_of_line ();
1055           return;
1056         }
1057       ++input_line_pointer;
1058       symbolP = symbol_find_or_make (name);
1059     }
1060   else
1061     symbol_table_insert (symbolP);
1062
1063   pseudo_set (symbolP);
1064   demand_empty_rest_of_line ();
1065 }
1066
1067 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1068 static void 
1069 tic4x_usect (int x ATTRIBUTE_UNUSED)
1070 {
1071   char c;
1072   char *name;
1073   char *section_name;
1074   segT seg;
1075   offsetT size, alignment_flag;
1076   segT current_seg;
1077   subsegT current_subseg;
1078
1079   current_seg = now_seg;        /* save current seg.  */
1080   current_subseg = now_subseg;  /* save current subseg.  */
1081
1082   SKIP_WHITESPACE ();
1083   if (*input_line_pointer == '"')
1084     input_line_pointer++;
1085   section_name = input_line_pointer;
1086   c = get_symbol_end ();        /* Get terminator.  */
1087   input_line_pointer++;         /* Skip null symbol terminator.  */
1088   name = xmalloc (input_line_pointer - section_name + 1);
1089   strcpy (name, section_name);
1090
1091   if (c == ',')
1092     input_line_pointer =
1093       tic4x_expression_abs (input_line_pointer, &size);
1094   else if (*input_line_pointer == ',')
1095     {
1096       input_line_pointer =
1097         tic4x_expression_abs (++input_line_pointer, &size);
1098     }
1099   else
1100     size = 0;
1101
1102   /* Read a possibly present third argument (alignment flag) [VK].  */
1103   if (*input_line_pointer == ',')
1104     {
1105       input_line_pointer =
1106         tic4x_expression_abs (++input_line_pointer, &alignment_flag);
1107     }
1108   else
1109     alignment_flag = 0;
1110   if (alignment_flag)
1111     as_warn (".usect: non-zero alignment flag ignored");
1112
1113   seg = subseg_new (name, 0);
1114   if (line_label != NULL)
1115     {
1116       S_SET_SEGMENT (line_label, seg);
1117       symbol_set_frag (line_label, frag_now);
1118       S_SET_VALUE (line_label, frag_now_fix ());
1119     }
1120   seg_info (seg)->bss = 1;      /* Uninitialised data.  */
1121   if (!bfd_set_section_flags (stdoutput, seg, SEC_ALLOC))
1122     as_warn ("Error setting flags for \"%s\": %s", name,
1123              bfd_errmsg (bfd_get_error ()));
1124   tic4x_seg_alloc (name, seg, size, line_label);
1125
1126   if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1127     S_SET_STORAGE_CLASS (line_label, C_STAT);
1128
1129   subseg_set (current_seg, current_subseg);     /* Restore current seg.  */
1130   demand_empty_rest_of_line ();
1131 }
1132
1133 /* .version cpu-version.  */
1134 static void 
1135 tic4x_version (int x ATTRIBUTE_UNUSED)
1136 {
1137   offsetT temp;
1138
1139   input_line_pointer =
1140     tic4x_expression_abs (input_line_pointer, &temp);
1141   if (!IS_CPU_TIC3X (temp) && !IS_CPU_TIC4X (temp))
1142     as_bad ("This assembler does not support processor generation %ld",
1143             (long) temp);
1144
1145   if (tic4x_cpu && temp != (offsetT) tic4x_cpu)
1146     as_warn ("Changing processor generation on fly not supported...");
1147   tic4x_cpu = temp;
1148   demand_empty_rest_of_line ();
1149 }
1150
1151 static void 
1152 tic4x_init_regtable (void)
1153 {
1154   unsigned int i;
1155
1156   for (i = 0; i < tic3x_num_registers; i++)
1157     tic4x_insert_reg (tic3x_registers[i].name,
1158                     tic3x_registers[i].regno);
1159
1160   if (IS_CPU_TIC4X (tic4x_cpu))
1161     {
1162       /* Add additional Tic4x registers, overriding some C3x ones.  */
1163       for (i = 0; i < tic4x_num_registers; i++)
1164         tic4x_insert_reg (tic4x_registers[i].name,
1165                         tic4x_registers[i].regno);
1166     }
1167 }
1168
1169 static void 
1170 tic4x_init_symbols (void)
1171 {
1172   /* The TI tools accept case insensitive versions of these symbols,
1173      we don't !
1174
1175      For TI C/Asm 5.0
1176
1177      .TMS320xx       30,31,32,40,or 44       set according to -v flag
1178      .C3X or .C3x    1 or 0                  1 if -v30,-v31,or -v32
1179      .C30            1 or 0                  1 if -v30
1180      .C31            1 or 0                  1 if -v31
1181      .C32            1 or 0                  1 if -v32
1182      .C4X or .C4x    1 or 0                  1 if -v40, or -v44
1183      .C40            1 or 0                  1 if -v40
1184      .C44            1 or 0                  1 if -v44
1185
1186      .REGPARM 1 or 0                  1 if -mr option used
1187      .BIGMODEL        1 or 0                  1 if -mb option used
1188
1189      These symbols are currently supported but will be removed in a
1190      later version:
1191      .TMS320C30      1 or 0                  1 if -v30,-v31,or -v32
1192      .TMS320C31      1 or 0                  1 if -v31
1193      .TMS320C32      1 or 0                  1 if -v32
1194      .TMS320C40      1 or 0                  1 if -v40, or -v44
1195      .TMS320C44      1 or 0                  1 if -v44
1196
1197      Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1198      1997, SPRU035C, p. 3-17/3-18.  */
1199   tic4x_insert_sym (".REGPARM", tic4x_reg_args);
1200   tic4x_insert_sym (".MEMPARM", !tic4x_reg_args);       
1201   tic4x_insert_sym (".BIGMODEL", tic4x_big_model);
1202   tic4x_insert_sym (".C30INTERRUPT", 0);
1203   tic4x_insert_sym (".TMS320xx", tic4x_cpu == 0 ? 40 : tic4x_cpu);
1204   tic4x_insert_sym (".C3X", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1205   tic4x_insert_sym (".C3x", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1206   tic4x_insert_sym (".C4X", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1207   tic4x_insert_sym (".C4x", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1208   /* Do we need to have the following symbols also in lower case?  */
1209   tic4x_insert_sym (".TMS320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1210   tic4x_insert_sym (".tms320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1211   tic4x_insert_sym (".TMS320C31", tic4x_cpu == 31);
1212   tic4x_insert_sym (".tms320C31", tic4x_cpu == 31);
1213   tic4x_insert_sym (".TMS320C32", tic4x_cpu == 32);
1214   tic4x_insert_sym (".tms320C32", tic4x_cpu == 32);
1215   tic4x_insert_sym (".TMS320C33", tic4x_cpu == 33);
1216   tic4x_insert_sym (".tms320C33", tic4x_cpu == 33);
1217   tic4x_insert_sym (".TMS320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1218   tic4x_insert_sym (".tms320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1219   tic4x_insert_sym (".TMS320C44", tic4x_cpu == 44);
1220   tic4x_insert_sym (".tms320C44", tic4x_cpu == 44);
1221   tic4x_insert_sym (".TMX320C40", 0);   /* C40 first pass silicon ?  */
1222   tic4x_insert_sym (".tmx320C40", 0);
1223 }
1224
1225 /* Insert a new instruction template into hash table.  */
1226 static int 
1227 tic4x_inst_insert (const tic4x_inst_t *inst)
1228 {
1229   static char prev_name[16];
1230   const char *retval = NULL;
1231
1232   /* Only insert the first name if have several similar entries.  */
1233   if (!strcmp (inst->name, prev_name) || inst->name[0] == '\0')
1234     return 1;
1235
1236   retval = hash_insert (tic4x_op_hash, inst->name, (void *) inst);
1237   if (retval != NULL)
1238     fprintf (stderr, "internal error: can't hash `%s': %s\n",
1239              inst->name, retval);
1240   else
1241     strcpy (prev_name, inst->name);
1242   return retval == NULL;
1243 }
1244
1245 /* Make a new instruction template.  */
1246 static tic4x_inst_t *
1247 tic4x_inst_make (char *name, unsigned long opcode, char *args)
1248 {
1249   static tic4x_inst_t *insts = NULL;
1250   static char *names = NULL;
1251   static int index = 0;
1252
1253   if (insts == NULL)
1254     {
1255       /* Allocate memory to store name strings.  */
1256       names = (char *) xmalloc (sizeof (char) * 8192);
1257       /* Allocate memory for additional insts.  */
1258       insts = (tic4x_inst_t *)
1259         xmalloc (sizeof (tic4x_inst_t) * 1024);
1260     }
1261   insts[index].name = names;
1262   insts[index].opcode = opcode;
1263   insts[index].opmask = 0xffffffff;
1264   insts[index].args = args;
1265   index++;
1266
1267   do
1268     *names++ = *name++;
1269   while (*name);
1270   *names++ = '\0';
1271
1272   return &insts[index - 1];
1273 }
1274
1275 /* Add instruction template, creating dynamic templates as required.  */
1276 static int 
1277 tic4x_inst_add (const tic4x_inst_t *insts)
1278 {
1279   char *s = insts->name;
1280   char *d;
1281   unsigned int i;
1282   int ok = 1;
1283   char name[16];
1284
1285   d = name;
1286
1287   /* We do not care about INSNs that is not a part of our
1288      oplevel setting */
1289   if (!insts->oplevel & tic4x_oplevel)
1290     return ok;
1291
1292   while (1)
1293     {
1294       switch (*s)
1295         {
1296         case 'B':
1297         case 'C':
1298           /* Dynamically create all the conditional insts.  */
1299           for (i = 0; i < tic4x_num_conds; i++)
1300             {
1301               tic4x_inst_t *inst;
1302               int k = 0;
1303               char *c = tic4x_conds[i].name;
1304               char *e = d;
1305
1306               while (*c)
1307                 *e++ = *c++;
1308               c = s + 1;
1309               while (*c)
1310                 *e++ = *c++;
1311               *e = '\0';
1312
1313               /* If instruction found then have already processed it.  */
1314               if (hash_find (tic4x_op_hash, name))
1315                 return 1;
1316
1317               do
1318                 {
1319                   inst = tic4x_inst_make (name, insts[k].opcode +
1320                                         (tic4x_conds[i].cond <<
1321                                          (*s == 'B' ? 16 : 23)),
1322                                         insts[k].args);
1323                   if (k == 0)   /* Save strcmp() with following func.  */
1324                     ok &= tic4x_inst_insert (inst);
1325                   k++;
1326                 }
1327               while (!strcmp (insts->name,
1328                               insts[k].name));
1329             }
1330           return ok;
1331           break;
1332
1333         case '\0':
1334           return tic4x_inst_insert (insts);
1335           break;
1336
1337         default:
1338           *d++ = *s++;
1339           break;
1340         }
1341     }
1342 }
1343
1344 /* This function is called once, at assembler startup time.  It should
1345    set up all the tables, etc., that the MD part of the assembler will
1346    need.  */
1347 void 
1348 md_begin (void)
1349 {
1350   int ok = 1;
1351   unsigned int i;
1352
1353   /* Setup the proper opcode level according to the
1354      commandline parameters */
1355   tic4x_oplevel = OP_C3X;
1356
1357   if ( IS_CPU_TIC4X(tic4x_cpu) )
1358     tic4x_oplevel |= OP_C4X;
1359
1360   if ( (   tic4x_cpu == 31 && tic4x_revision >= 6)
1361        || (tic4x_cpu == 32 && tic4x_revision >= 2)
1362        || (tic4x_cpu == 33)
1363        || tic4x_enhanced )
1364     tic4x_oplevel |= OP_ENH;
1365
1366   if ( (   tic4x_cpu == 30 && tic4x_revision >= 7)
1367        || (tic4x_cpu == 31 && tic4x_revision >= 5)
1368        || (tic4x_cpu == 32)
1369        || tic4x_lowpower )
1370     tic4x_oplevel |= OP_LPWR;
1371
1372   if ( (   tic4x_cpu == 30 && tic4x_revision >= 7)
1373        || (tic4x_cpu == 31 && tic4x_revision >= 5)
1374        || (tic4x_cpu == 32)
1375        || (tic4x_cpu == 33)
1376        || (tic4x_cpu == 40 && tic4x_revision >= 5)
1377        || (tic4x_cpu == 44)
1378        || tic4x_idle2 )
1379     tic4x_oplevel |= OP_IDLE2;
1380
1381   /* Create hash table for mnemonics.  */
1382   tic4x_op_hash = hash_new ();
1383
1384   /* Create hash table for asg pseudo.  */
1385   tic4x_asg_hash = hash_new ();
1386
1387   /* Add mnemonics to hash table, expanding conditional mnemonics on fly.  */
1388   for (i = 0; i < tic4x_num_insts; i++)
1389     ok &= tic4x_inst_add (tic4x_insts + i);
1390
1391   /* Create dummy inst to avoid errors accessing end of table.  */
1392   tic4x_inst_make ("", 0, "");
1393
1394   if (!ok)
1395     as_fatal ("Broken assembler.  No assembly attempted.");
1396
1397   /* Add registers to symbol table.  */
1398   tic4x_init_regtable ();
1399
1400   /* Add predefined symbols to symbol table.  */
1401   tic4x_init_symbols ();
1402 }
1403
1404 void 
1405 tic4x_end (void)
1406 {
1407   bfd_set_arch_mach (stdoutput, bfd_arch_tic4x, 
1408                      IS_CPU_TIC4X (tic4x_cpu) ? bfd_mach_tic4x : bfd_mach_tic3x);
1409 }
1410
1411 static int 
1412 tic4x_indirect_parse (tic4x_operand_t *operand,
1413                       const tic4x_indirect_t *indirect)
1414 {
1415   char *n = indirect->name;
1416   char *s = input_line_pointer;
1417   char *b;
1418   symbolS *symbolP;
1419   char name[32];
1420
1421   operand->disp = 0;
1422   for (; *n; n++)
1423     {
1424       switch (*n)
1425         {
1426         case 'a':               /* Need to match aux register.  */
1427           b = name;
1428 #ifdef TIC4X_ALT_SYNTAX
1429           if (*s == '%')
1430             s++;
1431 #endif
1432           while (ISALNUM (*s))
1433             *b++ = *s++;
1434           *b++ = '\0';
1435           if (!(symbolP = symbol_find (name)))
1436             return 0;
1437
1438           if (S_GET_SEGMENT (symbolP) != reg_section)
1439             return 0;
1440
1441           operand->aregno = S_GET_VALUE (symbolP);
1442           if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7)
1443             break;
1444
1445           as_bad ("Auxiliary register AR0--AR7 required for indirect");
1446           return -1;
1447
1448         case 'd':               /* Need to match constant for disp.  */
1449 #ifdef TIC4X_ALT_SYNTAX
1450           if (*s == '%')        /* expr() will die if we don't skip this.  */
1451             s++;
1452 #endif
1453           s = tic4x_expression (s, &operand->expr);
1454           if (operand->expr.X_op != O_constant)
1455             return 0;
1456           operand->disp = operand->expr.X_add_number;
1457           if (operand->disp < 0 || operand->disp > 255)
1458             {
1459               as_bad ("Bad displacement %d (require 0--255)\n",
1460                       operand->disp);
1461               return -1;
1462             }
1463           break;
1464
1465         case 'y':               /* Need to match IR0.  */
1466         case 'z':               /* Need to match IR1.  */
1467 #ifdef TIC4X_ALT_SYNTAX
1468           if (*s == '%')
1469             s++;
1470 #endif
1471           s = tic4x_expression (s, &operand->expr);
1472           if (operand->expr.X_op != O_register)
1473             return 0;
1474           if (operand->expr.X_add_number != REG_IR0
1475               && operand->expr.X_add_number != REG_IR1)
1476             {
1477               as_bad ("Index register IR0,IR1 required for displacement");
1478               return -1;
1479             }
1480
1481           if (*n == 'y' && operand->expr.X_add_number == REG_IR0)
1482             break;
1483           if (*n == 'z' && operand->expr.X_add_number == REG_IR1)
1484             break;
1485           return 0;
1486
1487         case '(':
1488           if (*s != '(')        /* No displacement, assume to be 1.  */
1489             {
1490               operand->disp = 1;
1491               while (*n != ')')
1492                 n++;
1493             }
1494           else
1495             s++;
1496           break;
1497
1498         default:
1499           if (TOLOWER (*s) != *n)
1500             return 0;
1501           s++;
1502         }
1503     }
1504   if (*s != ' ' && *s != ',' && *s != '\0')
1505     return 0;
1506   input_line_pointer = s;
1507   return 1;
1508 }
1509
1510 static char *
1511 tic4x_operand_parse (char *s, tic4x_operand_t *operand)
1512 {
1513   unsigned int i;
1514   char c;
1515   int ret;
1516   expressionS *exp = &operand->expr;
1517   char *save = input_line_pointer;
1518   char *str;
1519   char *new;
1520   struct hash_entry *entry = NULL;
1521
1522   input_line_pointer = s;
1523   SKIP_WHITESPACE ();
1524
1525   str = input_line_pointer;
1526   c = get_symbol_end ();        /* Get terminator.  */
1527   new = input_line_pointer;
1528   if (strlen (str) && (entry = hash_find (tic4x_asg_hash, str)) != NULL)
1529     {
1530       *input_line_pointer = c;
1531       input_line_pointer = (char *) entry;
1532     }
1533   else
1534     {
1535       *input_line_pointer = c;
1536       input_line_pointer = str;
1537     }
1538
1539   operand->mode = M_UNKNOWN;
1540   switch (*input_line_pointer)
1541     {
1542 #ifdef TIC4X_ALT_SYNTAX
1543     case '%':
1544       input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1545       if (exp->X_op != O_register)
1546         as_bad ("Expecting a register name");
1547       operand->mode = M_REGISTER;
1548       break;
1549
1550     case '^':
1551       /* Denotes high 16 bits.  */
1552       input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1553       if (exp->X_op == O_constant)
1554         operand->mode = M_IMMED;
1555       else if (exp->X_op == O_big)
1556         {
1557           if (exp->X_add_number)
1558             as_bad ("Number too large");        /* bignum required */
1559           else
1560             {
1561               tic4x_gen_to_words (generic_floating_point_number,
1562                                 operand->fwords, S_PRECISION);
1563               operand->mode = M_IMMED_F;
1564             }
1565         }
1566       /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0  */
1567       /* WARNING : The TI C40 assembler cannot do this.  */
1568       else if (exp->X_op == O_symbol)
1569         {
1570           operand->mode = M_HI;
1571           break;
1572         }
1573
1574     case '#':
1575       input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1576       if (exp->X_op == O_constant)
1577         operand->mode = M_IMMED;
1578       else if (exp->X_op == O_big)
1579         {
1580           if (exp->X_add_number > 0)
1581             as_bad ("Number too large");        /* bignum required.  */
1582           else
1583             {
1584               tic4x_gen_to_words (generic_floating_point_number,
1585                                 operand->fwords, S_PRECISION);
1586               operand->mode = M_IMMED_F;
1587             }
1588         }
1589       /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0  */
1590       /* WARNING : The TI C40 assembler cannot do this.  */
1591       else if (exp->X_op == O_symbol)
1592         {
1593           operand->mode = M_IMMED;
1594           break;
1595         }
1596
1597       else
1598         as_bad ("Expecting a constant value");
1599       break;
1600     case '\\':
1601 #endif
1602     case '@':
1603       input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1604       if (exp->X_op != O_constant && exp->X_op != O_symbol)
1605         as_bad ("Bad direct addressing construct %s", s);
1606       if (exp->X_op == O_constant)
1607         {
1608           if (exp->X_add_number < 0)
1609             as_bad ("Direct value of %ld is not suitable",
1610                     (long) exp->X_add_number);
1611         }
1612       operand->mode = M_DIRECT;
1613       break;
1614
1615     case '*':
1616       ret = -1;
1617       for (i = 0; i < tic4x_num_indirects; i++)
1618         if ((ret = tic4x_indirect_parse (operand, &tic4x_indirects[i])))
1619           break;
1620       if (ret < 0)
1621         break;
1622       if (i < tic4x_num_indirects)
1623         {
1624           operand->mode = M_INDIRECT;
1625           /* Indirect addressing mode number.  */
1626           operand->expr.X_add_number = tic4x_indirects[i].modn;
1627           /* Convert *+ARn(0) to *ARn etc.  Maybe we should
1628              squeal about silly ones?  */
1629           if (operand->expr.X_add_number < 0x08 && !operand->disp)
1630             operand->expr.X_add_number = 0x18;
1631         }
1632       else
1633         as_bad ("Unknown indirect addressing mode");
1634       break;
1635
1636     default:
1637       operand->mode = M_IMMED;  /* Assume immediate.  */
1638       str = input_line_pointer;
1639       input_line_pointer = tic4x_expression (input_line_pointer, exp);
1640       if (exp->X_op == O_register)
1641         {
1642           know (exp->X_add_symbol == 0);
1643           know (exp->X_op_symbol == 0);
1644           operand->mode = M_REGISTER;
1645           break;
1646         }
1647       else if (exp->X_op == O_big)
1648         {
1649           if (exp->X_add_number > 0)
1650             as_bad ("Number too large");        /* bignum required.  */
1651           else
1652             {
1653               tic4x_gen_to_words (generic_floating_point_number,
1654                                 operand->fwords, S_PRECISION);
1655               operand->mode = M_IMMED_F;
1656             }
1657           break;
1658         }
1659 #ifdef TIC4X_ALT_SYNTAX
1660       /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0.  */
1661       else if (exp->X_op == O_symbol)
1662         {
1663           operand->mode = M_DIRECT;
1664           break;
1665         }
1666 #endif
1667     }
1668   if (entry == NULL)
1669     new = input_line_pointer;
1670   input_line_pointer = save;
1671   return new;
1672 }
1673
1674 static int 
1675 tic4x_operands_match (tic4x_inst_t *inst, tic4x_insn_t *insn, int check)
1676 {
1677   const char *args = inst->args;
1678   unsigned long opcode = inst->opcode;
1679   int num_operands = insn->num_operands;
1680   tic4x_operand_t *operand = insn->operands;
1681   expressionS *exp = &operand->expr;
1682   int ret = 1;
1683   int reg;
1684
1685   /* Build the opcode, checking as we go to make sure that the
1686      operands match.
1687
1688      If an operand matches, we modify insn or opcode appropriately,
1689      and do a "continue".  If an operand fails to match, we "break".  */
1690
1691   insn->nchars = 4;             /* Instructions always 4 bytes.  */
1692   insn->reloc = NO_RELOC;
1693   insn->pcrel = 0;
1694
1695   if (*args == '\0')
1696     {
1697       insn->opcode = opcode;
1698       return num_operands == 0;
1699     }
1700
1701   for (;; ++args)
1702     {
1703       switch (*args)
1704         {
1705
1706         case '\0':              /* End of args.  */
1707           if (num_operands == 1)
1708             {
1709               insn->opcode = opcode;
1710               return ret;
1711             }
1712           break;                /* Too many operands.  */
1713
1714         case '#':               /* This is only used for ldp.  */
1715           if (operand->mode != M_DIRECT && operand->mode != M_IMMED)
1716             break;
1717           /* While this looks like a direct addressing mode, we actually
1718              use an immediate mode form of ldiu or ldpk instruction.  */
1719           if (exp->X_op == O_constant)
1720             {
1721               if( ( IS_CPU_TIC4X (tic4x_cpu) && exp->X_add_number <= 65535 )
1722                   || ( IS_CPU_TIC3X (tic4x_cpu) && exp->X_add_number <= 255 ) )
1723                 {
1724                   INSERTS (opcode, exp->X_add_number, 15, 0);
1725                   continue;
1726                 }
1727               else
1728                 {
1729                   if (!check)
1730                     as_bad ("Immediate value of %ld is too large for ldf",
1731                             (long) exp->X_add_number);
1732                   ret = -1;
1733                   continue;
1734                 }
1735             }
1736           else if (exp->X_op == O_symbol)
1737             {
1738               insn->reloc = BFD_RELOC_HI16;
1739               insn->exp = *exp;
1740               continue;
1741             }
1742           break;                /* Not direct (dp) addressing.  */
1743
1744         case '@':               /* direct.  */
1745           if (operand->mode != M_DIRECT)
1746             break;
1747           if (exp->X_op == O_constant)
1748             {
1749               /* Store only the 16 LSBs of the number.  */
1750               INSERTS (opcode, exp->X_add_number, 15, 0);
1751               continue;
1752             }
1753           else if (exp->X_op == O_symbol)
1754             {
1755               insn->reloc = BFD_RELOC_LO16;
1756               insn->exp = *exp;
1757               continue;
1758             }
1759           break;                /* Not direct addressing.  */
1760
1761         case 'A':
1762           if (operand->mode != M_REGISTER)
1763             break;
1764           reg = exp->X_add_number;
1765           if (reg >= REG_AR0 && reg <= REG_AR7)
1766             INSERTU (opcode, reg - REG_AR0, 24, 22);
1767           else
1768             {
1769               if (!check)
1770                 as_bad ("Destination register must be ARn");
1771               ret = -1;
1772             }
1773           continue;
1774
1775         case 'B':               /* Unsigned integer immediate.  */
1776           /* Allow br label or br @label.  */
1777           if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
1778             break;
1779           if (exp->X_op == O_constant)
1780             {
1781               if (exp->X_add_number < (1 << 24))
1782                 {
1783                   INSERTU (opcode, exp->X_add_number, 23, 0);
1784                   continue;
1785                 }
1786               else
1787                 {
1788                   if (!check)
1789                     as_bad ("Immediate value of %ld is too large",
1790                             (long) exp->X_add_number);
1791                   ret = -1;
1792                   continue;
1793                 }
1794             }
1795           if (IS_CPU_TIC4X (tic4x_cpu))
1796             {
1797               insn->reloc = BFD_RELOC_24_PCREL;
1798               insn->pcrel = 1;
1799             }
1800           else
1801             {
1802               insn->reloc = BFD_RELOC_24;
1803               insn->pcrel = 0;
1804             }
1805           insn->exp = *exp;
1806           continue;
1807
1808         case 'C':
1809           if (!IS_CPU_TIC4X (tic4x_cpu))
1810             break;
1811           if (operand->mode != M_INDIRECT)
1812             break;
1813           /* Require either *+ARn(disp) or *ARn.  */
1814           if (operand->expr.X_add_number != 0
1815               && operand->expr.X_add_number != 0x18)
1816             {
1817               if (!check)
1818                 as_bad ("Invalid indirect addressing mode");
1819               ret = -1;
1820               continue;
1821             }
1822           INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1823           INSERTU (opcode, operand->disp, 7, 3);
1824           continue;
1825
1826         case 'E':
1827           if (!(operand->mode == M_REGISTER))
1828             break;
1829           INSERTU (opcode, exp->X_add_number, 7, 0);
1830           continue;
1831
1832         case 'e':
1833           if (!(operand->mode == M_REGISTER))
1834             break;
1835           reg = exp->X_add_number;
1836           if ( (reg >= REG_R0 && reg <= REG_R7) 
1837                || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1838             INSERTU (opcode, reg, 7, 0);
1839           else
1840             {
1841               if (!check)
1842                 as_bad ("Register must be Rn");
1843               ret = -1;
1844             }
1845           continue;
1846
1847         case 'F':
1848           if (operand->mode != M_IMMED_F
1849               && !(operand->mode == M_IMMED && exp->X_op == O_constant))
1850             break;
1851
1852           if (operand->mode != M_IMMED_F)
1853             {
1854               /* OK, we 've got something like cmpf 0, r0
1855                  Why can't they stick in a bloody decimal point ?!  */
1856               char string[16];
1857
1858               /* Create floating point number string.  */
1859               sprintf (string, "%d.0", (int) exp->X_add_number);
1860               tic4x_atof (string, 's', operand->fwords);
1861             }
1862
1863           INSERTU (opcode, operand->fwords[0], 15, 0);
1864           continue;
1865
1866         case 'G':
1867           if (operand->mode != M_REGISTER)
1868             break;
1869           INSERTU (opcode, exp->X_add_number, 15, 8);
1870           continue;
1871
1872         case 'g':
1873           if (operand->mode != M_REGISTER)
1874             break;
1875           reg = exp->X_add_number;
1876           if ( (reg >= REG_R0 && reg <= REG_R7) 
1877                || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1878             INSERTU (opcode, reg, 15, 8);
1879           else
1880             {
1881               if (!check)
1882                 as_bad ("Register must be Rn");
1883               ret = -1;
1884             }
1885           continue;
1886
1887         case 'H':
1888           if (operand->mode != M_REGISTER)
1889             break;
1890           reg = exp->X_add_number;
1891           if (reg >= REG_R0 && reg <= REG_R7)
1892             INSERTU (opcode, reg - REG_R0, 18, 16);
1893           else
1894             {
1895               if (!check)
1896                 as_bad ("Register must be R0--R7");
1897               ret = -1;
1898             }
1899           continue;
1900
1901         case 'i':
1902           if ( operand->mode == M_REGISTER
1903                && tic4x_oplevel & OP_ENH )
1904             {
1905               reg = exp->X_add_number;
1906               INSERTU (opcode, reg, 4, 0);
1907               INSERTU (opcode, 7, 7, 5);
1908               continue;
1909             }
1910           /* Fallthrough */
1911
1912         case 'I':
1913           if (operand->mode != M_INDIRECT)
1914             break;
1915           if (operand->disp != 0 && operand->disp != 1)
1916             {
1917               if (IS_CPU_TIC4X (tic4x_cpu))
1918                 break;
1919               if (!check)
1920                 as_bad ("Invalid indirect addressing mode displacement %d",
1921                         operand->disp);
1922               ret = -1;
1923               continue;
1924             }
1925           INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1926           INSERTU (opcode, operand->expr.X_add_number, 7, 3);
1927           continue;
1928
1929         case 'j':
1930           if ( operand->mode == M_REGISTER
1931                && tic4x_oplevel & OP_ENH )
1932             {
1933               reg = exp->X_add_number;
1934               INSERTU (opcode, reg, 12, 8);
1935               INSERTU (opcode, 7, 15, 13);
1936               continue;
1937             }
1938           /* Fallthrough */
1939
1940         case 'J':
1941           if (operand->mode != M_INDIRECT)
1942             break;
1943           if (operand->disp != 0 && operand->disp != 1)
1944             {
1945               if (IS_CPU_TIC4X (tic4x_cpu))
1946                 break;
1947               if (!check)
1948                 as_bad ("Invalid indirect addressing mode displacement %d",
1949                         operand->disp);
1950               ret = -1;
1951               continue;
1952             }
1953           INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
1954           INSERTU (opcode, operand->expr.X_add_number, 15, 11);
1955           continue;
1956
1957         case 'K':
1958           if (operand->mode != M_REGISTER)
1959             break;
1960           reg = exp->X_add_number;
1961           if (reg >= REG_R0 && reg <= REG_R7)
1962             INSERTU (opcode, reg - REG_R0, 21, 19);
1963           else
1964             {
1965               if (!check)
1966                 as_bad ("Register must be R0--R7");
1967               ret = -1;
1968             }
1969           continue;
1970
1971         case 'L':
1972           if (operand->mode != M_REGISTER)
1973             break;
1974           reg = exp->X_add_number;
1975           if (reg >= REG_R0 && reg <= REG_R7)
1976             INSERTU (opcode, reg - REG_R0, 24, 22);
1977           else
1978             {
1979               if (!check)
1980                 as_bad ("Register must be R0--R7");
1981               ret = -1;
1982             }
1983           continue;
1984
1985         case 'M':
1986           if (operand->mode != M_REGISTER)
1987             break;
1988           reg = exp->X_add_number;
1989           if (reg == REG_R2 || reg == REG_R3)
1990             INSERTU (opcode, reg - REG_R2, 22, 22);
1991           else
1992             {
1993               if (!check)
1994                 as_bad ("Destination register must be R2 or R3");
1995               ret = -1;
1996             }
1997           continue;
1998
1999         case 'N':
2000           if (operand->mode != M_REGISTER)
2001             break;
2002           reg = exp->X_add_number;
2003           if (reg == REG_R0 || reg == REG_R1)
2004             INSERTU (opcode, reg - REG_R0, 23, 23);
2005           else
2006             {
2007               if (!check)
2008                 as_bad ("Destination register must be R0 or R1");
2009               ret = -1;
2010             }
2011           continue;
2012
2013         case 'O':
2014           if (!IS_CPU_TIC4X (tic4x_cpu))
2015             break;
2016           if (operand->mode != M_INDIRECT)
2017             break;
2018           /* Require either *+ARn(disp) or *ARn.  */
2019           if (operand->expr.X_add_number != 0
2020               && operand->expr.X_add_number != 0x18)
2021             {
2022               if (!check)
2023                 as_bad ("Invalid indirect addressing mode");
2024               ret = -1;
2025               continue;
2026             }
2027           INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2028           INSERTU (opcode, operand->disp, 15, 11);
2029           continue;
2030
2031         case 'P':               /* PC relative displacement.  */
2032           /* Allow br label or br @label.  */
2033           if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
2034             break;
2035           if (exp->X_op == O_constant)
2036             {
2037               if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767)
2038                 {
2039                   INSERTS (opcode, exp->X_add_number, 15, 0);
2040                   continue;
2041                 }
2042               else
2043                 {
2044                   if (!check)
2045                     as_bad ("Displacement value of %ld is too large",
2046                             (long) exp->X_add_number);
2047                   ret = -1;
2048                   continue;
2049                 }
2050             }
2051           insn->reloc = BFD_RELOC_16_PCREL;
2052           insn->pcrel = 1;
2053           insn->exp = *exp;
2054           continue;
2055
2056         case 'Q':
2057           if (operand->mode != M_REGISTER)
2058             break;
2059           reg = exp->X_add_number;
2060           INSERTU (opcode, reg, 15, 0);
2061           continue;
2062
2063         case 'q':
2064           if (operand->mode != M_REGISTER)
2065             break;
2066           reg = exp->X_add_number;
2067           if ( (reg >= REG_R0 && reg <= REG_R7) 
2068                || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2069             INSERTU (opcode, reg, 15, 0);
2070           else
2071             {
2072               if (!check)
2073                 as_bad ("Register must be Rn");
2074               ret = -1;
2075             }
2076           continue;
2077
2078         case 'R':
2079           if (operand->mode != M_REGISTER)
2080             break;
2081           reg = exp->X_add_number;
2082           INSERTU (opcode, reg, 20, 16);
2083           continue;
2084
2085         case 'r':
2086           if (operand->mode != M_REGISTER)
2087             break;
2088           reg = exp->X_add_number;
2089           if ( (reg >= REG_R0 && reg <= REG_R7) 
2090                || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2091             INSERTU (opcode, reg, 20, 16);
2092           else
2093             {
2094               if (!check)
2095                 as_bad ("Register must be Rn");
2096               ret = -1;
2097             }
2098           continue;
2099
2100         case 'S':               /* Short immediate int.  */
2101           if (operand->mode != M_IMMED && operand->mode != M_HI)
2102             break;
2103           if (exp->X_op == O_big)
2104             {
2105               if (!check)
2106                 as_bad ("Floating point number not valid in expression");
2107               ret = -1;
2108               continue;
2109             }
2110           if (exp->X_op == O_constant)
2111             {
2112               if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535)
2113                 {
2114                   INSERTS (opcode, exp->X_add_number, 15, 0);
2115                   continue;
2116                 }
2117               else
2118                 {
2119                   if (!check)
2120                     as_bad ("Signed immediate value %ld too large",
2121                             (long) exp->X_add_number);
2122                   ret = -1;
2123                   continue;
2124                 }
2125             }
2126           else if (exp->X_op == O_symbol)
2127             {
2128               if (operand->mode == M_HI)
2129                 {
2130                   insn->reloc = BFD_RELOC_HI16;
2131                 }
2132               else
2133                 {
2134                   insn->reloc = BFD_RELOC_LO16;
2135                 }
2136               insn->exp = *exp;
2137               continue;
2138             }
2139           /* Handle cases like ldi foo - $, ar0  where foo
2140              is a forward reference.  Perhaps we should check
2141              for X_op == O_symbol and disallow things like
2142              ldi foo, ar0.  */
2143           insn->reloc = BFD_RELOC_16;
2144           insn->exp = *exp;
2145           continue;
2146
2147         case 'T':               /* 5-bit immediate value for tic4x stik.  */
2148           if (!IS_CPU_TIC4X (tic4x_cpu))
2149             break;
2150           if (operand->mode != M_IMMED)
2151             break;
2152           if (exp->X_op == O_constant)
2153             {
2154               if (exp->X_add_number < 16 && exp->X_add_number >= -16)
2155                 {
2156                   INSERTS (opcode, exp->X_add_number, 20, 16);
2157                   continue;
2158                 }
2159               else
2160                 {
2161                   if (!check)
2162                     as_bad ("Immediate value of %ld is too large",
2163                             (long) exp->X_add_number);
2164                   ret = -1;
2165                   continue;
2166                 }
2167             }
2168           break;                /* No relocations allowed.  */
2169
2170         case 'U':               /* Unsigned integer immediate.  */
2171           if (operand->mode != M_IMMED && operand->mode != M_HI)
2172             break;
2173           if (exp->X_op == O_constant)
2174             {
2175               if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0)
2176                 {
2177                   INSERTU (opcode, exp->X_add_number, 15, 0);
2178                   continue;
2179                 }
2180               else
2181                 {
2182                   if (!check)
2183                     as_bad ("Unsigned immediate value %ld too large",
2184                             (long) exp->X_add_number);
2185                   ret = -1;
2186                   continue;
2187                 }
2188             }
2189           else if (exp->X_op == O_symbol)
2190             {
2191               if (operand->mode == M_HI)
2192                 insn->reloc = BFD_RELOC_HI16;
2193               else
2194                 insn->reloc = BFD_RELOC_LO16;
2195
2196               insn->exp = *exp;
2197               continue;
2198             }
2199           insn->reloc = BFD_RELOC_16;
2200           insn->exp = *exp;
2201           continue;
2202
2203         case 'V':               /* Trap numbers (immediate field).  */
2204           if (operand->mode != M_IMMED)
2205             break;
2206           if (exp->X_op == O_constant)
2207             {
2208               if (exp->X_add_number < 512 && IS_CPU_TIC4X (tic4x_cpu))
2209                 {
2210                   INSERTU (opcode, exp->X_add_number, 8, 0);
2211                   continue;
2212                 }
2213               else if (exp->X_add_number < 32 && IS_CPU_TIC3X (tic4x_cpu))
2214                 {
2215                   INSERTU (opcode, exp->X_add_number | 0x20, 4, 0);
2216                   continue;
2217                 }
2218               else
2219                 {
2220                   if (!check)
2221                     as_bad ("Immediate value of %ld is too large",
2222                             (long) exp->X_add_number);
2223                   ret = -1;
2224                   continue;
2225                 }
2226             }
2227           break;                /* No relocations allowed.  */
2228
2229         case 'W':               /* Short immediate int (0--7).  */
2230           if (!IS_CPU_TIC4X (tic4x_cpu))
2231             break;
2232           if (operand->mode != M_IMMED)
2233             break;
2234           if (exp->X_op == O_big)
2235             {
2236               if (!check)
2237                 as_bad ("Floating point number not valid in expression");
2238               ret = -1;
2239               continue;
2240             }
2241           if (exp->X_op == O_constant)
2242             {
2243               if (exp->X_add_number >= -256 && exp->X_add_number <= 127)
2244                 {
2245                   INSERTS (opcode, exp->X_add_number, 7, 0);
2246                   continue;
2247                 }
2248               else
2249                 {
2250                   if (!check)
2251                     as_bad ("Immediate value %ld too large",
2252                             (long) exp->X_add_number);
2253                   ret = -1;
2254                   continue;
2255                 }
2256             }
2257           insn->reloc = BFD_RELOC_16;
2258           insn->exp = *exp;
2259           continue;
2260
2261         case 'X':               /* Expansion register for tic4x.  */
2262           if (operand->mode != M_REGISTER)
2263             break;
2264           reg = exp->X_add_number;
2265           if (reg >= REG_IVTP && reg <= REG_TVTP)
2266             INSERTU (opcode, reg - REG_IVTP, 4, 0);
2267           else
2268             {
2269               if (!check)
2270                 as_bad ("Register must be ivtp or tvtp");
2271               ret = -1;
2272             }
2273           continue;
2274
2275         case 'Y':               /* Address register for tic4x lda.  */
2276           if (operand->mode != M_REGISTER)
2277             break;
2278           reg = exp->X_add_number;
2279           if (reg >= REG_AR0 && reg <= REG_SP)
2280             INSERTU (opcode, reg, 20, 16);
2281           else
2282             {
2283               if (!check)
2284                 as_bad ("Register must be address register");
2285               ret = -1;
2286             }
2287           continue;
2288
2289         case 'Z':               /* Expansion register for tic4x.  */
2290           if (operand->mode != M_REGISTER)
2291             break;
2292           reg = exp->X_add_number;
2293           if (reg >= REG_IVTP && reg <= REG_TVTP)
2294             INSERTU (opcode, reg - REG_IVTP, 20, 16);
2295           else
2296             {
2297               if (!check)
2298                 as_bad ("Register must be ivtp or tvtp");
2299               ret = -1;
2300             }
2301           continue;
2302
2303         case '*':
2304           if (operand->mode != M_INDIRECT)
2305             break;
2306           INSERTS (opcode, operand->disp, 7, 0);
2307           INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2308           INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2309           continue;
2310
2311         case '|':               /* treat as `,' if have ldi_ldi form.  */
2312           if (insn->parallel)
2313             {
2314               if (--num_operands < 0)
2315                 break;          /* Too few operands.  */
2316               operand++;
2317               if (operand->mode != M_PARALLEL)
2318                 break;
2319             }
2320           /* Fall through.  */
2321
2322         case ',':               /* Another operand.  */
2323           if (--num_operands < 0)
2324             break;              /* Too few operands.  */
2325           operand++;
2326           exp = &operand->expr;
2327           continue;
2328
2329         case ';':               /* Another optional operand.  */
2330           if (num_operands == 1 || operand[1].mode == M_PARALLEL)
2331             continue;
2332           if (--num_operands < 0)
2333             break;              /* Too few operands.  */
2334           operand++;
2335           exp = &operand->expr;
2336           continue;
2337
2338         default:
2339           BAD_CASE (*args);
2340         }
2341       return 0;
2342     }
2343 }
2344
2345 static void
2346 tic4x_insn_check (tic4x_insn_t *insn)
2347 {
2348   
2349   if (!strcmp(insn->name, "lda"))
2350     {
2351       if (insn->num_operands < 2 || insn->num_operands > 2)
2352         as_fatal ("Illegal internal LDA insn definition");
2353
2354       if ( insn->operands[0].mode == M_REGISTER
2355            && insn->operands[1].mode == M_REGISTER
2356            && insn->operands[0].expr.X_add_number == insn->operands[1].expr.X_add_number )
2357         as_bad ("Source and destination register should not be equal");
2358     }
2359   else if( !strcmp(insn->name, "ldi_ldi")
2360            || !strcmp(insn->name, "ldi1_ldi2")
2361            || !strcmp(insn->name, "ldi2_ldi1")
2362            || !strcmp(insn->name, "ldf_ldf")
2363            || !strcmp(insn->name, "ldf1_ldf2")
2364            || !strcmp(insn->name, "ldf2_ldf1") )
2365     {
2366       if ( insn->num_operands < 4 && insn->num_operands > 5 )
2367         as_fatal ("Illegal internal %s insn definition", insn->name);
2368       
2369       if ( insn->operands[1].mode == M_REGISTER
2370            && insn->operands[insn->num_operands-1].mode == M_REGISTER
2371            && insn->operands[1].expr.X_add_number == insn->operands[insn->num_operands-1].expr.X_add_number )
2372         as_warn ("Equal parallell destination registers, one result will be discarded");
2373     }
2374 }
2375
2376 static void 
2377 tic4x_insn_output (tic4x_insn_t *insn)
2378 {
2379   char *dst;
2380
2381   /* Grab another fragment for opcode.  */
2382   dst = frag_more (insn->nchars);
2383
2384   /* Put out opcode word as a series of bytes in little endian order.  */
2385   md_number_to_chars (dst, insn->opcode, insn->nchars);
2386
2387   /* Put out the symbol-dependent stuff.  */
2388   if (insn->reloc != NO_RELOC)
2389     {
2390       /* Where is the offset into the fragment for this instruction.  */
2391       fix_new_exp (frag_now,
2392                    dst - frag_now->fr_literal,  /* where */
2393                    insn->nchars,        /* size */
2394                    &insn->exp,
2395                    insn->pcrel,
2396                    insn->reloc);
2397     }
2398 }
2399
2400 /* Parse the operands.  */
2401 static int 
2402 tic4x_operands_parse (char *s, tic4x_operand_t *operands, int num_operands)
2403 {
2404   if (!*s)
2405     return num_operands;
2406
2407   do
2408     s = tic4x_operand_parse (s, &operands[num_operands++]);
2409   while (num_operands < TIC4X_OPERANDS_MAX && *s++ == ',');
2410
2411   if (num_operands > TIC4X_OPERANDS_MAX)
2412     {
2413       as_bad ("Too many operands scanned");
2414       return -1;
2415     }
2416   return num_operands;
2417 }
2418
2419 /* Assemble a single instruction.  Its label has already been handled
2420    by the generic front end.  We just parse mnemonic and operands, and
2421    produce the bytes of data and relocation.  */
2422 void 
2423 md_assemble (char *str)
2424 {
2425   int ok = 0;
2426   char *s;
2427   int i;
2428   int parsed = 0;
2429   tic4x_inst_t *inst;           /* Instruction template.  */
2430   tic4x_inst_t *first_inst;
2431
2432   /* Scan for parallel operators */
2433   if (str)
2434     {
2435       s = str;
2436       while (*s && *s != '|')
2437         s++;
2438       
2439       if (*s && s[1]=='|')
2440         {
2441           if(insn->parallel)
2442             {
2443               as_bad ("Parallel opcode cannot contain more than two instructions");
2444               insn->parallel = 0;
2445               insn->in_use = 0;
2446               return;
2447             }
2448           
2449           /* Lets take care of the first part of the parallel insn */
2450           *s++ = 0;
2451           md_assemble(str);
2452           insn->parallel = 1;
2453           str = ++s;
2454           /* .. and let the second run though here */
2455         }
2456     }
2457   
2458   if (str && insn->parallel)
2459     {
2460       /* Find mnemonic (second part of parallel instruction).  */
2461       s = str;
2462       /* Skip past instruction mnemonic.  */
2463       while (*s && *s != ' ')
2464         s++;
2465       if (*s)                   /* Null terminate for hash_find.  */
2466         *s++ = '\0';            /* and skip past null.  */
2467       strcat (insn->name, "_");
2468       strncat (insn->name, str, TIC4X_NAME_MAX - strlen (insn->name));
2469
2470       insn->operands[insn->num_operands++].mode = M_PARALLEL;
2471
2472       if ((i = tic4x_operands_parse
2473            (s, insn->operands, insn->num_operands)) < 0)
2474         {
2475           insn->parallel = 0;
2476           insn->in_use = 0;
2477           return;
2478         }
2479       insn->num_operands = i;
2480       parsed = 1;
2481     }
2482
2483   if (insn->in_use)
2484     {
2485       if ((insn->inst = (struct tic4x_inst *)
2486            hash_find (tic4x_op_hash, insn->name)) == NULL)
2487         {
2488           as_bad ("Unknown opcode `%s'.", insn->name);
2489           insn->parallel = 0;
2490           insn->in_use = 0;
2491           return;
2492         }
2493
2494       inst = insn->inst;
2495       first_inst = NULL;
2496       do
2497         {
2498           ok = tic4x_operands_match (inst, insn, 1);
2499           if (ok < 0)
2500             {
2501               if (!first_inst)
2502                 first_inst = inst;
2503               ok = 0;
2504             }
2505       } while (!ok && !strcmp (inst->name, inst[1].name) && inst++);
2506
2507       if (ok > 0)
2508         {
2509           tic4x_insn_check (insn);
2510           tic4x_insn_output (insn);
2511         }
2512       else if (!ok)
2513         {
2514           if (first_inst)
2515             tic4x_operands_match (first_inst, insn, 0);
2516           as_bad ("Invalid operands for %s", insn->name);
2517         }
2518       else
2519         as_bad ("Invalid instruction %s", insn->name);
2520     }
2521
2522   if (str && !parsed)
2523     {
2524       /* Find mnemonic.  */
2525       s = str;
2526       while (*s && *s != ' ')   /* Skip past instruction mnemonic.  */
2527         s++;
2528       if (*s)                   /* Null terminate for hash_find.  */
2529         *s++ = '\0';            /* and skip past null.  */
2530       strncpy (insn->name, str, TIC4X_NAME_MAX - 3);
2531
2532       if ((i = tic4x_operands_parse (s, insn->operands, 0)) < 0)
2533         {
2534           insn->inst = NULL;    /* Flag that error occurred.  */
2535           insn->parallel = 0;
2536           insn->in_use = 0;
2537           return;
2538         }
2539       insn->num_operands = i;
2540       insn->in_use = 1;
2541     }
2542   else
2543     insn->in_use = 0;
2544   insn->parallel = 0;
2545 }
2546
2547 void
2548 tic4x_cleanup (void)
2549 {
2550   if (insn->in_use)
2551     md_assemble (NULL);
2552 }
2553
2554 /* Turn a string in input_line_pointer into a floating point constant
2555    of type type, and store the appropriate bytes in *litP.  The number
2556    of chars emitted is stored in *sizeP.  An error message is
2557    returned, or NULL on OK.  */
2558
2559 char *
2560 md_atof (int type, char *litP, int *sizeP)
2561 {
2562   int prec;
2563   int ieee;
2564   LITTLENUM_TYPE words[MAX_LITTLENUMS];
2565   LITTLENUM_TYPE *wordP;
2566   char *t;
2567
2568   switch (type)
2569     {
2570     case 's':           /* .single  */
2571     case 'S':
2572       ieee = 0;
2573       prec = 1;
2574       break;
2575
2576     case 'd':           /* .double  */
2577     case 'D':
2578     case 'f':           /* .float  */
2579     case 'F':
2580       ieee = 0;
2581       prec = 2;         /* 1 32-bit word */
2582       break;
2583
2584     case 'i':           /* .ieee */
2585     case 'I':
2586       prec = 2;
2587       ieee = 1;
2588       type = 'f';  /* Rewrite type to be usable by atof_ieee().  */
2589       break;
2590
2591     case 'e':           /* .ldouble */
2592     case 'E':
2593       prec = 4;         /* 2 32-bit words */
2594       ieee = 0;
2595       break;
2596
2597     default:
2598       *sizeP = 0;
2599       return _("Unrecognized or unsupported floating point constant");
2600     }
2601
2602   if (ieee)
2603     t = atof_ieee (input_line_pointer, type, words);
2604   else
2605     t = tic4x_atof (input_line_pointer, type, words);
2606   if (t)
2607     input_line_pointer = t;
2608   *sizeP = prec * sizeof (LITTLENUM_TYPE);
2609
2610   /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2611      little endian byte order.  */
2612   /* SES: However it is required to put the words (32-bits) out in the
2613      correct order, hence we write 2 and 2 littlenums in little endian
2614      order, while we keep the original order on successive words.  */
2615   for (wordP = words; wordP<(words+prec) ; wordP+=2)
2616     {
2617       if (wordP < (words + prec - 1)) /* Dump wordP[1] (if we have one).  */
2618         {
2619           md_number_to_chars (litP, (valueT) (wordP[1]),
2620                               sizeof (LITTLENUM_TYPE));
2621           litP += sizeof (LITTLENUM_TYPE);
2622         }
2623
2624       /* Dump wordP[0] */
2625       md_number_to_chars (litP, (valueT) (wordP[0]),
2626                           sizeof (LITTLENUM_TYPE));
2627       litP += sizeof (LITTLENUM_TYPE);
2628     }
2629   return NULL;
2630 }
2631
2632 void 
2633 md_apply_fix (fixS *fixP, valueT *value, segT seg ATTRIBUTE_UNUSED)
2634 {
2635   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2636   valueT val = *value;
2637
2638   switch (fixP->fx_r_type)
2639     {
2640     case BFD_RELOC_HI16:
2641       val >>= 16;
2642       break;
2643
2644     case BFD_RELOC_LO16:
2645       val &= 0xffff;
2646       break;
2647     default:
2648       break;
2649     }
2650
2651   switch (fixP->fx_r_type)
2652     {
2653     case BFD_RELOC_32:
2654       buf[3] = val >> 24;
2655     case BFD_RELOC_24:
2656     case BFD_RELOC_24_PCREL:
2657       buf[2] = val >> 16;
2658     case BFD_RELOC_16:
2659     case BFD_RELOC_16_PCREL:
2660     case BFD_RELOC_LO16:
2661     case BFD_RELOC_HI16:
2662       buf[1] = val >> 8;
2663       buf[0] = val;
2664       break;
2665
2666     case NO_RELOC:
2667     default:
2668       as_bad ("Bad relocation type: 0x%02x", fixP->fx_r_type);
2669       break;
2670     }
2671
2672   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1;
2673 }
2674
2675 /* Should never be called for tic4x.  */
2676 void 
2677 md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
2678                  segT sec ATTRIBUTE_UNUSED,
2679                  fragS *fragP ATTRIBUTE_UNUSED)
2680 {
2681   as_fatal ("md_convert_frag");
2682 }
2683
2684 /* Should never be called for tic4x.  */
2685 void
2686 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
2687                       addressT from_addr ATTRIBUTE_UNUSED,
2688                       addressT to_addr ATTRIBUTE_UNUSED,
2689                       fragS *frag ATTRIBUTE_UNUSED,
2690                       symbolS *to_symbol ATTRIBUTE_UNUSED)
2691 {
2692   as_fatal ("md_create_short_jmp\n");
2693 }
2694
2695 /* Should never be called for tic4x.  */
2696 void
2697 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
2698                      addressT from_addr ATTRIBUTE_UNUSED,
2699                      addressT to_addr ATTRIBUTE_UNUSED,
2700                      fragS *frag ATTRIBUTE_UNUSED,
2701                      symbolS *to_symbol ATTRIBUTE_UNUSED)
2702 {
2703   as_fatal ("md_create_long_jump\n");
2704 }
2705
2706 /* Should never be called for tic4x.  */
2707 int
2708 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
2709                                segT segtype ATTRIBUTE_UNUSED)
2710 {
2711   as_fatal ("md_estimate_size_before_relax\n");
2712   return 0;
2713 }
2714
2715
2716 int
2717 md_parse_option (int c, char *arg)
2718 {
2719   switch (c)
2720     {
2721     case OPTION_CPU:             /* cpu brand */
2722       if (TOLOWER (*arg) == 'c')
2723         arg++;
2724       tic4x_cpu = atoi (arg);
2725       if (!IS_CPU_TIC3X (tic4x_cpu) && !IS_CPU_TIC4X (tic4x_cpu))
2726         as_warn ("Unsupported processor generation %d", tic4x_cpu);
2727       break;
2728
2729     case OPTION_REV:             /* cpu revision */
2730       tic4x_revision = atoi (arg);
2731       break;
2732
2733     case 'b':
2734       as_warn ("Option -b is depreciated, please use -mbig");
2735     case OPTION_BIG:             /* big model */
2736       tic4x_big_model = 1;
2737       break;
2738
2739     case 'p':
2740       as_warn ("Option -p is depreciated, please use -mmemparm");
2741     case OPTION_MEMPARM:         /* push args */
2742       tic4x_reg_args = 0;
2743       break;
2744
2745     case 'r':                   
2746       as_warn ("Option -r is depreciated, please use -mregparm");
2747     case OPTION_REGPARM:        /* register args */
2748       tic4x_reg_args = 1;
2749       break;
2750
2751     case 's':
2752       as_warn ("Option -s is depreciated, please use -msmall");
2753     case OPTION_SMALL:          /* small model */
2754       tic4x_big_model = 0;
2755       break;
2756
2757     case OPTION_IDLE2:
2758       tic4x_idle2 = 1;
2759       break;
2760
2761     case OPTION_LOWPOWER:
2762       tic4x_lowpower = 1;
2763       break;
2764
2765     case OPTION_ENHANCED:
2766       tic4x_enhanced = 1;
2767       break;
2768
2769     default:
2770       return 0;
2771     }
2772
2773   return 1;
2774 }
2775
2776 void
2777 md_show_usage (FILE *stream)
2778 {
2779   fprintf (stream,
2780       _("\nTIC4X options:\n"
2781         "  -mcpu=CPU  -mCPU        select architecture variant. CPU can be:\n"
2782         "                            30 - TMS320C30\n"
2783         "                            31 - TMS320C31, TMS320LC31\n"
2784         "                            32 - TMS320C32\n"
2785         "                            33 - TMS320VC33\n"
2786         "                            40 - TMS320C40\n"
2787         "                            44 - TMS320C44\n"
2788         "  -mrev=REV               set cpu hardware revision (integer numbers).\n"
2789         "                          Combinations of -mcpu and -mrev will enable/disable\n"
2790         "                          the appropriate options (-midle2, -mlowpower and\n"
2791         "                          -menhanced) according to the selected type\n"
2792         "  -mbig                   select big memory model\n"
2793         "  -msmall                 select small memory model (default)\n"
2794         "  -mregparm               select register parameters (default)\n"
2795         "  -mmemparm               select memory parameters\n"
2796         "  -midle2                 enable IDLE2 support\n"
2797         "  -mlowpower              enable LOPOWER and MAXSPEED support\n"
2798         "  -menhanced              enable enhanced opcode support\n"));
2799 }
2800
2801 /* This is called when a line is unrecognized.  This is used to handle
2802    definitions of TI C3x tools style local labels $n where n is a single
2803    decimal digit.  */
2804 int 
2805 tic4x_unrecognized_line (int c)
2806 {
2807   int lab;
2808   char *s;
2809
2810   if (c != '$' || ! ISDIGIT (input_line_pointer[0]))
2811     return 0;
2812
2813   s = input_line_pointer;
2814
2815   /* Let's allow multiple digit local labels.  */
2816   lab = 0;
2817   while (ISDIGIT (*s))
2818     {
2819       lab = lab * 10 + *s - '0';
2820       s++;
2821     }
2822
2823   if (dollar_label_defined (lab))
2824     {
2825       as_bad ("Label \"$%d\" redefined", lab);
2826       return 0;
2827     }
2828
2829   define_dollar_label (lab);
2830   colon (dollar_label_name (lab, 0));
2831   input_line_pointer = s + 1;
2832
2833   return 1;
2834 }
2835
2836 /* Handle local labels peculiar to us referred to in an expression.  */
2837 symbolS *
2838 md_undefined_symbol (char *name)
2839 {
2840   /* Look for local labels of the form $n.  */
2841   if (name[0] == '$' && ISDIGIT (name[1]))
2842     {
2843       symbolS *symbolP;
2844       char *s = name + 1;
2845       int lab = 0;
2846
2847       while (ISDIGIT ((unsigned char) *s))
2848         {
2849           lab = lab * 10 + *s - '0';
2850           s++;
2851         }
2852       if (dollar_label_defined (lab))
2853         {
2854           name = dollar_label_name (lab, 0);
2855           symbolP = symbol_find (name);
2856         }
2857       else
2858         {
2859           name = dollar_label_name (lab, 1);
2860           symbolP = symbol_find_or_make (name);
2861         }
2862
2863       return symbolP;
2864     }
2865   return NULL;
2866 }
2867
2868 /* Parse an operand that is machine-specific.  */
2869 void
2870 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
2871 {
2872 }
2873
2874 /* Round up a section size to the appropriate boundary---do we need this?  */
2875 valueT
2876 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2877 {
2878   return size;                  /* Byte (i.e., 32-bit) alignment is fine?  */
2879 }
2880
2881 static int 
2882 tic4x_pc_offset (unsigned int op)
2883 {
2884   /* Determine the PC offset for a C[34]x instruction.
2885      This could be simplified using some boolean algebra
2886      but at the expense of readability.  */
2887   switch (op >> 24)
2888     {
2889     case 0x60:                  /* br */
2890     case 0x62:                  /* call  (C4x) */
2891     case 0x64:                  /* rptb  (C4x) */
2892       return 1;
2893     case 0x61:                  /* brd */
2894     case 0x63:                  /* laj */
2895     case 0x65:                  /* rptbd (C4x) */
2896       return 3;
2897     case 0x66:                  /* swi */
2898     case 0x67:
2899       return 0;
2900     default:
2901       break;
2902     }
2903
2904   switch ((op & 0xffe00000) >> 20)
2905     {
2906     case 0x6a0:         /* bB */
2907     case 0x720:         /* callB */
2908     case 0x740:         /* trapB */
2909       return 1;
2910
2911     case 0x6a2:         /* bBd */
2912     case 0x6a6:         /* bBat */
2913     case 0x6aa:         /* bBaf */
2914     case 0x722:         /* lajB */
2915     case 0x748:         /* latB */
2916     case 0x798:         /* rptbd */
2917       return 3;
2918
2919     default:
2920       break;
2921     }
2922
2923   switch ((op & 0xfe200000) >> 20)
2924     {
2925     case 0x6e0:         /* dbB */
2926       return 1;
2927
2928     case 0x6e2:         /* dbBd */
2929       return 3;
2930
2931     default:
2932       break;
2933     }
2934
2935   return 0;
2936 }
2937
2938 /* Exactly what point is a PC-relative offset relative TO?
2939    With the C3x we have the following:
2940    DBcond,  Bcond   disp + PC + 1 => PC
2941    DBcondD, BcondD  disp + PC + 3 => PC
2942  */
2943 long
2944 md_pcrel_from (fixS *fixP)
2945 {
2946   unsigned char *buf;
2947   unsigned int op;
2948
2949   buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
2950   op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2951
2952   return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
2953     tic4x_pc_offset (op);
2954 }
2955
2956 /* Fill the alignment area with NOP's on .text, unless fill-data
2957    was specified. */
2958 int 
2959 tic4x_do_align (int alignment ATTRIBUTE_UNUSED,
2960                 const char *fill ATTRIBUTE_UNUSED,
2961                 int len ATTRIBUTE_UNUSED,
2962                 int max ATTRIBUTE_UNUSED)
2963 {
2964   unsigned long nop = TIC_NOP_OPCODE;
2965
2966   /* Because we are talking lwords, not bytes, adjust alignment to do words */
2967   alignment += 2;
2968   
2969   if (alignment != 0 && !need_pass_2)
2970     {
2971       if (fill == NULL)
2972         {
2973           /*if (subseg_text_p (now_seg))*/  /* FIXME: doesn't work for .text for some reason */
2974           frag_align_pattern( alignment, (const char *)&nop, sizeof(nop), max);
2975           return 1;
2976           /*else
2977             frag_align (alignment, 0, max);*/
2978         }
2979       else if (len <= 1)
2980         frag_align (alignment, *fill, max);
2981       else
2982         frag_align_pattern (alignment, fill, len, max);
2983     }
2984   
2985   /* Return 1 to skip the default alignment function */
2986   return 1;
2987 }
2988
2989 /* Look for and remove parallel instruction operator ||.  */
2990 void 
2991 tic4x_start_line (void)
2992 {
2993   char *s = input_line_pointer;
2994
2995   SKIP_WHITESPACE ();
2996
2997   /* If parallel instruction prefix found at start of line, skip it.  */
2998   if (*input_line_pointer == '|' && input_line_pointer[1] == '|')
2999     {
3000       if (insn->in_use)
3001         {
3002           insn->parallel = 1;
3003           input_line_pointer ++;
3004           *input_line_pointer = ' ';
3005           /* So line counters get bumped.  */
3006           input_line_pointer[-1] = '\n';
3007         }
3008     }
3009   else
3010     {
3011       /* Write out the previous insn here */
3012       if (insn->in_use)
3013         md_assemble (NULL);
3014       input_line_pointer = s;
3015     }
3016 }
3017
3018 arelent *
3019 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixP)
3020 {
3021   arelent *reloc;
3022
3023   reloc = (arelent *) xmalloc (sizeof (arelent));
3024
3025   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
3026   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3027   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3028   reloc->address /= OCTETS_PER_BYTE;
3029   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
3030   if (reloc->howto == (reloc_howto_type *) NULL)
3031     {
3032       as_bad_where (fixP->fx_file, fixP->fx_line,
3033                     "Reloc %d not supported by object file format",
3034                     (int) fixP->fx_r_type);
3035       return NULL;
3036     }
3037
3038   if (fixP->fx_r_type == BFD_RELOC_HI16)
3039     reloc->addend = fixP->fx_offset;
3040   else
3041     reloc->addend = fixP->fx_addnumber;
3042
3043   return reloc;
3044 }