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