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