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