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