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