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