(root)/
binutils-2.41/
gas/
config/
tc-tic4x.c
       1  /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
       2     Copyright (C) 1997-2023 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
     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 *
     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
     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
     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 *
     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 *
     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
     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
     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
     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
     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
     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
     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
     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
     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
     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
     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
    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
    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
    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
    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
    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
    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 *
    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
    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
    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
    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
    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 *
    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
    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
    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
    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
    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
    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
    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 *
    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
    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
    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
    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
    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
    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
    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
    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
    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 *
    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
    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
    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
    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
    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
    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
    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 *
    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  }