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