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