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