Home | History | Annotate | Line # | Download | only in config
tc-tic30.c revision 1.1.1.8.2.1
      1          1.1     skrll /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
      2  1.1.1.8.2.1  perseant    Copyright (C) 1998-2024 Free Software Foundation, Inc.
      3          1.1     skrll    Contributed by Steven Haworth (steve (at) pm.cse.rmit.edu.au)
      4          1.1     skrll 
      5          1.1     skrll    This file is part of GAS, the GNU Assembler.
      6          1.1     skrll 
      7          1.1     skrll    GAS is free software; you can redistribute it and/or modify
      8          1.1     skrll    it under the terms of the GNU General Public License as published by
      9          1.1     skrll    the Free Software Foundation; either version 3, or (at your option)
     10          1.1     skrll    any later version.
     11          1.1     skrll 
     12          1.1     skrll    GAS is distributed in the hope that it will be useful,
     13          1.1     skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14          1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15          1.1     skrll    GNU General Public License for more details.
     16          1.1     skrll 
     17          1.1     skrll    You should have received a copy of the GNU General Public License
     18          1.1     skrll    along with GAS; see the file COPYING.  If not, write to the Free
     19          1.1     skrll    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     20          1.1     skrll    02110-1301, USA.  */
     21          1.1     skrll 
     22          1.1     skrll /* Texas Instruments TMS320C30 machine specific gas.
     23          1.1     skrll    Written by Steven Haworth (steve (at) pm.cse.rmit.edu.au).
     24          1.1     skrll    Bugs & suggestions are completely welcome.  This is free software.
     25          1.1     skrll    Please help us make it better.  */
     26          1.1     skrll 
     27          1.1     skrll #include "as.h"
     28          1.1     skrll #include "safe-ctype.h"
     29          1.1     skrll #include "opcode/tic30.h"
     30          1.1     skrll 
     31          1.1     skrll /* Put here all non-digit non-letter characters that may occur in an
     32          1.1     skrll    operand.  */
     33          1.1     skrll static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
     34      1.1.1.5  christos static const char *ordinal_names[] =
     35          1.1     skrll {
     36      1.1.1.3  christos   N_("first"), N_("second"), N_("third"), N_("fourth"), N_("fifth")
     37          1.1     skrll };
     38          1.1     skrll 
     39          1.1     skrll const char comment_chars[]        = ";";
     40          1.1     skrll const char line_comment_chars[]   = "*";
     41          1.1     skrll const char line_separator_chars[] = "";
     42          1.1     skrll 
     43          1.1     skrll const char *md_shortopts = "";
     44          1.1     skrll struct option md_longopts[] =
     45          1.1     skrll {
     46          1.1     skrll   {NULL, no_argument, NULL, 0}
     47          1.1     skrll };
     48          1.1     skrll 
     49          1.1     skrll size_t md_longopts_size = sizeof (md_longopts);
     50          1.1     skrll 
     51          1.1     skrll /* Chars that mean this number is a floating point constant.
     52          1.1     skrll    As in 0f12.456
     53          1.1     skrll    or    0d1.2345e12.  */
     54          1.1     skrll const char FLT_CHARS[] = "fFdDxX";
     55          1.1     skrll 
     56          1.1     skrll /* Chars that can be used to separate mant from exp in floating point
     57          1.1     skrll    nums.  */
     58          1.1     skrll const char EXP_CHARS[] = "eE";
     59          1.1     skrll 
     60          1.1     skrll /* Tables for lexical analysis.  */
     61          1.1     skrll static char opcode_chars[256];
     62          1.1     skrll static char register_chars[256];
     63          1.1     skrll static char operand_chars[256];
     64          1.1     skrll static char space_chars[256];
     65          1.1     skrll static char identifier_chars[256];
     66          1.1     skrll static char digit_chars[256];
     67          1.1     skrll 
     68          1.1     skrll /* Lexical macros.  */
     69          1.1     skrll #define is_opcode_char(x)     (opcode_chars     [(unsigned char) x])
     70          1.1     skrll #define is_operand_char(x)    (operand_chars    [(unsigned char) x])
     71          1.1     skrll #define is_register_char(x)   (register_chars   [(unsigned char) x])
     72          1.1     skrll #define is_space_char(x)      (space_chars      [(unsigned char) x])
     73          1.1     skrll #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
     74          1.1     skrll #define is_digit_char(x)      (digit_chars      [(unsigned char) x])
     75          1.1     skrll 
     76          1.1     skrll const pseudo_typeS md_pseudo_table[] =
     77          1.1     skrll {
     78          1.1     skrll   {0, 0, 0}
     79          1.1     skrll };
     80          1.1     skrll 
     81          1.1     skrll static int ATTRIBUTE_PRINTF_1
     82          1.1     skrll debug (const char *string, ...)
     83          1.1     skrll {
     84          1.1     skrll   if (flag_debug)
     85          1.1     skrll     {
     86          1.1     skrll       char str[100];
     87      1.1.1.4  christos       va_list argptr;
     88          1.1     skrll 
     89      1.1.1.4  christos       va_start (argptr, string);
     90          1.1     skrll       vsprintf (str, string, argptr);
     91      1.1.1.4  christos       va_end (argptr);
     92          1.1     skrll       if (str[0] == '\0')
     93          1.1     skrll 	return (0);
     94          1.1     skrll       fputs (str, USE_STDOUT ? stdout : stderr);
     95          1.1     skrll       return strlen (str);
     96          1.1     skrll     }
     97          1.1     skrll   else
     98          1.1     skrll     return 0;
     99          1.1     skrll }
    100          1.1     skrll 
    101          1.1     skrll /* Hash table for opcode lookup.  */
    102      1.1.1.8  christos static htab_t op_hash;
    103          1.1     skrll /* Hash table for parallel opcode lookup.  */
    104      1.1.1.8  christos static htab_t parop_hash;
    105          1.1     skrll /* Hash table for register lookup.  */
    106      1.1.1.8  christos static htab_t reg_hash;
    107          1.1     skrll /* Hash table for indirect addressing lookup.  */
    108      1.1.1.8  christos static htab_t ind_hash;
    109          1.1     skrll 
    110          1.1     skrll void
    111          1.1     skrll md_begin (void)
    112          1.1     skrll {
    113          1.1     skrll   debug ("In md_begin()\n");
    114      1.1.1.8  christos   op_hash = str_htab_create ();
    115          1.1     skrll 
    116          1.1     skrll   {
    117      1.1.1.2  christos     const insn_template *current_optab = tic30_optab;
    118          1.1     skrll 
    119          1.1     skrll     for (; current_optab < tic30_optab_end; current_optab++)
    120      1.1.1.8  christos       if (str_hash_insert (op_hash, current_optab->name, current_optab, 0))
    121      1.1.1.8  christos 	as_fatal (_("duplicate %s"), current_optab->name);
    122          1.1     skrll   }
    123          1.1     skrll 
    124      1.1.1.8  christos   parop_hash = str_htab_create ();
    125          1.1     skrll 
    126          1.1     skrll   {
    127          1.1     skrll     const partemplate *current_parop = tic30_paroptab;
    128          1.1     skrll 
    129          1.1     skrll     for (; current_parop < tic30_paroptab_end; current_parop++)
    130      1.1.1.8  christos       if (str_hash_insert (parop_hash, current_parop->name, current_parop, 0))
    131      1.1.1.8  christos 	as_fatal (_("duplicate %s"), current_parop->name);
    132          1.1     skrll   }
    133          1.1     skrll 
    134      1.1.1.8  christos   reg_hash = str_htab_create ();
    135          1.1     skrll 
    136          1.1     skrll   {
    137          1.1     skrll     const reg *current_reg = tic30_regtab;
    138          1.1     skrll 
    139          1.1     skrll     for (; current_reg < tic30_regtab_end; current_reg++)
    140      1.1.1.8  christos       if (str_hash_insert (reg_hash, current_reg->name, current_reg, 0))
    141      1.1.1.8  christos 	as_fatal (_("duplicate %s"), current_reg->name);
    142          1.1     skrll   }
    143          1.1     skrll 
    144      1.1.1.8  christos   ind_hash = str_htab_create ();
    145          1.1     skrll 
    146          1.1     skrll   {
    147          1.1     skrll     const ind_addr_type *current_ind = tic30_indaddr_tab;
    148          1.1     skrll 
    149          1.1     skrll     for (; current_ind < tic30_indaddrtab_end; current_ind++)
    150      1.1.1.8  christos       if (str_hash_insert (ind_hash, current_ind->syntax, current_ind, 0))
    151      1.1.1.8  christos 	as_fatal (_("duplicate %s"), current_ind->syntax);
    152          1.1     skrll   }
    153          1.1     skrll 
    154          1.1     skrll   /* Fill in lexical tables:  opcode_chars, operand_chars, space_chars.  */
    155          1.1     skrll   {
    156          1.1     skrll     int c;
    157          1.1     skrll     char *p;
    158          1.1     skrll 
    159          1.1     skrll     for (c = 0; c < 256; c++)
    160          1.1     skrll       {
    161          1.1     skrll 	if (ISLOWER (c) || ISDIGIT (c))
    162          1.1     skrll 	  {
    163          1.1     skrll 	    opcode_chars[c] = c;
    164          1.1     skrll 	    register_chars[c] = c;
    165          1.1     skrll 	  }
    166          1.1     skrll 	else if (ISUPPER (c))
    167          1.1     skrll 	  {
    168          1.1     skrll 	    opcode_chars[c] = TOLOWER (c);
    169          1.1     skrll 	    register_chars[c] = opcode_chars[c];
    170          1.1     skrll 	  }
    171          1.1     skrll 	else if (c == ')' || c == '(')
    172          1.1     skrll 	  register_chars[c] = c;
    173          1.1     skrll 
    174          1.1     skrll 	if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
    175          1.1     skrll 	  operand_chars[c] = c;
    176          1.1     skrll 
    177          1.1     skrll 	if (ISDIGIT (c) || c == '-')
    178          1.1     skrll 	  digit_chars[c] = c;
    179          1.1     skrll 
    180          1.1     skrll 	if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
    181          1.1     skrll 	  identifier_chars[c] = c;
    182          1.1     skrll 
    183          1.1     skrll 	if (c == ' ' || c == '\t')
    184          1.1     skrll 	  space_chars[c] = c;
    185          1.1     skrll 
    186          1.1     skrll 	if (c == '_')
    187          1.1     skrll 	  opcode_chars[c] = c;
    188          1.1     skrll       }
    189          1.1     skrll     for (p = operand_special_chars; *p != '\0'; p++)
    190          1.1     skrll       operand_chars[(unsigned char) *p] = *p;
    191          1.1     skrll   }
    192          1.1     skrll }
    193          1.1     skrll 
    194          1.1     skrll /* Address Mode OR values.  */
    195          1.1     skrll #define AM_Register  0x00000000
    196          1.1     skrll #define AM_Direct    0x00200000
    197          1.1     skrll #define AM_Indirect  0x00400000
    198          1.1     skrll #define AM_Immediate 0x00600000
    199          1.1     skrll #define AM_NotReq    0xFFFFFFFF
    200          1.1     skrll 
    201          1.1     skrll /* PC Relative OR values.  */
    202          1.1     skrll #define PC_Register 0x00000000
    203          1.1     skrll #define PC_Relative 0x02000000
    204          1.1     skrll 
    205          1.1     skrll typedef struct
    206          1.1     skrll {
    207          1.1     skrll   unsigned op_type;
    208          1.1     skrll   struct
    209          1.1     skrll   {
    210          1.1     skrll     int resolved;
    211          1.1     skrll     unsigned address;
    212          1.1     skrll     char *label;
    213          1.1     skrll     expressionS direct_expr;
    214          1.1     skrll   } direct;
    215          1.1     skrll   struct
    216          1.1     skrll   {
    217          1.1     skrll     unsigned mod;
    218          1.1     skrll     int ARnum;
    219          1.1     skrll     unsigned char disp;
    220          1.1     skrll   } indirect;
    221          1.1     skrll   struct
    222          1.1     skrll   {
    223          1.1     skrll     unsigned opcode;
    224          1.1     skrll   } reg;
    225          1.1     skrll   struct
    226          1.1     skrll   {
    227          1.1     skrll     int resolved;
    228          1.1     skrll     int decimal_found;
    229          1.1     skrll     float f_number;
    230          1.1     skrll     int s_number;
    231          1.1     skrll     unsigned int u_number;
    232          1.1     skrll     char *label;
    233          1.1     skrll     expressionS imm_expr;
    234          1.1     skrll   } immediate;
    235          1.1     skrll } operand;
    236          1.1     skrll 
    237      1.1.1.2  christos insn_template *opcode;
    238          1.1     skrll 
    239          1.1     skrll struct tic30_insn
    240          1.1     skrll {
    241      1.1.1.2  christos   insn_template *tm;		/* Template of current instruction.  */
    242          1.1     skrll   unsigned opcode;		/* Final opcode.  */
    243          1.1     skrll   unsigned int operands;	/* Number of given operands.  */
    244          1.1     skrll   /* Type of operand given in instruction.  */
    245          1.1     skrll   operand *operand_type[MAX_OPERANDS];
    246          1.1     skrll   unsigned addressing_mode;	/* Final addressing mode of instruction.  */
    247          1.1     skrll };
    248          1.1     skrll 
    249          1.1     skrll struct tic30_insn insn;
    250          1.1     skrll static int found_parallel_insn;
    251          1.1     skrll 
    252          1.1     skrll static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
    253          1.1     skrll 
    254          1.1     skrll static char *
    255          1.1     skrll output_invalid (char c)
    256          1.1     skrll {
    257          1.1     skrll   if (ISPRINT (c))
    258          1.1     skrll     snprintf (output_invalid_buf, sizeof (output_invalid_buf),
    259          1.1     skrll 	      "'%c'", c);
    260          1.1     skrll   else
    261      1.1.1.4  christos     snprintf (output_invalid_buf, sizeof (output_invalid_buf),
    262          1.1     skrll 	      "(0x%x)", (unsigned char) c);
    263          1.1     skrll   return output_invalid_buf;
    264          1.1     skrll }
    265          1.1     skrll 
    266          1.1     skrll /* next_line points to the next line after the current instruction
    267          1.1     skrll    (current_line).  Search for the parallel bars, and if found, merge two
    268          1.1     skrll    lines into internal syntax for a parallel instruction:
    269          1.1     skrll      q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
    270          1.1     skrll    By this stage, all comments are scrubbed, and only the bare lines are
    271          1.1     skrll    given.  */
    272          1.1     skrll 
    273          1.1     skrll #define NONE           0
    274          1.1     skrll #define START_OPCODE   1
    275          1.1     skrll #define END_OPCODE     2
    276          1.1     skrll #define START_OPERANDS 3
    277          1.1     skrll #define END_OPERANDS   4
    278          1.1     skrll 
    279          1.1     skrll static char *
    280          1.1     skrll tic30_find_parallel_insn (char *current_line, char *next_line)
    281          1.1     skrll {
    282          1.1     skrll   int found_parallel = 0;
    283          1.1     skrll   char first_opcode[256];
    284          1.1     skrll   char second_opcode[256];
    285          1.1     skrll   char first_operands[256];
    286          1.1     skrll   char second_operands[256];
    287          1.1     skrll   char *parallel_insn;
    288          1.1     skrll 
    289          1.1     skrll   debug ("In tic30_find_parallel_insn()\n");
    290          1.1     skrll   while (!is_end_of_line[(unsigned char) *next_line])
    291          1.1     skrll     {
    292          1.1     skrll       if (*next_line == PARALLEL_SEPARATOR
    293          1.1     skrll 	  && *(next_line + 1) == PARALLEL_SEPARATOR)
    294          1.1     skrll 	{
    295          1.1     skrll 	  found_parallel = 1;
    296          1.1     skrll 	  next_line++;
    297          1.1     skrll 	  break;
    298          1.1     skrll 	}
    299          1.1     skrll       next_line++;
    300          1.1     skrll     }
    301          1.1     skrll   if (!found_parallel)
    302          1.1     skrll     return NULL;
    303          1.1     skrll   debug ("Found a parallel instruction\n");
    304          1.1     skrll 
    305          1.1     skrll   {
    306          1.1     skrll     int i;
    307      1.1.1.2  christos     char *op, *operands, *line;
    308          1.1     skrll 
    309          1.1     skrll     for (i = 0; i < 2; i++)
    310          1.1     skrll       {
    311          1.1     skrll 	if (i == 0)
    312          1.1     skrll 	  {
    313      1.1.1.2  christos 	    op = &first_opcode[0];
    314          1.1     skrll 	    operands = &first_operands[0];
    315          1.1     skrll 	    line = current_line;
    316          1.1     skrll 	  }
    317          1.1     skrll 	else
    318          1.1     skrll 	  {
    319      1.1.1.2  christos 	    op = &second_opcode[0];
    320          1.1     skrll 	    operands = &second_operands[0];
    321          1.1     skrll 	    line = next_line;
    322          1.1     skrll 	  }
    323          1.1     skrll 
    324          1.1     skrll 	{
    325          1.1     skrll 	  int search_status = NONE;
    326          1.1     skrll 	  int char_ptr = 0;
    327          1.1     skrll 	  char c;
    328          1.1     skrll 
    329          1.1     skrll 	  while (!is_end_of_line[(unsigned char) (c = *line)])
    330          1.1     skrll 	    {
    331          1.1     skrll 	      if (is_opcode_char (c) && search_status == NONE)
    332          1.1     skrll 		{
    333      1.1.1.2  christos 		  op[char_ptr++] = TOLOWER (c);
    334          1.1     skrll 		  search_status = START_OPCODE;
    335          1.1     skrll 		}
    336          1.1     skrll 	      else if (is_opcode_char (c) && search_status == START_OPCODE)
    337      1.1.1.2  christos 		op[char_ptr++] = TOLOWER (c);
    338          1.1     skrll 	      else if (!is_opcode_char (c) && search_status == START_OPCODE)
    339          1.1     skrll 		{
    340      1.1.1.2  christos 		  op[char_ptr] = '\0';
    341          1.1     skrll 		  char_ptr = 0;
    342          1.1     skrll 		  search_status = END_OPCODE;
    343          1.1     skrll 		}
    344          1.1     skrll 	      else if (is_operand_char (c) && search_status == START_OPERANDS)
    345          1.1     skrll 		operands[char_ptr++] = c;
    346          1.1     skrll 
    347          1.1     skrll 	      if (is_operand_char (c) && search_status == END_OPCODE)
    348          1.1     skrll 		{
    349          1.1     skrll 		  operands[char_ptr++] = c;
    350          1.1     skrll 		  search_status = START_OPERANDS;
    351          1.1     skrll 		}
    352          1.1     skrll 
    353          1.1     skrll 	      line++;
    354          1.1     skrll 	    }
    355          1.1     skrll 	  if (search_status != START_OPERANDS)
    356          1.1     skrll 	    return NULL;
    357          1.1     skrll 	  operands[char_ptr] = '\0';
    358          1.1     skrll 	}
    359          1.1     skrll       }
    360          1.1     skrll   }
    361      1.1.1.5  christos 
    362      1.1.1.5  christos   parallel_insn = concat ("q_", first_opcode, "_", second_opcode, " ",
    363      1.1.1.5  christos 			  first_operands, " | ", second_operands,
    364      1.1.1.5  christos 			  (char *) NULL);
    365          1.1     skrll   debug ("parallel insn = %s\n", parallel_insn);
    366          1.1     skrll   return parallel_insn;
    367          1.1     skrll }
    368          1.1     skrll 
    369          1.1     skrll #undef NONE
    370          1.1     skrll #undef START_OPCODE
    371          1.1     skrll #undef END_OPCODE
    372          1.1     skrll #undef START_OPERANDS
    373          1.1     skrll #undef END_OPERANDS
    374          1.1     skrll 
    375          1.1     skrll static operand *
    376          1.1     skrll tic30_operand (char *token)
    377          1.1     skrll {
    378          1.1     skrll   unsigned int count;
    379          1.1     skrll   operand *current_op;
    380          1.1     skrll 
    381          1.1     skrll   debug ("In tic30_operand with %s\n", token);
    382      1.1.1.5  christos   current_op = XCNEW (operand);
    383          1.1     skrll 
    384          1.1     skrll   if (*token == DIRECT_REFERENCE)
    385          1.1     skrll     {
    386          1.1     skrll       char *token_posn = token + 1;
    387          1.1     skrll       int direct_label = 0;
    388          1.1     skrll 
    389          1.1     skrll       debug ("Found direct reference\n");
    390          1.1     skrll       while (*token_posn)
    391          1.1     skrll 	{
    392          1.1     skrll 	  if (!is_digit_char (*token_posn))
    393          1.1     skrll 	    direct_label = 1;
    394          1.1     skrll 	  token_posn++;
    395          1.1     skrll 	}
    396          1.1     skrll 
    397          1.1     skrll       if (direct_label)
    398          1.1     skrll 	{
    399          1.1     skrll 	  char *save_input_line_pointer;
    400          1.1     skrll 	  segT retval;
    401          1.1     skrll 
    402          1.1     skrll 	  debug ("Direct reference is a label\n");
    403          1.1     skrll 	  current_op->direct.label = token + 1;
    404          1.1     skrll 	  save_input_line_pointer = input_line_pointer;
    405          1.1     skrll 	  input_line_pointer = token + 1;
    406          1.1     skrll 	  debug ("Current input_line_pointer: %s\n", input_line_pointer);
    407          1.1     skrll 	  retval = expression (&current_op->direct.direct_expr);
    408          1.1     skrll 
    409          1.1     skrll 	  debug ("Expression type: %d\n",
    410          1.1     skrll 		 current_op->direct.direct_expr.X_op);
    411          1.1     skrll 	  debug ("Expression addnum: %ld\n",
    412          1.1     skrll 		 (long) current_op->direct.direct_expr.X_add_number);
    413          1.1     skrll 	  debug ("Segment: %p\n", retval);
    414          1.1     skrll 
    415          1.1     skrll 	  input_line_pointer = save_input_line_pointer;
    416          1.1     skrll 
    417          1.1     skrll 	  if (current_op->direct.direct_expr.X_op == O_constant)
    418          1.1     skrll 	    {
    419          1.1     skrll 	      current_op->direct.address =
    420          1.1     skrll 		current_op->direct.direct_expr.X_add_number;
    421          1.1     skrll 	      current_op->direct.resolved = 1;
    422          1.1     skrll 	    }
    423          1.1     skrll 	}
    424          1.1     skrll       else
    425          1.1     skrll 	{
    426          1.1     skrll 	  debug ("Direct reference is a number\n");
    427          1.1     skrll 	  current_op->direct.address = atoi (token + 1);
    428          1.1     skrll 	  current_op->direct.resolved = 1;
    429          1.1     skrll 	}
    430          1.1     skrll       current_op->op_type = Direct;
    431          1.1     skrll     }
    432          1.1     skrll   else if (*token == INDIRECT_REFERENCE)
    433          1.1     skrll     {
    434          1.1     skrll       /* Indirect reference operand.  */
    435          1.1     skrll       int found_ar = 0;
    436          1.1     skrll       int found_disp = 0;
    437          1.1     skrll       int ar_number = -1;
    438          1.1     skrll       int disp_number = 0;
    439          1.1     skrll       int buffer_posn = 1;
    440          1.1     skrll       ind_addr_type *ind_addr_op;
    441      1.1.1.5  christos       char * ind_buffer;
    442      1.1.1.5  christos 
    443      1.1.1.5  christos       ind_buffer = XNEWVEC (char, strlen (token));
    444          1.1     skrll 
    445          1.1     skrll       debug ("Found indirect reference\n");
    446          1.1     skrll       ind_buffer[0] = *token;
    447          1.1     skrll 
    448          1.1     skrll       for (count = 1; count < strlen (token); count++)
    449          1.1     skrll 	{
    450          1.1     skrll 	  /* Strip operand.  */
    451          1.1     skrll 	  ind_buffer[buffer_posn] = TOLOWER (*(token + count));
    452          1.1     skrll 
    453          1.1     skrll 	  if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
    454          1.1     skrll 	      && (*(token + count) == 'r' || *(token + count) == 'R'))
    455          1.1     skrll 	    {
    456          1.1     skrll 	      /* AR reference is found, so get its number and remove
    457      1.1.1.8  christos 		 it from the buffer so it can pass through str_hash_find().  */
    458          1.1     skrll 	      if (found_ar)
    459          1.1     skrll 		{
    460      1.1.1.2  christos 		  as_bad (_("More than one AR register found in indirect reference"));
    461      1.1.1.5  christos 		  free (ind_buffer);
    462          1.1     skrll 		  return NULL;
    463          1.1     skrll 		}
    464          1.1     skrll 	      if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
    465          1.1     skrll 		{
    466      1.1.1.2  christos 		  as_bad (_("Illegal AR register in indirect reference"));
    467      1.1.1.5  christos 		  free (ind_buffer);
    468          1.1     skrll 		  return NULL;
    469          1.1     skrll 		}
    470          1.1     skrll 	      ar_number = *(token + count + 1) - '0';
    471          1.1     skrll 	      found_ar = 1;
    472          1.1     skrll 	      count++;
    473          1.1     skrll 	    }
    474          1.1     skrll 
    475          1.1     skrll 	  if (*(token + count) == '(')
    476          1.1     skrll 	    {
    477          1.1     skrll 	      /* Parenthesis found, so check if a displacement value is
    478          1.1     skrll 		 inside.  If so, get the value and remove it from the
    479          1.1     skrll 		 buffer.  */
    480          1.1     skrll 	      if (is_digit_char (*(token + count + 1)))
    481          1.1     skrll 		{
    482          1.1     skrll 		  char disp[10];
    483          1.1     skrll 		  int disp_posn = 0;
    484          1.1     skrll 
    485          1.1     skrll 		  if (found_disp)
    486          1.1     skrll 		    {
    487      1.1.1.2  christos 		      as_bad (_("More than one displacement found in indirect reference"));
    488      1.1.1.5  christos 		      free (ind_buffer);
    489          1.1     skrll 		      return NULL;
    490          1.1     skrll 		    }
    491          1.1     skrll 		  count++;
    492          1.1     skrll 		  while (*(token + count) != ')')
    493          1.1     skrll 		    {
    494          1.1     skrll 		      if (!is_digit_char (*(token + count)))
    495          1.1     skrll 			{
    496      1.1.1.2  christos 			  as_bad (_("Invalid displacement in indirect reference"));
    497      1.1.1.5  christos 			  free (ind_buffer);
    498          1.1     skrll 			  return NULL;
    499          1.1     skrll 			}
    500          1.1     skrll 		      disp[disp_posn++] = *(token + (count++));
    501          1.1     skrll 		    }
    502          1.1     skrll 		  disp[disp_posn] = '\0';
    503          1.1     skrll 		  disp_number = atoi (disp);
    504          1.1     skrll 		  count--;
    505          1.1     skrll 		  found_disp = 1;
    506          1.1     skrll 		}
    507          1.1     skrll 	    }
    508          1.1     skrll 	  buffer_posn++;
    509          1.1     skrll 	}
    510          1.1     skrll 
    511          1.1     skrll       ind_buffer[buffer_posn] = '\0';
    512          1.1     skrll       if (!found_ar)
    513          1.1     skrll 	{
    514      1.1.1.2  christos 	  as_bad (_("AR register not found in indirect reference"));
    515      1.1.1.5  christos 	  free (ind_buffer);
    516          1.1     skrll 	  return NULL;
    517          1.1     skrll 	}
    518          1.1     skrll 
    519      1.1.1.8  christos       ind_addr_op = (ind_addr_type *) str_hash_find (ind_hash, ind_buffer);
    520          1.1     skrll       if (ind_addr_op)
    521          1.1     skrll 	{
    522          1.1     skrll 	  debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
    523          1.1     skrll 	  if (ind_addr_op->displacement == IMPLIED_DISP)
    524          1.1     skrll 	    {
    525          1.1     skrll 	      found_disp = 1;
    526          1.1     skrll 	      disp_number = 1;
    527          1.1     skrll 	    }
    528          1.1     skrll 	  else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
    529          1.1     skrll 	    {
    530          1.1     skrll 	      /* Maybe an implied displacement of 1 again.  */
    531      1.1.1.2  christos 	      as_bad (_("required displacement wasn't given in indirect reference"));
    532      1.1.1.5  christos 	      free (ind_buffer);
    533      1.1.1.5  christos 	      return NULL;
    534          1.1     skrll 	    }
    535          1.1     skrll 	}
    536          1.1     skrll       else
    537          1.1     skrll 	{
    538      1.1.1.2  christos 	  as_bad (_("illegal indirect reference"));
    539      1.1.1.5  christos 	  free (ind_buffer);
    540          1.1     skrll 	  return NULL;
    541          1.1     skrll 	}
    542          1.1     skrll 
    543          1.1     skrll       if (found_disp && (disp_number < 0 || disp_number > 255))
    544          1.1     skrll 	{
    545      1.1.1.2  christos 	  as_bad (_("displacement must be an unsigned 8-bit number"));
    546      1.1.1.5  christos 	  free (ind_buffer);
    547          1.1     skrll 	  return NULL;
    548          1.1     skrll 	}
    549          1.1     skrll 
    550          1.1     skrll       current_op->indirect.mod = ind_addr_op->modfield;
    551          1.1     skrll       current_op->indirect.disp = disp_number;
    552          1.1     skrll       current_op->indirect.ARnum = ar_number;
    553          1.1     skrll       current_op->op_type = Indirect;
    554      1.1.1.5  christos       free (ind_buffer);
    555          1.1     skrll     }
    556          1.1     skrll   else
    557          1.1     skrll     {
    558      1.1.1.8  christos       reg *regop = (reg *) str_hash_find (reg_hash, token);
    559          1.1     skrll 
    560          1.1     skrll       if (regop)
    561          1.1     skrll 	{
    562          1.1     skrll 	  debug ("Found register operand: %s\n", regop->name);
    563          1.1     skrll 	  if (regop->regtype == REG_ARn)
    564          1.1     skrll 	    current_op->op_type = ARn;
    565          1.1     skrll 	  else if (regop->regtype == REG_Rn)
    566          1.1     skrll 	    current_op->op_type = Rn;
    567          1.1     skrll 	  else if (regop->regtype == REG_DP)
    568          1.1     skrll 	    current_op->op_type = DPReg;
    569          1.1     skrll 	  else
    570          1.1     skrll 	    current_op->op_type = OtherReg;
    571          1.1     skrll 	  current_op->reg.opcode = regop->opcode;
    572          1.1     skrll 	}
    573          1.1     skrll       else
    574          1.1     skrll 	{
    575          1.1     skrll 	  if (!is_digit_char (*token)
    576          1.1     skrll 	      || *(token + 1) == 'x'
    577          1.1     skrll 	      || strchr (token, 'h'))
    578          1.1     skrll 	    {
    579          1.1     skrll 	      char *save_input_line_pointer;
    580          1.1     skrll 	      segT retval;
    581          1.1     skrll 
    582          1.1     skrll 	      debug ("Probably a label: %s\n", token);
    583      1.1.1.5  christos 	      current_op->immediate.label = xstrdup (token);
    584          1.1     skrll 	      save_input_line_pointer = input_line_pointer;
    585          1.1     skrll 	      input_line_pointer = token;
    586          1.1     skrll 
    587          1.1     skrll 	      debug ("Current input_line_pointer: %s\n", input_line_pointer);
    588          1.1     skrll 	      retval = expression (&current_op->immediate.imm_expr);
    589          1.1     skrll 	      debug ("Expression type: %d\n",
    590          1.1     skrll 		     current_op->immediate.imm_expr.X_op);
    591          1.1     skrll 	      debug ("Expression addnum: %ld\n",
    592          1.1     skrll 		     (long) current_op->immediate.imm_expr.X_add_number);
    593          1.1     skrll 	      debug ("Segment: %p\n", retval);
    594          1.1     skrll 	      input_line_pointer = save_input_line_pointer;
    595          1.1     skrll 
    596          1.1     skrll 	      if (current_op->immediate.imm_expr.X_op == O_constant)
    597          1.1     skrll 		{
    598          1.1     skrll 		  current_op->immediate.s_number
    599          1.1     skrll 		    = current_op->immediate.imm_expr.X_add_number;
    600          1.1     skrll 		  current_op->immediate.u_number
    601          1.1     skrll 		    = (unsigned int) current_op->immediate.imm_expr.X_add_number;
    602          1.1     skrll 		  current_op->immediate.resolved = 1;
    603          1.1     skrll 		}
    604          1.1     skrll 	    }
    605          1.1     skrll 	  else
    606          1.1     skrll 	    {
    607          1.1     skrll 	      debug ("Found a number or displacement\n");
    608          1.1     skrll 	      for (count = 0; count < strlen (token); count++)
    609          1.1     skrll 		if (*(token + count) == '.')
    610          1.1     skrll 		  current_op->immediate.decimal_found = 1;
    611      1.1.1.5  christos 	      current_op->immediate.label = xstrdup (token);
    612          1.1     skrll 	      current_op->immediate.f_number = (float) atof (token);
    613          1.1     skrll 	      current_op->immediate.s_number = (int) atoi (token);
    614          1.1     skrll 	      current_op->immediate.u_number = (unsigned int) atoi (token);
    615          1.1     skrll 	      current_op->immediate.resolved = 1;
    616          1.1     skrll 	    }
    617          1.1     skrll 	  current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
    618          1.1     skrll 	  if (current_op->immediate.u_number <= 31)
    619          1.1     skrll 	    current_op->op_type |= IVector;
    620          1.1     skrll 	}
    621          1.1     skrll     }
    622          1.1     skrll   return current_op;
    623          1.1     skrll }
    624          1.1     skrll 
    625          1.1     skrll struct tic30_par_insn
    626          1.1     skrll {
    627          1.1     skrll   partemplate *tm;		/* Template of current parallel instruction.  */
    628          1.1     skrll   unsigned operands[2];		/* Number of given operands for each insn.  */
    629          1.1     skrll   /* Type of operand given in instruction.  */
    630          1.1     skrll   operand *operand_type[2][MAX_OPERANDS];
    631          1.1     skrll   int swap_operands;		/* Whether to swap operands around.  */
    632          1.1     skrll   unsigned p_field;		/* Value of p field in multiply add/sub instructions.  */
    633          1.1     skrll   unsigned opcode;		/* Final opcode.  */
    634          1.1     skrll };
    635          1.1     skrll 
    636          1.1     skrll struct tic30_par_insn p_insn;
    637          1.1     skrll 
    638          1.1     skrll static int
    639          1.1     skrll tic30_parallel_insn (char *token)
    640          1.1     skrll {
    641          1.1     skrll   static partemplate *p_opcode;
    642          1.1     skrll   char *current_posn = token;
    643          1.1     skrll   char *token_start;
    644          1.1     skrll   char save_char;
    645          1.1     skrll 
    646          1.1     skrll   debug ("In tic30_parallel_insn with %s\n", token);
    647          1.1     skrll   memset (&p_insn, '\0', sizeof (p_insn));
    648          1.1     skrll 
    649          1.1     skrll   while (is_opcode_char (*current_posn))
    650          1.1     skrll     current_posn++;
    651          1.1     skrll   {
    652          1.1     skrll     /* Find instruction.  */
    653          1.1     skrll     save_char = *current_posn;
    654          1.1     skrll     *current_posn = '\0';
    655      1.1.1.8  christos     p_opcode = (partemplate *) str_hash_find (parop_hash, token);
    656          1.1     skrll     if (p_opcode)
    657          1.1     skrll       {
    658          1.1     skrll 	debug ("Found instruction %s\n", p_opcode->name);
    659          1.1     skrll 	p_insn.tm = p_opcode;
    660          1.1     skrll       }
    661          1.1     skrll     else
    662          1.1     skrll       {
    663          1.1     skrll 	char first_opcode[6] = {0};
    664          1.1     skrll 	char second_opcode[6] = {0};
    665          1.1     skrll 	unsigned int i;
    666          1.1     skrll 	int current_opcode = -1;
    667          1.1     skrll 	int char_ptr = 0;
    668          1.1     skrll 
    669          1.1     skrll 	for (i = 0; i < strlen (token); i++)
    670          1.1     skrll 	  {
    671          1.1     skrll 	    char ch = *(token + i);
    672          1.1     skrll 
    673          1.1     skrll 	    if (ch == '_' && current_opcode == -1)
    674          1.1     skrll 	      {
    675          1.1     skrll 		current_opcode = 0;
    676          1.1     skrll 		continue;
    677          1.1     skrll 	      }
    678          1.1     skrll 
    679          1.1     skrll 	    if (ch == '_' && current_opcode == 0)
    680          1.1     skrll 	      {
    681          1.1     skrll 		current_opcode = 1;
    682          1.1     skrll 		char_ptr = 0;
    683          1.1     skrll 		continue;
    684          1.1     skrll 	      }
    685          1.1     skrll 
    686          1.1     skrll 	    switch (current_opcode)
    687          1.1     skrll 	      {
    688          1.1     skrll 	      case 0:
    689          1.1     skrll 		first_opcode[char_ptr++] = ch;
    690          1.1     skrll 		break;
    691          1.1     skrll 	      case 1:
    692          1.1     skrll 		second_opcode[char_ptr++] = ch;
    693          1.1     skrll 		break;
    694          1.1     skrll 	      }
    695          1.1     skrll 	  }
    696          1.1     skrll 
    697          1.1     skrll 	debug ("first_opcode = %s\n", first_opcode);
    698          1.1     skrll 	debug ("second_opcode = %s\n", second_opcode);
    699          1.1     skrll 	sprintf (token, "q_%s_%s", second_opcode, first_opcode);
    700      1.1.1.8  christos 	p_opcode = (partemplate *) str_hash_find (parop_hash, token);
    701          1.1     skrll 
    702          1.1     skrll 	if (p_opcode)
    703          1.1     skrll 	  {
    704          1.1     skrll 	    debug ("Found instruction %s\n", p_opcode->name);
    705          1.1     skrll 	    p_insn.tm = p_opcode;
    706          1.1     skrll 	    p_insn.swap_operands = 1;
    707          1.1     skrll 	  }
    708          1.1     skrll 	else
    709          1.1     skrll 	  return 0;
    710          1.1     skrll       }
    711          1.1     skrll     *current_posn = save_char;
    712          1.1     skrll   }
    713          1.1     skrll 
    714          1.1     skrll   {
    715          1.1     skrll     /* Find operands.  */
    716          1.1     skrll     int paren_not_balanced;
    717          1.1     skrll     int expecting_operand = 0;
    718          1.1     skrll     int found_separator = 0;
    719          1.1     skrll 
    720          1.1     skrll     do
    721          1.1     skrll       {
    722          1.1     skrll 	/* Skip optional white space before operand.  */
    723          1.1     skrll 	while (!is_operand_char (*current_posn)
    724          1.1     skrll 	       && *current_posn != END_OF_INSN)
    725          1.1     skrll 	  {
    726          1.1     skrll 	    if (!is_space_char (*current_posn)
    727          1.1     skrll 		&& *current_posn != PARALLEL_SEPARATOR)
    728          1.1     skrll 	      {
    729      1.1.1.2  christos 		as_bad (_("Invalid character %s before %s operand"),
    730          1.1     skrll 			output_invalid (*current_posn),
    731          1.1     skrll 			ordinal_names[insn.operands]);
    732          1.1     skrll 		return 1;
    733          1.1     skrll 	      }
    734          1.1     skrll 	    if (*current_posn == PARALLEL_SEPARATOR)
    735          1.1     skrll 	      found_separator = 1;
    736          1.1     skrll 	    current_posn++;
    737          1.1     skrll 	  }
    738          1.1     skrll 
    739          1.1     skrll 	token_start = current_posn;
    740          1.1     skrll 	paren_not_balanced = 0;
    741          1.1     skrll 
    742          1.1     skrll 	while (paren_not_balanced || *current_posn != ',')
    743          1.1     skrll 	  {
    744          1.1     skrll 	    if (*current_posn == END_OF_INSN)
    745          1.1     skrll 	      {
    746          1.1     skrll 		if (paren_not_balanced)
    747          1.1     skrll 		  {
    748      1.1.1.2  christos 		    as_bad (_("Unbalanced parenthesis in %s operand."),
    749          1.1     skrll 			    ordinal_names[insn.operands]);
    750          1.1     skrll 		    return 1;
    751          1.1     skrll 		  }
    752          1.1     skrll 		else
    753          1.1     skrll 		  break;
    754          1.1     skrll 	      }
    755          1.1     skrll 	    else if (*current_posn == PARALLEL_SEPARATOR)
    756          1.1     skrll 	      {
    757          1.1     skrll 		while (is_space_char (*(current_posn - 1)))
    758          1.1     skrll 		  current_posn--;
    759          1.1     skrll 		break;
    760          1.1     skrll 	      }
    761          1.1     skrll 	    else if (!is_operand_char (*current_posn)
    762          1.1     skrll 		     && !is_space_char (*current_posn))
    763          1.1     skrll 	      {
    764      1.1.1.2  christos 		as_bad (_("Invalid character %s in %s operand"),
    765          1.1     skrll 			output_invalid (*current_posn),
    766          1.1     skrll 			ordinal_names[insn.operands]);
    767          1.1     skrll 		return 1;
    768          1.1     skrll 	      }
    769          1.1     skrll 
    770          1.1     skrll 	    if (*current_posn == '(')
    771          1.1     skrll 	      ++paren_not_balanced;
    772          1.1     skrll 	    if (*current_posn == ')')
    773          1.1     skrll 	      --paren_not_balanced;
    774          1.1     skrll 	    current_posn++;
    775          1.1     skrll 	  }
    776          1.1     skrll 
    777          1.1     skrll 	if (current_posn != token_start)
    778          1.1     skrll 	  {
    779          1.1     skrll 	    /* Yes, we've read in another operand.  */
    780          1.1     skrll 	    p_insn.operands[found_separator]++;
    781          1.1     skrll 	    if (p_insn.operands[found_separator] > MAX_OPERANDS)
    782          1.1     skrll 	      {
    783      1.1.1.2  christos 		as_bad (_("Spurious operands; (%d operands/instruction max)"),
    784          1.1     skrll 			MAX_OPERANDS);
    785          1.1     skrll 		return 1;
    786          1.1     skrll 	      }
    787          1.1     skrll 
    788          1.1     skrll 	    /* Now parse operand adding info to 'insn' as we go along.  */
    789          1.1     skrll 	    save_char = *current_posn;
    790          1.1     skrll 	    *current_posn = '\0';
    791          1.1     skrll 	    p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
    792          1.1     skrll 	      tic30_operand (token_start);
    793          1.1     skrll 	    *current_posn = save_char;
    794          1.1     skrll 	    if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
    795          1.1     skrll 	      return 1;
    796          1.1     skrll 	  }
    797          1.1     skrll 	else
    798          1.1     skrll 	  {
    799          1.1     skrll 	    if (expecting_operand)
    800          1.1     skrll 	      {
    801      1.1.1.2  christos 		as_bad (_("Expecting operand after ','; got nothing"));
    802          1.1     skrll 		return 1;
    803          1.1     skrll 	      }
    804          1.1     skrll 	    if (*current_posn == ',')
    805          1.1     skrll 	      {
    806      1.1.1.2  christos 		as_bad (_("Expecting operand before ','; got nothing"));
    807          1.1     skrll 		return 1;
    808          1.1     skrll 	      }
    809          1.1     skrll 	  }
    810          1.1     skrll 
    811          1.1     skrll 	/* Now *current_posn must be either ',' or END_OF_INSN.  */
    812          1.1     skrll 	if (*current_posn == ',')
    813          1.1     skrll 	  {
    814          1.1     skrll 	    if (*++current_posn == END_OF_INSN)
    815          1.1     skrll 	      {
    816          1.1     skrll 		/* Just skip it, if it's \n complain.  */
    817      1.1.1.2  christos 		as_bad (_("Expecting operand after ','; got nothing"));
    818          1.1     skrll 		return 1;
    819          1.1     skrll 	      }
    820          1.1     skrll 	    expecting_operand = 1;
    821          1.1     skrll 	  }
    822          1.1     skrll       }
    823          1.1     skrll     while (*current_posn != END_OF_INSN);
    824          1.1     skrll   }
    825          1.1     skrll 
    826          1.1     skrll   if (p_insn.swap_operands)
    827          1.1     skrll     {
    828          1.1     skrll       int temp_num, i;
    829          1.1     skrll       operand *temp_op;
    830          1.1     skrll 
    831          1.1     skrll       temp_num = p_insn.operands[0];
    832          1.1     skrll       p_insn.operands[0] = p_insn.operands[1];
    833          1.1     skrll       p_insn.operands[1] = temp_num;
    834          1.1     skrll       for (i = 0; i < MAX_OPERANDS; i++)
    835          1.1     skrll 	{
    836          1.1     skrll 	  temp_op = p_insn.operand_type[0][i];
    837          1.1     skrll 	  p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
    838          1.1     skrll 	  p_insn.operand_type[1][i] = temp_op;
    839          1.1     skrll 	}
    840          1.1     skrll     }
    841          1.1     skrll 
    842          1.1     skrll   if (p_insn.operands[0] != p_insn.tm->operands_1)
    843          1.1     skrll     {
    844      1.1.1.2  christos       as_bad (_("incorrect number of operands given in the first instruction"));
    845          1.1     skrll       return 1;
    846          1.1     skrll     }
    847          1.1     skrll 
    848          1.1     skrll   if (p_insn.operands[1] != p_insn.tm->operands_2)
    849          1.1     skrll     {
    850      1.1.1.2  christos       as_bad (_("incorrect number of operands given in the second instruction"));
    851          1.1     skrll       return 1;
    852          1.1     skrll     }
    853          1.1     skrll 
    854          1.1     skrll   debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
    855          1.1     skrll   debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
    856          1.1     skrll 
    857          1.1     skrll   {
    858          1.1     skrll     /* Now check if operands are correct.  */
    859          1.1     skrll     int count;
    860          1.1     skrll     int num_rn = 0;
    861          1.1     skrll     int num_ind = 0;
    862          1.1     skrll 
    863          1.1     skrll     for (count = 0; count < 2; count++)
    864          1.1     skrll       {
    865          1.1     skrll 	unsigned int i;
    866          1.1     skrll 	for (i = 0; i < p_insn.operands[count]; i++)
    867          1.1     skrll 	  {
    868          1.1     skrll 	    if ((p_insn.operand_type[count][i]->op_type &
    869          1.1     skrll 		 p_insn.tm->operand_types[count][i]) == 0)
    870          1.1     skrll 	      {
    871      1.1.1.2  christos 		as_bad (_("%s instruction, operand %d doesn't match"),
    872          1.1     skrll 			ordinal_names[count], i + 1);
    873          1.1     skrll 		return 1;
    874          1.1     skrll 	      }
    875          1.1     skrll 
    876          1.1     skrll 	    /* Get number of R register and indirect reference contained
    877          1.1     skrll 	       within the first two operands of each instruction.  This is
    878          1.1     skrll 	       required for the multiply parallel instructions which require
    879          1.1     skrll 	       two R registers and two indirect references, but not in any
    880          1.1     skrll 	       particular place.  */
    881          1.1     skrll 	    if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
    882          1.1     skrll 	      num_rn++;
    883          1.1     skrll 	    else if ((p_insn.operand_type[count][i]->op_type & Indirect)
    884          1.1     skrll 		     && i < 2)
    885          1.1     skrll 	      num_ind++;
    886          1.1     skrll 	  }
    887          1.1     skrll       }
    888          1.1     skrll 
    889          1.1     skrll     if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
    890          1.1     skrll 	== (Indirect | Rn))
    891          1.1     skrll       {
    892          1.1     skrll 	/* Check for the multiply instructions.  */
    893          1.1     skrll 	if (num_rn != 2)
    894          1.1     skrll 	  {
    895      1.1.1.2  christos 	    as_bad (_("incorrect format for multiply parallel instruction"));
    896          1.1     skrll 	    return 1;
    897          1.1     skrll 	  }
    898          1.1     skrll 
    899          1.1     skrll 	if (num_ind != 2)
    900          1.1     skrll 	  {
    901          1.1     skrll 	    /* Shouldn't get here.  */
    902      1.1.1.2  christos 	    as_bad (_("incorrect format for multiply parallel instruction"));
    903          1.1     skrll 	    return 1;
    904          1.1     skrll 	  }
    905          1.1     skrll 
    906          1.1     skrll 	if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
    907          1.1     skrll 	    && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
    908          1.1     skrll 	  {
    909      1.1.1.2  christos 	    as_bad (_("destination for multiply can only be R0 or R1"));
    910          1.1     skrll 	    return 1;
    911          1.1     skrll 	  }
    912          1.1     skrll 
    913          1.1     skrll 	if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
    914          1.1     skrll 	    && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
    915          1.1     skrll 	  {
    916      1.1.1.2  christos 	    as_bad (_("destination for add/subtract can only be R2 or R3"));
    917          1.1     skrll 	    return 1;
    918          1.1     skrll 	  }
    919          1.1     skrll 
    920          1.1     skrll 	/* Now determine the P field for the instruction.  */
    921          1.1     skrll 	if (p_insn.operand_type[0][0]->op_type & Indirect)
    922          1.1     skrll 	  {
    923          1.1     skrll 	    if (p_insn.operand_type[0][1]->op_type & Indirect)
    924          1.1     skrll 	      p_insn.p_field = 0x00000000;	/* Ind * Ind, Rn  +/- Rn.  */
    925          1.1     skrll 	    else if (p_insn.operand_type[1][0]->op_type & Indirect)
    926          1.1     skrll 	      p_insn.p_field = 0x01000000;	/* Ind * Rn,  Ind +/- Rn.  */
    927          1.1     skrll 	    else
    928          1.1     skrll 	      p_insn.p_field = 0x03000000;	/* Ind * Rn,  Rn  +/- Ind.  */
    929          1.1     skrll 	  }
    930          1.1     skrll 	else
    931          1.1     skrll 	  {
    932          1.1     skrll 	    if (p_insn.operand_type[0][1]->op_type & Rn)
    933          1.1     skrll 	      p_insn.p_field = 0x02000000;	/* Rn  * Rn,  Ind +/- Ind.  */
    934          1.1     skrll 	    else if (p_insn.operand_type[1][0]->op_type & Indirect)
    935          1.1     skrll 	      {
    936          1.1     skrll 		operand *temp;
    937          1.1     skrll 		p_insn.p_field = 0x01000000;	/* Rn  * Ind, Ind +/- Rn.  */
    938          1.1     skrll 		/* Need to swap the two multiply operands around so that
    939          1.1     skrll 		   everything is in its place for the opcode makeup.
    940          1.1     skrll 		   ie so Ind * Rn, Ind +/- Rn.  */
    941          1.1     skrll 		temp = p_insn.operand_type[0][0];
    942          1.1     skrll 		p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
    943          1.1     skrll 		p_insn.operand_type[0][1] = temp;
    944          1.1     skrll 	      }
    945          1.1     skrll 	    else
    946          1.1     skrll 	      {
    947          1.1     skrll 		operand *temp;
    948          1.1     skrll 		p_insn.p_field = 0x03000000;	/* Rn  * Ind, Rn  +/- Ind.  */
    949          1.1     skrll 		temp = p_insn.operand_type[0][0];
    950          1.1     skrll 		p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
    951          1.1     skrll 		p_insn.operand_type[0][1] = temp;
    952          1.1     skrll 	      }
    953          1.1     skrll 	  }
    954          1.1     skrll       }
    955          1.1     skrll   }
    956          1.1     skrll 
    957          1.1     skrll   debug ("P field: %08X\n", p_insn.p_field);
    958          1.1     skrll 
    959          1.1     skrll   /* Finalise opcode.  This is easier for parallel instructions as they have
    960          1.1     skrll      to be fully resolved, there are no memory addresses allowed, except
    961          1.1     skrll      through indirect addressing, so there are no labels to resolve.  */
    962          1.1     skrll   p_insn.opcode = p_insn.tm->base_opcode;
    963          1.1     skrll 
    964          1.1     skrll   switch (p_insn.tm->oporder)
    965          1.1     skrll     {
    966          1.1     skrll     case OO_4op1:
    967          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
    968          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
    969          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
    970          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
    971          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
    972          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
    973          1.1     skrll       break;
    974          1.1     skrll 
    975          1.1     skrll     case OO_4op2:
    976          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
    977          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
    978          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
    979          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
    980          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
    981          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
    982          1.1     skrll       if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
    983      1.1.1.2  christos 	as_warn (_("loading the same register in parallel operation"));
    984          1.1     skrll       break;
    985          1.1     skrll 
    986          1.1     skrll     case OO_4op3:
    987          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
    988          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
    989          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
    990          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
    991          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
    992          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
    993          1.1     skrll       break;
    994          1.1     skrll 
    995          1.1     skrll     case OO_5op1:
    996          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
    997          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
    998          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
    999          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
   1000          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
   1001          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
   1002          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
   1003          1.1     skrll       break;
   1004          1.1     skrll 
   1005          1.1     skrll     case OO_5op2:
   1006          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
   1007          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
   1008          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
   1009          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
   1010          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
   1011          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
   1012          1.1     skrll       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
   1013          1.1     skrll       break;
   1014          1.1     skrll 
   1015          1.1     skrll     case OO_PField:
   1016          1.1     skrll       p_insn.opcode |= p_insn.p_field;
   1017          1.1     skrll       if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
   1018          1.1     skrll 	p_insn.opcode |= 0x00800000;
   1019          1.1     skrll       if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
   1020          1.1     skrll 	p_insn.opcode |= 0x00400000;
   1021          1.1     skrll 
   1022          1.1     skrll       switch (p_insn.p_field)
   1023          1.1     skrll 	{
   1024          1.1     skrll 	case 0x00000000:
   1025          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
   1026          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
   1027          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
   1028          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
   1029          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
   1030          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
   1031          1.1     skrll 	  break;
   1032          1.1     skrll 	case 0x01000000:
   1033          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
   1034          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
   1035          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
   1036          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
   1037          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
   1038          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
   1039          1.1     skrll 	  break;
   1040          1.1     skrll 	case 0x02000000:
   1041          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
   1042          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
   1043          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
   1044          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
   1045          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
   1046          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
   1047          1.1     skrll 	  break;
   1048          1.1     skrll 	case 0x03000000:
   1049          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
   1050          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
   1051          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
   1052          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
   1053          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
   1054          1.1     skrll 	  p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
   1055          1.1     skrll 	  break;
   1056          1.1     skrll 	}
   1057          1.1     skrll       break;
   1058          1.1     skrll     }
   1059          1.1     skrll 
   1060          1.1     skrll   {
   1061          1.1     skrll     char *p;
   1062          1.1     skrll 
   1063          1.1     skrll     p = frag_more (INSN_SIZE);
   1064          1.1     skrll     md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
   1065          1.1     skrll   }
   1066          1.1     skrll 
   1067          1.1     skrll   {
   1068          1.1     skrll     unsigned int i, j;
   1069          1.1     skrll 
   1070          1.1     skrll     for (i = 0; i < 2; i++)
   1071          1.1     skrll       for (j = 0; j < p_insn.operands[i]; j++)
   1072          1.1     skrll 	free (p_insn.operand_type[i][j]);
   1073          1.1     skrll   }
   1074          1.1     skrll 
   1075          1.1     skrll   debug ("Final opcode: %08X\n", p_insn.opcode);
   1076          1.1     skrll   debug ("\n");
   1077          1.1     skrll 
   1078          1.1     skrll   return 1;
   1079          1.1     skrll }
   1080          1.1     skrll 
   1081          1.1     skrll /* In order to get gas to ignore any | chars at the start of a line,
   1082          1.1     skrll    this function returns true if a | is found in a line.  */
   1083          1.1     skrll 
   1084          1.1     skrll int
   1085          1.1     skrll tic30_unrecognized_line (int c)
   1086          1.1     skrll {
   1087          1.1     skrll   debug ("In tc_unrecognized_line\n");
   1088          1.1     skrll   return (c == PARALLEL_SEPARATOR);
   1089          1.1     skrll }
   1090          1.1     skrll 
   1091          1.1     skrll int
   1092          1.1     skrll md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
   1093          1.1     skrll 			       segT segment ATTRIBUTE_UNUSED)
   1094          1.1     skrll {
   1095          1.1     skrll   debug ("In md_estimate_size_before_relax()\n");
   1096          1.1     skrll   return 0;
   1097          1.1     skrll }
   1098          1.1     skrll 
   1099          1.1     skrll void
   1100          1.1     skrll md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   1101          1.1     skrll 		 segT sec ATTRIBUTE_UNUSED,
   1102      1.1.1.4  christos 		 fragS *fragP ATTRIBUTE_UNUSED)
   1103          1.1     skrll {
   1104          1.1     skrll   debug ("In md_convert_frag()\n");
   1105          1.1     skrll }
   1106          1.1     skrll 
   1107          1.1     skrll void
   1108          1.1     skrll md_apply_fix (fixS *fixP,
   1109          1.1     skrll 	       valueT *valP,
   1110          1.1     skrll 	       segT seg ATTRIBUTE_UNUSED)
   1111          1.1     skrll {
   1112          1.1     skrll   valueT value = *valP;
   1113          1.1     skrll 
   1114          1.1     skrll   debug ("In md_apply_fix() with value = %ld\n", (long) value);
   1115          1.1     skrll   debug ("Values in fixP\n");
   1116          1.1     skrll   debug ("fx_size = %d\n", fixP->fx_size);
   1117          1.1     skrll   debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
   1118          1.1     skrll   debug ("fx_where = %ld\n", fixP->fx_where);
   1119          1.1     skrll   debug ("fx_offset = %d\n", (int) fixP->fx_offset);
   1120          1.1     skrll   {
   1121          1.1     skrll     char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
   1122          1.1     skrll 
   1123          1.1     skrll     value /= INSN_SIZE;
   1124          1.1     skrll     if (fixP->fx_size == 1)
   1125          1.1     skrll       /* Special fix for LDP instruction.  */
   1126          1.1     skrll       value = (value & 0x00FF0000) >> 16;
   1127          1.1     skrll 
   1128          1.1     skrll     debug ("new value = %ld\n", (long) value);
   1129          1.1     skrll     md_number_to_chars (buf, value, fixP->fx_size);
   1130          1.1     skrll   }
   1131          1.1     skrll 
   1132          1.1     skrll   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
   1133          1.1     skrll     fixP->fx_done = 1;
   1134          1.1     skrll }
   1135          1.1     skrll 
   1136          1.1     skrll int
   1137          1.1     skrll md_parse_option (int c ATTRIBUTE_UNUSED,
   1138      1.1.1.5  christos 		 const char *arg ATTRIBUTE_UNUSED)
   1139          1.1     skrll {
   1140          1.1     skrll   debug ("In md_parse_option()\n");
   1141          1.1     skrll   return 0;
   1142          1.1     skrll }
   1143          1.1     skrll 
   1144          1.1     skrll void
   1145          1.1     skrll md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
   1146          1.1     skrll {
   1147          1.1     skrll   debug ("In md_show_usage()\n");
   1148          1.1     skrll }
   1149          1.1     skrll 
   1150          1.1     skrll symbolS *
   1151          1.1     skrll md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   1152          1.1     skrll {
   1153          1.1     skrll   debug ("In md_undefined_symbol()\n");
   1154          1.1     skrll   return (symbolS *) 0;
   1155          1.1     skrll }
   1156          1.1     skrll 
   1157          1.1     skrll valueT
   1158          1.1     skrll md_section_align (segT segment, valueT size)
   1159          1.1     skrll {
   1160          1.1     skrll   debug ("In md_section_align() segment = %p and size = %lu\n",
   1161          1.1     skrll 	 segment, (unsigned long) size);
   1162          1.1     skrll   size = (size + 3) / 4;
   1163          1.1     skrll   size *= 4;
   1164          1.1     skrll   debug ("New size value = %lu\n", (unsigned long) size);
   1165          1.1     skrll   return size;
   1166          1.1     skrll }
   1167          1.1     skrll 
   1168          1.1     skrll long
   1169          1.1     skrll md_pcrel_from (fixS *fixP)
   1170          1.1     skrll {
   1171          1.1     skrll   int offset;
   1172          1.1     skrll 
   1173          1.1     skrll   debug ("In md_pcrel_from()\n");
   1174          1.1     skrll   debug ("fx_where = %ld\n", fixP->fx_where);
   1175          1.1     skrll   debug ("fx_size = %d\n", fixP->fx_size);
   1176          1.1     skrll   /* Find the opcode that represents the current instruction in the
   1177          1.1     skrll      fr_literal storage area, and check bit 21.  Bit 21 contains whether the
   1178          1.1     skrll      current instruction is a delayed one or not, and then set the offset
   1179          1.1     skrll      value appropriately.  */
   1180          1.1     skrll   if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
   1181          1.1     skrll     offset = 3;
   1182          1.1     skrll   else
   1183          1.1     skrll     offset = 1;
   1184          1.1     skrll   debug ("offset = %d\n", offset);
   1185          1.1     skrll   /* PC Relative instructions have a format:
   1186          1.1     skrll      displacement = Label - (PC + offset)
   1187          1.1     skrll      This function returns PC + offset where:
   1188          1.1     skrll      fx_where - fx_size = PC
   1189          1.1     skrll      INSN_SIZE * offset = offset number of instructions.  */
   1190          1.1     skrll   return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
   1191          1.1     skrll }
   1192          1.1     skrll 
   1193      1.1.1.5  christos const char *
   1194          1.1     skrll md_atof (int what_statement_type,
   1195          1.1     skrll 	 char *literalP,
   1196          1.1     skrll 	 int *sizeP)
   1197          1.1     skrll {
   1198          1.1     skrll   int prec;
   1199          1.1     skrll   char *token;
   1200          1.1     skrll   char keepval;
   1201          1.1     skrll   unsigned long value;
   1202          1.1     skrll   float float_value;
   1203          1.1     skrll 
   1204          1.1     skrll   debug ("In md_atof()\n");
   1205          1.1     skrll   debug ("precision = %c\n", what_statement_type);
   1206          1.1     skrll   debug ("literal = %s\n", literalP);
   1207          1.1     skrll   debug ("line = ");
   1208          1.1     skrll   token = input_line_pointer;
   1209          1.1     skrll   while (!is_end_of_line[(unsigned char) *input_line_pointer]
   1210          1.1     skrll 	 && (*input_line_pointer != ','))
   1211          1.1     skrll     {
   1212          1.1     skrll       debug ("%c", *input_line_pointer);
   1213          1.1     skrll       input_line_pointer++;
   1214          1.1     skrll     }
   1215          1.1     skrll 
   1216          1.1     skrll   keepval = *input_line_pointer;
   1217          1.1     skrll   *input_line_pointer = '\0';
   1218          1.1     skrll   debug ("\n");
   1219          1.1     skrll   float_value = (float) atof (token);
   1220          1.1     skrll   *input_line_pointer = keepval;
   1221          1.1     skrll   debug ("float_value = %f\n", float_value);
   1222          1.1     skrll 
   1223          1.1     skrll   switch (what_statement_type)
   1224          1.1     skrll     {
   1225          1.1     skrll     case 'f':
   1226          1.1     skrll     case 'F':
   1227          1.1     skrll     case 's':
   1228          1.1     skrll     case 'S':
   1229          1.1     skrll       prec = 2;
   1230          1.1     skrll       break;
   1231          1.1     skrll 
   1232          1.1     skrll     case 'd':
   1233          1.1     skrll     case 'D':
   1234          1.1     skrll     case 'r':
   1235          1.1     skrll     case 'R':
   1236          1.1     skrll       prec = 4;
   1237          1.1     skrll       break;
   1238          1.1     skrll 
   1239          1.1     skrll     default:
   1240          1.1     skrll       *sizeP = 0;
   1241          1.1     skrll       return _("Unrecognized or unsupported floating point constant");
   1242          1.1     skrll     }
   1243          1.1     skrll 
   1244          1.1     skrll   if (float_value == 0.0)
   1245          1.1     skrll     value = (prec == 2) ? 0x00008000L : 0x80000000L;
   1246          1.1     skrll   else
   1247          1.1     skrll     {
   1248          1.1     skrll       unsigned long exp, sign, mant, tmsfloat;
   1249          1.1     skrll       union
   1250          1.1     skrll       {
   1251          1.1     skrll 	float f;
   1252          1.1     skrll 	long  l;
   1253          1.1     skrll       }
   1254          1.1     skrll       converter;
   1255          1.1     skrll 
   1256          1.1     skrll       converter.f = float_value;
   1257          1.1     skrll       tmsfloat = converter.l;
   1258          1.1     skrll       sign = tmsfloat & 0x80000000;
   1259          1.1     skrll       mant = tmsfloat & 0x007FFFFF;
   1260          1.1     skrll       exp = tmsfloat & 0x7F800000;
   1261          1.1     skrll       exp <<= 1;
   1262          1.1     skrll       if (exp == 0xFF000000)
   1263          1.1     skrll 	{
   1264          1.1     skrll 	  if (mant == 0)
   1265          1.1     skrll 	    value = 0x7F7FFFFF;
   1266          1.1     skrll 	  else if (sign == 0)
   1267          1.1     skrll 	    value = 0x7F7FFFFF;
   1268          1.1     skrll 	  else
   1269          1.1     skrll 	    value = 0x7F800000;
   1270          1.1     skrll 	}
   1271          1.1     skrll       else
   1272          1.1     skrll 	{
   1273          1.1     skrll 	  exp -= 0x7F000000;
   1274          1.1     skrll 	  if (sign)
   1275          1.1     skrll 	    {
   1276          1.1     skrll 	      mant = mant & 0x007FFFFF;
   1277          1.1     skrll 	      mant = -mant;
   1278          1.1     skrll 	      mant = mant & 0x00FFFFFF;
   1279          1.1     skrll 	      if (mant == 0)
   1280          1.1     skrll 		{
   1281          1.1     skrll 		  mant |= 0x00800000;
   1282          1.1     skrll 		  exp = (long) exp - 0x01000000;
   1283          1.1     skrll 		}
   1284          1.1     skrll 	    }
   1285          1.1     skrll 	  tmsfloat = exp | mant;
   1286          1.1     skrll 	  value = tmsfloat;
   1287          1.1     skrll 	}
   1288          1.1     skrll       if (prec == 2)
   1289          1.1     skrll 	{
   1290      1.1.1.2  christos 	  long expon, mantis;
   1291          1.1     skrll 
   1292          1.1     skrll 	  if (tmsfloat == 0x80000000)
   1293          1.1     skrll 	    value = 0x8000;
   1294          1.1     skrll 	  else
   1295          1.1     skrll 	    {
   1296          1.1     skrll 	      value = 0;
   1297      1.1.1.2  christos 	      expon = (tmsfloat & 0xFF000000);
   1298      1.1.1.2  christos 	      expon >>= 24;
   1299      1.1.1.2  christos 	      mantis = tmsfloat & 0x007FFFFF;
   1300          1.1     skrll 	      if (tmsfloat & 0x00800000)
   1301          1.1     skrll 		{
   1302      1.1.1.2  christos 		  mantis |= 0xFF000000;
   1303      1.1.1.2  christos 		  mantis += 0x00000800;
   1304      1.1.1.2  christos 		  mantis >>= 12;
   1305      1.1.1.2  christos 		  mantis |= 0x00000800;
   1306      1.1.1.2  christos 		  mantis &= 0x0FFF;
   1307      1.1.1.2  christos 		  if (expon > 7)
   1308          1.1     skrll 		    value = 0x7800;
   1309          1.1     skrll 		}
   1310          1.1     skrll 	      else
   1311          1.1     skrll 		{
   1312      1.1.1.2  christos 		  mantis |= 0x00800000;
   1313      1.1.1.2  christos 		  mantis += 0x00000800;
   1314      1.1.1.2  christos 		  expon += (mantis >> 24);
   1315      1.1.1.2  christos 		  mantis >>= 12;
   1316      1.1.1.2  christos 		  mantis &= 0x07FF;
   1317      1.1.1.2  christos 		  if (expon > 7)
   1318          1.1     skrll 		    value = 0x77FF;
   1319          1.1     skrll 		}
   1320      1.1.1.2  christos 	      if (expon < -8)
   1321          1.1     skrll 		value = 0x8000;
   1322          1.1     skrll 	      if (value == 0)
   1323          1.1     skrll 		{
   1324      1.1.1.2  christos 		  mantis = (expon << 12) | mantis;
   1325      1.1.1.2  christos 		  value = mantis & 0xFFFF;
   1326          1.1     skrll 		}
   1327          1.1     skrll 	    }
   1328          1.1     skrll 	}
   1329          1.1     skrll     }
   1330          1.1     skrll   md_number_to_chars (literalP, value, prec);
   1331          1.1     skrll   *sizeP = prec;
   1332          1.1     skrll   return NULL;
   1333          1.1     skrll }
   1334          1.1     skrll 
   1335          1.1     skrll void
   1336          1.1     skrll md_number_to_chars (char *buf, valueT val, int n)
   1337          1.1     skrll {
   1338          1.1     skrll   debug ("In md_number_to_chars()\n");
   1339          1.1     skrll   number_to_chars_bigendian (buf, val, n);
   1340          1.1     skrll }
   1341          1.1     skrll 
   1342          1.1     skrll #define F(SZ,PCREL)		(((SZ) << 1) + (PCREL))
   1343          1.1     skrll #define MAP(SZ,PCREL,TYPE)	case F(SZ,PCREL): code = (TYPE); break
   1344          1.1     skrll 
   1345          1.1     skrll arelent *
   1346          1.1     skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   1347          1.1     skrll {
   1348          1.1     skrll   arelent *rel;
   1349          1.1     skrll   bfd_reloc_code_real_type code = 0;
   1350          1.1     skrll 
   1351          1.1     skrll   debug ("In tc_gen_reloc()\n");
   1352          1.1     skrll   debug ("fixP.size = %d\n", fixP->fx_size);
   1353          1.1     skrll   debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
   1354          1.1     skrll   debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
   1355          1.1     skrll 
   1356          1.1     skrll   switch (F (fixP->fx_size, fixP->fx_pcrel))
   1357          1.1     skrll     {
   1358          1.1     skrll       MAP (1, 0, BFD_RELOC_TIC30_LDP);
   1359          1.1     skrll       MAP (2, 0, BFD_RELOC_16);
   1360          1.1     skrll       MAP (3, 0, BFD_RELOC_24);
   1361          1.1     skrll       MAP (2, 1, BFD_RELOC_16_PCREL);
   1362          1.1     skrll       MAP (4, 0, BFD_RELOC_32);
   1363          1.1     skrll     default:
   1364      1.1.1.2  christos       as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
   1365      1.1.1.2  christos 	      fixP->fx_pcrel ? _("pc-relative ") : "");
   1366          1.1     skrll     }
   1367          1.1     skrll #undef MAP
   1368          1.1     skrll #undef F
   1369          1.1     skrll 
   1370      1.1.1.5  christos   rel = XNEW (arelent);
   1371      1.1.1.2  christos   gas_assert (rel != 0);
   1372      1.1.1.5  christos   rel->sym_ptr_ptr = XNEW (asymbol *);
   1373          1.1     skrll   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   1374          1.1     skrll   rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
   1375          1.1     skrll   rel->addend = 0;
   1376          1.1     skrll   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
   1377          1.1     skrll   if (!rel->howto)
   1378          1.1     skrll     {
   1379          1.1     skrll       const char *name;
   1380          1.1     skrll 
   1381          1.1     skrll       name = S_GET_NAME (fixP->fx_addsy);
   1382          1.1     skrll       if (name == NULL)
   1383          1.1     skrll 	name = "<unknown>";
   1384          1.1     skrll       as_fatal ("Cannot generate relocation type for symbol %s, code %s",
   1385          1.1     skrll 		name, bfd_get_reloc_code_name (code));
   1386          1.1     skrll     }
   1387          1.1     skrll   return rel;
   1388          1.1     skrll }
   1389          1.1     skrll 
   1390          1.1     skrll void
   1391          1.1     skrll md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
   1392          1.1     skrll {
   1393          1.1     skrll   debug ("In md_operand()\n");
   1394          1.1     skrll }
   1395          1.1     skrll 
   1396          1.1     skrll void
   1397          1.1     skrll md_assemble (char *line)
   1398          1.1     skrll {
   1399      1.1.1.2  christos   insn_template *op;
   1400          1.1     skrll   char *current_posn;
   1401          1.1     skrll   char *token_start;
   1402          1.1     skrll   char save_char;
   1403          1.1     skrll   unsigned int count;
   1404          1.1     skrll 
   1405          1.1     skrll   debug ("In md_assemble() with argument %s\n", line);
   1406          1.1     skrll   memset (&insn, '\0', sizeof (insn));
   1407          1.1     skrll   if (found_parallel_insn)
   1408          1.1     skrll     {
   1409          1.1     skrll       debug ("Line is second part of parallel instruction\n\n");
   1410          1.1     skrll       found_parallel_insn = 0;
   1411          1.1     skrll       return;
   1412          1.1     skrll     }
   1413          1.1     skrll   if ((current_posn =
   1414          1.1     skrll        tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
   1415          1.1     skrll     current_posn = line;
   1416          1.1     skrll   else
   1417          1.1     skrll     found_parallel_insn = 1;
   1418          1.1     skrll 
   1419          1.1     skrll   while (is_space_char (*current_posn))
   1420          1.1     skrll     current_posn++;
   1421          1.1     skrll 
   1422          1.1     skrll   token_start = current_posn;
   1423          1.1     skrll 
   1424          1.1     skrll   if (!is_opcode_char (*current_posn))
   1425          1.1     skrll     {
   1426      1.1.1.2  christos       as_bad (_("Invalid character %s in opcode"),
   1427          1.1     skrll 	      output_invalid (*current_posn));
   1428          1.1     skrll       return;
   1429          1.1     skrll     }
   1430          1.1     skrll   /* Check if instruction is a parallel instruction
   1431          1.1     skrll      by seeing if the first character is a q.  */
   1432          1.1     skrll   if (*token_start == 'q')
   1433          1.1     skrll     {
   1434          1.1     skrll       if (tic30_parallel_insn (token_start))
   1435          1.1     skrll 	{
   1436          1.1     skrll 	  if (found_parallel_insn)
   1437          1.1     skrll 	    free (token_start);
   1438          1.1     skrll 	  return;
   1439          1.1     skrll 	}
   1440          1.1     skrll     }
   1441          1.1     skrll   while (is_opcode_char (*current_posn))
   1442          1.1     skrll     current_posn++;
   1443          1.1     skrll   {
   1444          1.1     skrll     /* Find instruction.  */
   1445          1.1     skrll     save_char = *current_posn;
   1446          1.1     skrll     *current_posn = '\0';
   1447      1.1.1.8  christos     op = (insn_template *) str_hash_find (op_hash, token_start);
   1448      1.1.1.2  christos     if (op)
   1449          1.1     skrll       {
   1450      1.1.1.2  christos 	debug ("Found instruction %s\n", op->name);
   1451      1.1.1.2  christos 	insn.tm = op;
   1452          1.1     skrll       }
   1453          1.1     skrll     else
   1454          1.1     skrll       {
   1455          1.1     skrll 	debug ("Didn't find insn\n");
   1456      1.1.1.2  christos 	as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
   1457          1.1     skrll 	return;
   1458          1.1     skrll       }
   1459          1.1     skrll     *current_posn = save_char;
   1460          1.1     skrll   }
   1461          1.1     skrll 
   1462          1.1     skrll   if (*current_posn != END_OF_INSN)
   1463          1.1     skrll     {
   1464          1.1     skrll       /* Find operands.  */
   1465          1.1     skrll       int paren_not_balanced;
   1466          1.1     skrll       int expecting_operand = 0;
   1467          1.1     skrll       int this_operand;
   1468          1.1     skrll       do
   1469          1.1     skrll 	{
   1470          1.1     skrll 	  /* Skip optional white space before operand.  */
   1471          1.1     skrll 	  while (!is_operand_char (*current_posn)
   1472          1.1     skrll 		 && *current_posn != END_OF_INSN)
   1473          1.1     skrll 	    {
   1474          1.1     skrll 	      if (!is_space_char (*current_posn))
   1475          1.1     skrll 		{
   1476      1.1.1.2  christos 		  as_bad (_("Invalid character %s before %s operand"),
   1477          1.1     skrll 			  output_invalid (*current_posn),
   1478          1.1     skrll 			  ordinal_names[insn.operands]);
   1479          1.1     skrll 		  return;
   1480          1.1     skrll 		}
   1481          1.1     skrll 	      current_posn++;
   1482          1.1     skrll 	    }
   1483          1.1     skrll 	  token_start = current_posn;
   1484          1.1     skrll 	  paren_not_balanced = 0;
   1485          1.1     skrll 	  while (paren_not_balanced || *current_posn != ',')
   1486          1.1     skrll 	    {
   1487          1.1     skrll 	      if (*current_posn == END_OF_INSN)
   1488          1.1     skrll 		{
   1489          1.1     skrll 		  if (paren_not_balanced)
   1490          1.1     skrll 		    {
   1491      1.1.1.2  christos 		      as_bad (_("Unbalanced parenthesis in %s operand."),
   1492          1.1     skrll 			      ordinal_names[insn.operands]);
   1493          1.1     skrll 		      return;
   1494          1.1     skrll 		    }
   1495          1.1     skrll 		  else
   1496          1.1     skrll 		    break;
   1497          1.1     skrll 		}
   1498          1.1     skrll 	      else if (!is_operand_char (*current_posn)
   1499          1.1     skrll 		       && !is_space_char (*current_posn))
   1500          1.1     skrll 		{
   1501      1.1.1.2  christos 		  as_bad (_("Invalid character %s in %s operand"),
   1502          1.1     skrll 			  output_invalid (*current_posn),
   1503          1.1     skrll 			  ordinal_names[insn.operands]);
   1504          1.1     skrll 		  return;
   1505          1.1     skrll 		}
   1506          1.1     skrll 	      if (*current_posn == '(')
   1507          1.1     skrll 		++paren_not_balanced;
   1508          1.1     skrll 	      if (*current_posn == ')')
   1509          1.1     skrll 		--paren_not_balanced;
   1510          1.1     skrll 	      current_posn++;
   1511          1.1     skrll 	    }
   1512          1.1     skrll 	  if (current_posn != token_start)
   1513          1.1     skrll 	    {
   1514          1.1     skrll 	      /* Yes, we've read in another operand.  */
   1515          1.1     skrll 	      this_operand = insn.operands++;
   1516          1.1     skrll 	      if (insn.operands > MAX_OPERANDS)
   1517          1.1     skrll 		{
   1518      1.1.1.2  christos 		  as_bad (_("Spurious operands; (%d operands/instruction max)"),
   1519          1.1     skrll 			  MAX_OPERANDS);
   1520          1.1     skrll 		  return;
   1521          1.1     skrll 		}
   1522          1.1     skrll 
   1523          1.1     skrll 	      /* Now parse operand adding info to 'insn' as we go along.  */
   1524          1.1     skrll 	      save_char = *current_posn;
   1525          1.1     skrll 	      *current_posn = '\0';
   1526          1.1     skrll 	      insn.operand_type[this_operand] = tic30_operand (token_start);
   1527          1.1     skrll 	      *current_posn = save_char;
   1528          1.1     skrll 	      if (insn.operand_type[this_operand] == NULL)
   1529          1.1     skrll 		return;
   1530          1.1     skrll 	    }
   1531          1.1     skrll 	  else
   1532          1.1     skrll 	    {
   1533          1.1     skrll 	      if (expecting_operand)
   1534          1.1     skrll 		{
   1535      1.1.1.2  christos 		  as_bad (_("Expecting operand after ','; got nothing"));
   1536          1.1     skrll 		  return;
   1537          1.1     skrll 		}
   1538          1.1     skrll 	      if (*current_posn == ',')
   1539          1.1     skrll 		{
   1540      1.1.1.2  christos 		  as_bad (_("Expecting operand before ','; got nothing"));
   1541          1.1     skrll 		  return;
   1542          1.1     skrll 		}
   1543          1.1     skrll 	    }
   1544          1.1     skrll 
   1545          1.1     skrll 	  /* Now *current_posn must be either ',' or END_OF_INSN.  */
   1546          1.1     skrll 	  if (*current_posn == ',')
   1547          1.1     skrll 	    {
   1548          1.1     skrll 	      if (*++current_posn == END_OF_INSN)
   1549          1.1     skrll 		{
   1550          1.1     skrll 		  /* Just skip it, if it's \n complain.  */
   1551      1.1.1.2  christos 		  as_bad (_("Expecting operand after ','; got nothing"));
   1552          1.1     skrll 		  return;
   1553          1.1     skrll 		}
   1554          1.1     skrll 	      expecting_operand = 1;
   1555          1.1     skrll 	    }
   1556          1.1     skrll 	}
   1557          1.1     skrll       while (*current_posn != END_OF_INSN);
   1558          1.1     skrll     }
   1559          1.1     skrll 
   1560          1.1     skrll   debug ("Number of operands found: %d\n", insn.operands);
   1561          1.1     skrll 
   1562          1.1     skrll   /* Check that number of operands is correct.  */
   1563          1.1     skrll   if (insn.operands != insn.tm->operands)
   1564          1.1     skrll     {
   1565          1.1     skrll       unsigned int i;
   1566          1.1     skrll       unsigned int numops = insn.tm->operands;
   1567          1.1     skrll 
   1568          1.1     skrll       /* If operands are not the same, then see if any of the operands are
   1569          1.1     skrll 	 not required.  Then recheck with number of given operands.  If they
   1570          1.1     skrll 	 are still not the same, then give an error, otherwise carry on.  */
   1571          1.1     skrll       for (i = 0; i < insn.tm->operands; i++)
   1572          1.1     skrll 	if (insn.tm->operand_types[i] & NotReq)
   1573          1.1     skrll 	  numops--;
   1574          1.1     skrll       if (insn.operands != numops)
   1575          1.1     skrll 	{
   1576      1.1.1.2  christos 	  as_bad (_("Incorrect number of operands given"));
   1577          1.1     skrll 	  return;
   1578          1.1     skrll 	}
   1579          1.1     skrll     }
   1580          1.1     skrll   insn.addressing_mode = AM_NotReq;
   1581          1.1     skrll   for (count = 0; count < insn.operands; count++)
   1582          1.1     skrll     {
   1583          1.1     skrll       if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
   1584          1.1     skrll 	{
   1585          1.1     skrll 	  debug ("Operand %d matches\n", count + 1);
   1586          1.1     skrll 	  /* If instruction has two operands and has an AddressMode
   1587          1.1     skrll 	     modifier then set addressing mode type for instruction.  */
   1588          1.1     skrll 	  if (insn.tm->opcode_modifier == AddressMode)
   1589          1.1     skrll 	    {
   1590          1.1     skrll 	      int addr_insn = 0;
   1591          1.1     skrll 	      /* Store instruction uses the second
   1592          1.1     skrll 		 operand for the address mode.  */
   1593          1.1     skrll 	      if ((insn.tm->operand_types[1] & (Indirect | Direct))
   1594          1.1     skrll 		  == (Indirect | Direct))
   1595          1.1     skrll 		addr_insn = 1;
   1596          1.1     skrll 
   1597          1.1     skrll 	      if (insn.operand_type[addr_insn]->op_type & (AllReg))
   1598          1.1     skrll 		insn.addressing_mode = AM_Register;
   1599          1.1     skrll 	      else if (insn.operand_type[addr_insn]->op_type & Direct)
   1600          1.1     skrll 		insn.addressing_mode = AM_Direct;
   1601          1.1     skrll 	      else if (insn.operand_type[addr_insn]->op_type & Indirect)
   1602          1.1     skrll 		insn.addressing_mode = AM_Indirect;
   1603          1.1     skrll 	      else
   1604          1.1     skrll 		insn.addressing_mode = AM_Immediate;
   1605          1.1     skrll 	    }
   1606          1.1     skrll 	}
   1607          1.1     skrll       else
   1608          1.1     skrll 	{
   1609      1.1.1.2  christos 	  as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
   1610          1.1     skrll 	  return;
   1611          1.1     skrll 	}
   1612          1.1     skrll     }
   1613          1.1     skrll 
   1614          1.1     skrll   /* Now set the addressing mode for 3 operand instructions.  */
   1615          1.1     skrll   if ((insn.tm->operand_types[0] & op3T1)
   1616          1.1     skrll       && (insn.tm->operand_types[1] & op3T2))
   1617          1.1     skrll     {
   1618          1.1     skrll       /* Set the addressing mode to the values used for 2 operand
   1619          1.1     skrll 	 instructions in the  G addressing field of the opcode.  */
   1620          1.1     skrll       char *p;
   1621          1.1     skrll       switch (insn.operand_type[0]->op_type)
   1622          1.1     skrll 	{
   1623          1.1     skrll 	case Rn:
   1624          1.1     skrll 	case ARn:
   1625          1.1     skrll 	case DPReg:
   1626          1.1     skrll 	case OtherReg:
   1627          1.1     skrll 	  if (insn.operand_type[1]->op_type & (AllReg))
   1628          1.1     skrll 	    insn.addressing_mode = AM_Register;
   1629          1.1     skrll 	  else if (insn.operand_type[1]->op_type & Indirect)
   1630          1.1     skrll 	    insn.addressing_mode = AM_Direct;
   1631          1.1     skrll 	  else
   1632          1.1     skrll 	    {
   1633          1.1     skrll 	      /* Shouldn't make it to this stage.  */
   1634      1.1.1.2  christos 	      as_bad (_("Incompatible first and second operands in instruction"));
   1635          1.1     skrll 	      return;
   1636          1.1     skrll 	    }
   1637          1.1     skrll 	  break;
   1638          1.1     skrll 	case Indirect:
   1639          1.1     skrll 	  if (insn.operand_type[1]->op_type & (AllReg))
   1640          1.1     skrll 	    insn.addressing_mode = AM_Indirect;
   1641          1.1     skrll 	  else if (insn.operand_type[1]->op_type & Indirect)
   1642          1.1     skrll 	    insn.addressing_mode = AM_Immediate;
   1643          1.1     skrll 	  else
   1644          1.1     skrll 	    {
   1645          1.1     skrll 	      /* Shouldn't make it to this stage.  */
   1646      1.1.1.2  christos 	      as_bad (_("Incompatible first and second operands in instruction"));
   1647          1.1     skrll 	      return;
   1648          1.1     skrll 	    }
   1649          1.1     skrll 	  break;
   1650          1.1     skrll 	}
   1651          1.1     skrll       /* Now make up the opcode for the 3 operand instructions.  As in
   1652          1.1     skrll 	 parallel instructions, there will be no unresolved values, so they
   1653          1.1     skrll 	 can be fully formed and added to the frag table.  */
   1654          1.1     skrll       insn.opcode = insn.tm->base_opcode;
   1655          1.1     skrll       if (insn.operand_type[0]->op_type & Indirect)
   1656          1.1     skrll 	{
   1657          1.1     skrll 	  insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
   1658          1.1     skrll 	  insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
   1659          1.1     skrll 	}
   1660          1.1     skrll       else
   1661          1.1     skrll 	insn.opcode |= (insn.operand_type[0]->reg.opcode);
   1662          1.1     skrll 
   1663          1.1     skrll       if (insn.operand_type[1]->op_type & Indirect)
   1664          1.1     skrll 	{
   1665          1.1     skrll 	  insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
   1666          1.1     skrll 	  insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
   1667          1.1     skrll 	}
   1668          1.1     skrll       else
   1669          1.1     skrll 	insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
   1670          1.1     skrll 
   1671          1.1     skrll       if (insn.operands == 3)
   1672          1.1     skrll 	insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
   1673          1.1     skrll 
   1674          1.1     skrll       insn.opcode |= insn.addressing_mode;
   1675          1.1     skrll       p = frag_more (INSN_SIZE);
   1676          1.1     skrll       md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1677          1.1     skrll     }
   1678          1.1     skrll   else
   1679          1.1     skrll     {
   1680          1.1     skrll       /* Not a three operand instruction.  */
   1681          1.1     skrll       char *p;
   1682          1.1     skrll       int am_insn = -1;
   1683          1.1     skrll       insn.opcode = insn.tm->base_opcode;
   1684          1.1     skrll       /* Create frag for instruction - all instructions are 4 bytes long.  */
   1685          1.1     skrll       p = frag_more (INSN_SIZE);
   1686          1.1     skrll       if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
   1687          1.1     skrll 	{
   1688          1.1     skrll 	  insn.opcode |= insn.addressing_mode;
   1689          1.1     skrll 	  if (insn.addressing_mode == AM_Indirect)
   1690          1.1     skrll 	    {
   1691          1.1     skrll 	      /* Determine which operand gives the addressing mode.  */
   1692          1.1     skrll 	      if (insn.operand_type[0]->op_type & Indirect)
   1693          1.1     skrll 		am_insn = 0;
   1694          1.1     skrll 	      if ((insn.operands > 1)
   1695          1.1     skrll 		  && (insn.operand_type[1]->op_type & Indirect))
   1696          1.1     skrll 		am_insn = 1;
   1697          1.1     skrll 	      insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
   1698          1.1     skrll 	      insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
   1699          1.1     skrll 	      insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
   1700          1.1     skrll 	      if (insn.operands > 1)
   1701          1.1     skrll 		insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
   1702          1.1     skrll 	      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1703          1.1     skrll 	    }
   1704          1.1     skrll 	  else if (insn.addressing_mode == AM_Register)
   1705          1.1     skrll 	    {
   1706          1.1     skrll 	      insn.opcode |= (insn.operand_type[0]->reg.opcode);
   1707          1.1     skrll 	      if (insn.operands > 1)
   1708          1.1     skrll 		insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
   1709          1.1     skrll 	      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1710          1.1     skrll 	    }
   1711          1.1     skrll 	  else if (insn.addressing_mode == AM_Direct)
   1712          1.1     skrll 	    {
   1713          1.1     skrll 	      if (insn.operand_type[0]->op_type & Direct)
   1714          1.1     skrll 		am_insn = 0;
   1715          1.1     skrll 	      if ((insn.operands > 1)
   1716          1.1     skrll 		  && (insn.operand_type[1]->op_type & Direct))
   1717          1.1     skrll 		am_insn = 1;
   1718          1.1     skrll 	      if (insn.operands > 1)
   1719          1.1     skrll 		insn.opcode |=
   1720          1.1     skrll 		  (insn.operand_type[! am_insn]->reg.opcode << 16);
   1721          1.1     skrll 	      if (insn.operand_type[am_insn]->direct.resolved == 1)
   1722          1.1     skrll 		{
   1723          1.1     skrll 		  /* Resolved values can be placed straight
   1724          1.1     skrll 		     into instruction word, and output.  */
   1725          1.1     skrll 		  insn.opcode |=
   1726          1.1     skrll 		    (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
   1727          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1728          1.1     skrll 		}
   1729          1.1     skrll 	      else
   1730          1.1     skrll 		{
   1731          1.1     skrll 		  /* Unresolved direct addressing mode instruction.  */
   1732          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1733          1.1     skrll 		  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
   1734          1.1     skrll 			       & insn.operand_type[am_insn]->direct.direct_expr,
   1735          1.1     skrll 			       0, 0);
   1736          1.1     skrll 		}
   1737          1.1     skrll 	    }
   1738          1.1     skrll 	  else if (insn.addressing_mode == AM_Immediate)
   1739          1.1     skrll 	    {
   1740          1.1     skrll 	      if (insn.operand_type[0]->immediate.resolved == 1)
   1741          1.1     skrll 		{
   1742          1.1     skrll 		  char *keeploc;
   1743          1.1     skrll 		  int size;
   1744          1.1     skrll 
   1745          1.1     skrll 		  if (insn.operands > 1)
   1746          1.1     skrll 		    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
   1747          1.1     skrll 
   1748          1.1     skrll 		  switch (insn.tm->imm_arg_type)
   1749          1.1     skrll 		    {
   1750          1.1     skrll 		    case Imm_Float:
   1751          1.1     skrll 		      debug ("Floating point first operand\n");
   1752          1.1     skrll 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1753          1.1     skrll 
   1754          1.1     skrll 		      keeploc = input_line_pointer;
   1755          1.1     skrll 		      input_line_pointer =
   1756          1.1     skrll 			insn.operand_type[0]->immediate.label;
   1757          1.1     skrll 
   1758          1.1     skrll 		      if (md_atof ('f', p + 2, & size) != 0)
   1759          1.1     skrll 			{
   1760      1.1.1.2  christos 			  as_bad (_("invalid short form floating point immediate operand"));
   1761          1.1     skrll 			  return;
   1762          1.1     skrll 			}
   1763          1.1     skrll 
   1764          1.1     skrll 		      input_line_pointer = keeploc;
   1765          1.1     skrll 		      break;
   1766          1.1     skrll 
   1767          1.1     skrll 		    case Imm_UInt:
   1768          1.1     skrll 		      debug ("Unsigned int first operand\n");
   1769          1.1     skrll 		      if (insn.operand_type[0]->immediate.decimal_found)
   1770      1.1.1.2  christos 			as_warn (_("rounding down first operand float to unsigned int"));
   1771          1.1     skrll 		      if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
   1772      1.1.1.2  christos 			as_warn (_("only lower 16-bits of first operand are used"));
   1773          1.1     skrll 		      insn.opcode |=
   1774          1.1     skrll 			(insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
   1775          1.1     skrll 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1776          1.1     skrll 		      break;
   1777          1.1     skrll 
   1778          1.1     skrll 		    case Imm_SInt:
   1779          1.1     skrll 		      debug ("Int first operand\n");
   1780          1.1     skrll 
   1781          1.1     skrll 		      if (insn.operand_type[0]->immediate.decimal_found)
   1782      1.1.1.2  christos 			as_warn (_("rounding down first operand float to signed int"));
   1783          1.1     skrll 
   1784          1.1     skrll 		      if (insn.operand_type[0]->immediate.s_number < -32768 ||
   1785          1.1     skrll 			  insn.operand_type[0]->immediate.s_number > 32767)
   1786          1.1     skrll 			{
   1787      1.1.1.2  christos 			  as_bad (_("first operand is too large for 16-bit signed int"));
   1788          1.1     skrll 			  return;
   1789          1.1     skrll 			}
   1790          1.1     skrll 		      insn.opcode |=
   1791          1.1     skrll 			(insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
   1792          1.1     skrll 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1793          1.1     skrll 		      break;
   1794          1.1     skrll 		    }
   1795          1.1     skrll 		}
   1796          1.1     skrll 	      else
   1797          1.1     skrll 		{
   1798          1.1     skrll 		  /* Unresolved immediate label.  */
   1799          1.1     skrll 		  if (insn.operands > 1)
   1800          1.1     skrll 		    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
   1801          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1802          1.1     skrll 		  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
   1803          1.1     skrll 			       & insn.operand_type[0]->immediate.imm_expr,
   1804          1.1     skrll 			       0, 0);
   1805          1.1     skrll 		}
   1806          1.1     skrll 	    }
   1807          1.1     skrll 	}
   1808          1.1     skrll       else if (insn.tm->opcode_modifier == PCRel)
   1809          1.1     skrll 	{
   1810          1.1     skrll 	  /* Conditional Branch and Call instructions.  */
   1811          1.1     skrll 	  if ((insn.tm->operand_types[0] & (AllReg | Disp))
   1812          1.1     skrll 	      == (AllReg | Disp))
   1813          1.1     skrll 	    {
   1814          1.1     skrll 	      if (insn.operand_type[0]->op_type & (AllReg))
   1815          1.1     skrll 		{
   1816          1.1     skrll 		  insn.opcode |= (insn.operand_type[0]->reg.opcode);
   1817          1.1     skrll 		  insn.opcode |= PC_Register;
   1818          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1819          1.1     skrll 		}
   1820          1.1     skrll 	      else
   1821          1.1     skrll 		{
   1822          1.1     skrll 		  insn.opcode |= PC_Relative;
   1823          1.1     skrll 		  if (insn.operand_type[0]->immediate.resolved == 1)
   1824          1.1     skrll 		    {
   1825          1.1     skrll 		      insn.opcode |=
   1826          1.1     skrll 			(insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
   1827          1.1     skrll 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1828          1.1     skrll 		    }
   1829          1.1     skrll 		  else
   1830          1.1     skrll 		    {
   1831          1.1     skrll 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1832          1.1     skrll 		      fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
   1833          1.1     skrll 				   2, & insn.operand_type[0]->immediate.imm_expr,
   1834          1.1     skrll 				   1, 0);
   1835          1.1     skrll 		    }
   1836          1.1     skrll 		}
   1837          1.1     skrll 	    }
   1838          1.1     skrll 	  else if ((insn.tm->operand_types[0] & ARn) == ARn)
   1839          1.1     skrll 	    {
   1840          1.1     skrll 	      /* Decrement and Branch instructions.  */
   1841          1.1     skrll 	      insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
   1842          1.1     skrll 	      if (insn.operand_type[1]->op_type & (AllReg))
   1843          1.1     skrll 		{
   1844          1.1     skrll 		  insn.opcode |= (insn.operand_type[1]->reg.opcode);
   1845          1.1     skrll 		  insn.opcode |= PC_Register;
   1846          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1847          1.1     skrll 		}
   1848          1.1     skrll 	      else if (insn.operand_type[1]->immediate.resolved == 1)
   1849          1.1     skrll 		{
   1850          1.1     skrll 		  if (insn.operand_type[0]->immediate.decimal_found)
   1851          1.1     skrll 		    {
   1852      1.1.1.2  christos 		      as_bad (_("first operand is floating point"));
   1853          1.1     skrll 		      return;
   1854          1.1     skrll 		    }
   1855          1.1     skrll 		  if (insn.operand_type[0]->immediate.s_number < -32768 ||
   1856          1.1     skrll 		      insn.operand_type[0]->immediate.s_number > 32767)
   1857          1.1     skrll 		    {
   1858      1.1.1.2  christos 		      as_bad (_("first operand is too large for 16-bit signed int"));
   1859          1.1     skrll 		      return;
   1860          1.1     skrll 		    }
   1861          1.1     skrll 		  insn.opcode |= (insn.operand_type[1]->immediate.s_number);
   1862          1.1     skrll 		  insn.opcode |= PC_Relative;
   1863          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1864          1.1     skrll 		}
   1865          1.1     skrll 	      else
   1866          1.1     skrll 		{
   1867          1.1     skrll 		  insn.opcode |= PC_Relative;
   1868          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1869          1.1     skrll 		  fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
   1870          1.1     skrll 			       & insn.operand_type[1]->immediate.imm_expr,
   1871          1.1     skrll 			       1, 0);
   1872          1.1     skrll 		}
   1873          1.1     skrll 	    }
   1874          1.1     skrll 	}
   1875          1.1     skrll       else if (insn.tm->operand_types[0] == IVector)
   1876          1.1     skrll 	{
   1877          1.1     skrll 	  /* Trap instructions.  */
   1878          1.1     skrll 	  if (insn.operand_type[0]->op_type & IVector)
   1879          1.1     skrll 	    insn.opcode |= (insn.operand_type[0]->immediate.u_number);
   1880          1.1     skrll 	  else
   1881          1.1     skrll 	    {
   1882          1.1     skrll 	      /* Shouldn't get here.  */
   1883      1.1.1.2  christos 	      as_bad (_("interrupt vector for trap instruction out of range"));
   1884          1.1     skrll 	      return;
   1885          1.1     skrll 	    }
   1886          1.1     skrll 	  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1887          1.1     skrll 	}
   1888          1.1     skrll       else if (insn.tm->opcode_modifier == StackOp
   1889          1.1     skrll 	       || insn.tm->opcode_modifier == Rotate)
   1890          1.1     skrll 	{
   1891          1.1     skrll 	  /* Push, Pop and Rotate instructions.  */
   1892          1.1     skrll 	  insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
   1893          1.1     skrll 	  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1894          1.1     skrll 	}
   1895          1.1     skrll       else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
   1896          1.1     skrll 	       == (Abs24 | Direct))
   1897          1.1     skrll 	{
   1898          1.1     skrll 	  /* LDP Instruction needs to be tested
   1899          1.1     skrll 	     for before the next section.  */
   1900          1.1     skrll 	  if (insn.operand_type[0]->op_type & Direct)
   1901          1.1     skrll 	    {
   1902          1.1     skrll 	      if (insn.operand_type[0]->direct.resolved == 1)
   1903          1.1     skrll 		{
   1904          1.1     skrll 		  /* Direct addressing uses lower 8 bits of direct address.  */
   1905          1.1     skrll 		  insn.opcode |=
   1906          1.1     skrll 		    (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
   1907          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1908          1.1     skrll 		}
   1909          1.1     skrll 	      else
   1910          1.1     skrll 		{
   1911          1.1     skrll 		  fixS *fix;
   1912          1.1     skrll 
   1913          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1914          1.1     skrll 		  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
   1915          1.1     skrll 				     1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
   1916          1.1     skrll 		  /* Ensure that the assembler doesn't complain
   1917          1.1     skrll 		     about fitting a 24-bit address into 8 bits.  */
   1918          1.1     skrll 		  fix->fx_no_overflow = 1;
   1919          1.1     skrll 		}
   1920          1.1     skrll 	    }
   1921          1.1     skrll 	  else
   1922          1.1     skrll 	    {
   1923          1.1     skrll 	      if (insn.operand_type[0]->immediate.resolved == 1)
   1924          1.1     skrll 		{
   1925          1.1     skrll 		  /* Immediate addressing uses upper 8 bits of address.  */
   1926          1.1     skrll 		  if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
   1927          1.1     skrll 		    {
   1928      1.1.1.2  christos 		      as_bad (_("LDP instruction needs a 24-bit operand"));
   1929          1.1     skrll 		      return;
   1930          1.1     skrll 		    }
   1931          1.1     skrll 		  insn.opcode |=
   1932          1.1     skrll 		    ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
   1933          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1934          1.1     skrll 		}
   1935          1.1     skrll 	      else
   1936          1.1     skrll 		{
   1937          1.1     skrll 		  fixS *fix;
   1938          1.1     skrll 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1939          1.1     skrll 		  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
   1940          1.1     skrll 				     1, &insn.operand_type[0]->immediate.imm_expr,
   1941          1.1     skrll 				     0, 0);
   1942          1.1     skrll 		  fix->fx_no_overflow = 1;
   1943          1.1     skrll 		}
   1944          1.1     skrll 	    }
   1945          1.1     skrll 	}
   1946          1.1     skrll       else if (insn.tm->operand_types[0] & (Imm24))
   1947          1.1     skrll 	{
   1948          1.1     skrll 	  /* Unconditional Branch and Call instructions.  */
   1949          1.1     skrll 	  if (insn.operand_type[0]->immediate.resolved == 1)
   1950          1.1     skrll 	    {
   1951          1.1     skrll 	      if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
   1952      1.1.1.2  christos 		as_warn (_("first operand is too large for a 24-bit displacement"));
   1953          1.1     skrll 	      insn.opcode |=
   1954          1.1     skrll 		(insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
   1955          1.1     skrll 	      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1956          1.1     skrll 	    }
   1957          1.1     skrll 	  else
   1958          1.1     skrll 	    {
   1959          1.1     skrll 	      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1960          1.1     skrll 	      fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
   1961          1.1     skrll 			   & insn.operand_type[0]->immediate.imm_expr, 0, 0);
   1962          1.1     skrll 	    }
   1963          1.1     skrll 	}
   1964          1.1     skrll       else if (insn.tm->operand_types[0] & NotReq)
   1965          1.1     skrll 	/* Check for NOP instruction without arguments.  */
   1966          1.1     skrll 	md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1967          1.1     skrll 
   1968          1.1     skrll       else if (insn.tm->operands == 0)
   1969          1.1     skrll 	/* Check for instructions without operands.  */
   1970          1.1     skrll 	md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
   1971          1.1     skrll     }
   1972          1.1     skrll   debug ("Addressing mode: %08X\n", insn.addressing_mode);
   1973          1.1     skrll   {
   1974          1.1     skrll     unsigned int i;
   1975          1.1     skrll 
   1976          1.1     skrll     for (i = 0; i < insn.operands; i++)
   1977          1.1     skrll       {
   1978      1.1.1.8  christos 	free (insn.operand_type[i]->immediate.label);
   1979          1.1     skrll 	free (insn.operand_type[i]);
   1980          1.1     skrll       }
   1981          1.1     skrll   }
   1982          1.1     skrll   debug ("Final opcode: %08X\n", insn.opcode);
   1983          1.1     skrll   debug ("\n");
   1984          1.1     skrll }
   1985