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