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