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