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