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