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