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