Home | History | Annotate | Line # | Download | only in config
tc-cr16.c revision 1.8
      1  1.1  christos /* tc-cr16.c -- Assembler code for the CR16 CPU core.
      2  1.8  christos    Copyright (C) 2007-2022 Free Software Foundation, Inc.
      3  1.1  christos 
      4  1.1  christos    Contributed by M R Swami Reddy <MR.Swami.Reddy (at) nsc.com>
      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
     20  1.1  christos    Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
     21  1.1  christos    MA 02110-1301, USA.  */
     22  1.1  christos 
     23  1.1  christos #include "as.h"
     24  1.1  christos #include "safe-ctype.h"
     25  1.1  christos #include "dwarf2dbg.h"
     26  1.1  christos #include "opcode/cr16.h"
     27  1.1  christos #include "elf/cr16.h"
     28  1.1  christos 
     29  1.8  christos #include <limits.h>
     30  1.8  christos #ifndef CHAR_BIT
     31  1.8  christos #define CHAR_BIT 8
     32  1.8  christos #endif
     33  1.1  christos 
     34  1.1  christos /* Word is considered here as a 16-bit unsigned short int.  */
     35  1.1  christos #define WORD_SHIFT  16
     36  1.1  christos 
     37  1.1  christos /* Register is 2-byte size.  */
     38  1.1  christos #define REG_SIZE   2
     39  1.1  christos 
     40  1.1  christos /* Maximum size of a single instruction (in words).  */
     41  1.1  christos #define INSN_MAX_SIZE   3
     42  1.1  christos 
     43  1.1  christos /* Maximum bits which may be set in a `mask16' operand.  */
     44  1.1  christos #define MAX_REGS_IN_MASK16  8
     45  1.1  christos 
     46  1.1  christos /* Assign a number NUM, shifted by SHIFT bytes, into a location
     47  1.1  christos    pointed by index BYTE of array 'output_opcode'.  */
     48  1.8  christos #define CR16_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM) << (SHIFT)
     49  1.1  christos 
     50  1.1  christos /* Operand errors.  */
     51  1.1  christos typedef enum
     52  1.1  christos   {
     53  1.1  christos     OP_LEGAL = 0,       /* Legal operand.  */
     54  1.1  christos     OP_OUT_OF_RANGE,    /* Operand not within permitted range.  */
     55  1.1  christos     OP_NOT_EVEN         /* Operand is Odd number, should be even.  */
     56  1.1  christos   }
     57  1.1  christos op_err;
     58  1.1  christos 
     59  1.1  christos /* Opcode mnemonics hash table.  */
     60  1.8  christos static htab_t cr16_inst_hash;
     61  1.1  christos /* CR16 registers hash table.  */
     62  1.8  christos static htab_t reg_hash;
     63  1.1  christos /* CR16 register pair hash table.  */
     64  1.8  christos static htab_t regp_hash;
     65  1.1  christos /* CR16 processor registers hash table.  */
     66  1.8  christos static htab_t preg_hash;
     67  1.1  christos /* CR16 processor registers 32 bit hash table.  */
     68  1.8  christos static htab_t pregp_hash;
     69  1.1  christos /* Current instruction we're assembling.  */
     70  1.1  christos const inst *instruction;
     71  1.1  christos 
     72  1.1  christos 
     73  1.1  christos static int code_label = 0;
     74  1.1  christos 
     75  1.1  christos /* Global variables.  */
     76  1.1  christos 
     77  1.1  christos /* Array to hold an instruction encoding.  */
     78  1.1  christos long output_opcode[2];
     79  1.1  christos 
     80  1.1  christos /* Nonzero means a relocatable symbol.  */
     81  1.1  christos int relocatable;
     82  1.1  christos 
     83  1.1  christos /* A copy of the original instruction (used in error messages).  */
     84  1.1  christos char ins_parse[MAX_INST_LEN];
     85  1.1  christos 
     86  1.1  christos /* The current processed argument number.  */
     87  1.1  christos int cur_arg_num;
     88  1.1  christos 
     89  1.1  christos /* Generic assembler global variables which must be defined by all targets.  */
     90  1.1  christos 
     91  1.1  christos /* Characters which always start a comment.  */
     92  1.1  christos const char comment_chars[] = "#";
     93  1.1  christos 
     94  1.1  christos /* Characters which start a comment at the beginning of a line.  */
     95  1.1  christos const char line_comment_chars[] = "#";
     96  1.1  christos 
     97  1.1  christos /* This array holds machine specific line separator characters.  */
     98  1.1  christos const char line_separator_chars[] = ";";
     99  1.1  christos 
    100  1.1  christos /* Chars that can be used to separate mant from exp in floating point nums.  */
    101  1.1  christos const char EXP_CHARS[] = "eE";
    102  1.1  christos 
    103  1.1  christos /* Chars that mean this number is a floating point constant as in 0f12.456  */
    104  1.1  christos const char FLT_CHARS[] = "f'";
    105  1.1  christos 
    106  1.1  christos #ifdef OBJ_ELF
    107  1.1  christos /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
    108  1.1  christos symbolS * GOT_symbol;
    109  1.1  christos #endif
    110  1.1  christos 
    111  1.1  christos /* Target-specific multicharacter options, not const-declared at usage.  */
    112  1.1  christos const char *md_shortopts = "";
    113  1.1  christos struct option md_longopts[] =
    114  1.1  christos {
    115  1.1  christos   {NULL, no_argument, NULL, 0}
    116  1.1  christos };
    117  1.1  christos size_t md_longopts_size = sizeof (md_longopts);
    118  1.1  christos 
    119  1.1  christos static void
    120  1.1  christos l_cons (int nbytes)
    121  1.1  christos {
    122  1.1  christos   int c;
    123  1.1  christos   expressionS exp;
    124  1.1  christos 
    125  1.1  christos #ifdef md_flush_pending_output
    126  1.8  christos   md_flush_pending_output ();
    127  1.1  christos #endif
    128  1.1  christos 
    129  1.1  christos   if (is_it_end_of_statement ())
    130  1.1  christos     {
    131  1.1  christos       demand_empty_rest_of_line ();
    132  1.1  christos       return;
    133  1.1  christos     }
    134  1.1  christos 
    135  1.1  christos #ifdef TC_ADDRESS_BYTES
    136  1.1  christos   if (nbytes == 0)
    137  1.1  christos     nbytes = TC_ADDRESS_BYTES ();
    138  1.1  christos #endif
    139  1.1  christos 
    140  1.1  christos #ifdef md_cons_align
    141  1.1  christos   md_cons_align (nbytes);
    142  1.1  christos #endif
    143  1.1  christos 
    144  1.1  christos   c = 0;
    145  1.1  christos   do
    146  1.1  christos     {
    147  1.1  christos       unsigned int bits_available = BITS_PER_CHAR * nbytes;
    148  1.1  christos       char *hold = input_line_pointer;
    149  1.1  christos 
    150  1.1  christos       expression (&exp);
    151  1.1  christos 
    152  1.1  christos       if (*input_line_pointer == ':')
    153  1.8  christos 	{
    154  1.8  christos 	  /* Bitfields.  */
    155  1.8  christos 	  long value = 0;
    156  1.8  christos 
    157  1.8  christos 	  for (;;)
    158  1.8  christos 	    {
    159  1.8  christos 	      unsigned long width;
    160  1.8  christos 
    161  1.8  christos 	      if (*input_line_pointer != ':')
    162  1.8  christos 		{
    163  1.8  christos 		  input_line_pointer = hold;
    164  1.8  christos 		  break;
    165  1.8  christos 		}
    166  1.8  christos 	      if (exp.X_op == O_absent)
    167  1.8  christos 		{
    168  1.8  christos 		  as_warn (_("using a bit field width of zero"));
    169  1.8  christos 		  exp.X_add_number = 0;
    170  1.8  christos 		  exp.X_op = O_constant;
    171  1.8  christos 		}
    172  1.8  christos 
    173  1.8  christos 	      if (exp.X_op != O_constant)
    174  1.8  christos 		{
    175  1.8  christos 		  *input_line_pointer = '\0';
    176  1.8  christos 		  as_bad (_("field width \"%s\" too complex for a bitfield"),
    177  1.8  christos 			  hold);
    178  1.8  christos 		  *input_line_pointer = ':';
    179  1.8  christos 		  demand_empty_rest_of_line ();
    180  1.8  christos 		  return;
    181  1.8  christos 		}
    182  1.8  christos 
    183  1.8  christos 	      if ((width = exp.X_add_number) >
    184  1.8  christos 		  (unsigned int)(BITS_PER_CHAR * nbytes))
    185  1.8  christos 		{
    186  1.6  christos 		  as_warn (ngettext ("field width %lu too big to fit in %d"
    187  1.6  christos 				     " byte: truncated to %d bits",
    188  1.6  christos 				     "field width %lu too big to fit in %d"
    189  1.6  christos 				     " bytes: truncated to %d bits",
    190  1.6  christos 				     nbytes),
    191  1.6  christos 			   width, nbytes, (BITS_PER_CHAR * nbytes));
    192  1.8  christos 		  width = BITS_PER_CHAR * nbytes;
    193  1.8  christos 		}
    194  1.8  christos 
    195  1.8  christos 	      if (width > bits_available)
    196  1.8  christos 		{
    197  1.8  christos 		  /* FIXME-SOMEDAY: backing up and reparsing is wasteful.  */
    198  1.8  christos 		  input_line_pointer = hold;
    199  1.8  christos 		  exp.X_add_number = value;
    200  1.8  christos 		  break;
    201  1.8  christos 		}
    202  1.8  christos 
    203  1.8  christos 	      /* Skip ':'.  */
    204  1.8  christos 	      hold = ++input_line_pointer;
    205  1.8  christos 
    206  1.8  christos 	      expression (&exp);
    207  1.8  christos 	      if (exp.X_op != O_constant)
    208  1.8  christos 		{
    209  1.8  christos 		  char cache = *input_line_pointer;
    210  1.8  christos 
    211  1.8  christos 		  *input_line_pointer = '\0';
    212  1.8  christos 		  as_bad (_("field value \"%s\" too complex for a bitfield"),
    213  1.8  christos 			  hold);
    214  1.8  christos 		  *input_line_pointer = cache;
    215  1.8  christos 		  demand_empty_rest_of_line ();
    216  1.8  christos 		  return;
    217  1.8  christos 		}
    218  1.8  christos 
    219  1.8  christos 	      value |= ((~(-(1 << width)) & exp.X_add_number)
    220  1.8  christos 			<< ((BITS_PER_CHAR * nbytes) - bits_available));
    221  1.8  christos 
    222  1.8  christos 	      if ((bits_available -= width) == 0
    223  1.8  christos 		  || is_it_end_of_statement ()
    224  1.8  christos 		  || *input_line_pointer != ',')
    225  1.8  christos 		break;
    226  1.1  christos 
    227  1.8  christos 	      hold = ++input_line_pointer;
    228  1.8  christos 	      expression (&exp);
    229  1.8  christos 	    }
    230  1.1  christos 
    231  1.8  christos 	  exp.X_add_number = value;
    232  1.8  christos 	  exp.X_op = O_constant;
    233  1.8  christos 	  exp.X_unsigned = 1;
    234  1.8  christos 	}
    235  1.1  christos 
    236  1.1  christos       if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
    237  1.8  christos 	code_label = 1;
    238  1.1  christos       emit_expr (&exp, (unsigned int) nbytes);
    239  1.1  christos       ++c;
    240  1.1  christos       if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
    241  1.8  christos 	{
    242  1.8  christos 	  input_line_pointer +=3;
    243  1.8  christos 	  break;
    244  1.8  christos 	}
    245  1.1  christos     }
    246  1.1  christos   while ((*input_line_pointer++ == ','));
    247  1.1  christos 
    248  1.1  christos   /* Put terminator back into stream.  */
    249  1.1  christos   input_line_pointer--;
    250  1.1  christos 
    251  1.1  christos   demand_empty_rest_of_line ();
    252  1.1  christos }
    253  1.1  christos 
    254  1.1  christos /* This table describes all the machine specific pseudo-ops
    255  1.1  christos    the assembler has to support.  The fields are:
    256  1.1  christos    *** Pseudo-op name without dot.
    257  1.1  christos    *** Function to call to execute this pseudo-op.
    258  1.1  christos    *** Integer arg to pass to the function.  */
    259  1.1  christos 
    260  1.1  christos const pseudo_typeS md_pseudo_table[] =
    261  1.1  christos {
    262  1.1  christos   /* In CR16 machine, align is in bytes (not a ptwo boundary).  */
    263  1.1  christos   {"align", s_align_bytes, 0},
    264  1.1  christos   {"long", l_cons,  4 },
    265  1.1  christos   {"4byte", l_cons, 4 },
    266  1.1  christos   {0, 0, 0}
    267  1.1  christos };
    268  1.1  christos 
    269  1.1  christos /* CR16 relaxation table.  */
    270  1.1  christos const relax_typeS md_relax_table[] =
    271  1.1  christos {
    272  1.1  christos   /* bCC  */
    273  1.1  christos   {0x7f, -0x80, 2, 1},                  /*  8 */
    274  1.1  christos   {0xfffe, -0x10000, 4, 2},             /* 16 */
    275  1.1  christos   {0xfffffe, -0x1000000, 6, 0},         /* 24 */
    276  1.1  christos };
    277  1.1  christos 
    278  1.1  christos /* Return the bit size for a given operand.  */
    279  1.1  christos 
    280  1.1  christos static int
    281  1.1  christos get_opbits (operand_type op)
    282  1.1  christos {
    283  1.1  christos   if (op < MAX_OPRD)
    284  1.1  christos     return cr16_optab[op].bit_size;
    285  1.1  christos 
    286  1.1  christos   return 0;
    287  1.1  christos }
    288  1.1  christos 
    289  1.1  christos /* Return the argument type of a given operand.  */
    290  1.1  christos 
    291  1.1  christos static argtype
    292  1.1  christos get_optype (operand_type op)
    293  1.1  christos {
    294  1.1  christos   if (op < MAX_OPRD)
    295  1.1  christos     return cr16_optab[op].arg_type;
    296  1.1  christos   else
    297  1.1  christos     return nullargs;
    298  1.1  christos }
    299  1.1  christos 
    300  1.1  christos /* Return the flags of a given operand.  */
    301  1.1  christos 
    302  1.1  christos static int
    303  1.1  christos get_opflags (operand_type op)
    304  1.1  christos {
    305  1.1  christos   if (op < MAX_OPRD)
    306  1.1  christos     return cr16_optab[op].flags;
    307  1.1  christos 
    308  1.1  christos   return 0;
    309  1.1  christos }
    310  1.1  christos 
    311  1.1  christos /* Get the cc code.  */
    312  1.1  christos 
    313  1.1  christos static int
    314  1.1  christos get_cc (char *cc_name)
    315  1.1  christos {
    316  1.1  christos    unsigned int i;
    317  1.1  christos 
    318  1.1  christos    for (i = 0; i < cr16_num_cc; i++)
    319  1.1  christos      if (strcmp (cc_name, cr16_b_cond_tab[i]) == 0)
    320  1.1  christos        return i;
    321  1.1  christos 
    322  1.1  christos    return -1;
    323  1.1  christos }
    324  1.1  christos 
    325  1.1  christos /* Get the core processor register 'reg_name'.  */
    326  1.1  christos 
    327  1.1  christos static reg
    328  1.1  christos get_register (char *reg_name)
    329  1.1  christos {
    330  1.1  christos   const reg_entry *rreg;
    331  1.1  christos 
    332  1.8  christos   rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
    333  1.1  christos 
    334  1.1  christos   if (rreg != NULL)
    335  1.1  christos     return rreg->value.reg_val;
    336  1.1  christos 
    337  1.1  christos   return nullregister;
    338  1.1  christos }
    339  1.1  christos /* Get the core processor register-pair 'reg_name'.  */
    340  1.1  christos 
    341  1.1  christos static reg
    342  1.1  christos get_register_pair (char *reg_name)
    343  1.1  christos {
    344  1.1  christos   const reg_entry *rreg;
    345  1.1  christos   char tmp_rp[16]="\0";
    346  1.1  christos 
    347  1.6  christos   /* Add '(' and ')' to the reg pair, if it's not present.  */
    348  1.3  christos   if (reg_name[0] != '(')
    349  1.1  christos     {
    350  1.1  christos       tmp_rp[0] = '(';
    351  1.1  christos       strcat (tmp_rp, reg_name);
    352  1.1  christos       strcat (tmp_rp,")");
    353  1.8  christos       rreg = (const reg_entry *) str_hash_find (regp_hash, tmp_rp);
    354  1.1  christos     }
    355  1.1  christos   else
    356  1.8  christos     rreg = (const reg_entry *) str_hash_find (regp_hash, reg_name);
    357  1.1  christos 
    358  1.1  christos   if (rreg != NULL)
    359  1.1  christos     return rreg->value.reg_val;
    360  1.1  christos 
    361  1.1  christos   return nullregister;
    362  1.3  christos }
    363  1.1  christos 
    364  1.1  christos /* Get the index register 'reg_name'.  */
    365  1.1  christos 
    366  1.1  christos static reg
    367  1.1  christos get_index_register (char *reg_name)
    368  1.1  christos {
    369  1.1  christos   const reg_entry *rreg;
    370  1.1  christos 
    371  1.8  christos   rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
    372  1.1  christos 
    373  1.1  christos   if ((rreg != NULL)
    374  1.1  christos       && ((rreg->value.reg_val == 12) || (rreg->value.reg_val == 13)))
    375  1.1  christos     return rreg->value.reg_val;
    376  1.1  christos 
    377  1.1  christos   return nullregister;
    378  1.1  christos }
    379  1.1  christos /* Get the core processor index register-pair 'reg_name'.  */
    380  1.1  christos 
    381  1.1  christos static reg
    382  1.1  christos get_index_register_pair (char *reg_name)
    383  1.1  christos {
    384  1.1  christos   const reg_entry *rreg;
    385  1.1  christos 
    386  1.8  christos   rreg = (const reg_entry *) str_hash_find (regp_hash, reg_name);
    387  1.1  christos 
    388  1.1  christos   if (rreg != NULL)
    389  1.1  christos     {
    390  1.1  christos       if ((rreg->value.reg_val != 1) || (rreg->value.reg_val != 7)
    391  1.8  christos 	  || (rreg->value.reg_val != 9) || (rreg->value.reg_val > 10))
    392  1.8  christos 	return rreg->value.reg_val;
    393  1.1  christos 
    394  1.1  christos       as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg->value.reg_val);
    395  1.1  christos     }
    396  1.1  christos 
    397  1.1  christos   return nullregister;
    398  1.1  christos }
    399  1.1  christos 
    400  1.1  christos /* Get the processor register 'preg_name'.  */
    401  1.1  christos 
    402  1.1  christos static preg
    403  1.1  christos get_pregister (char *preg_name)
    404  1.1  christos {
    405  1.1  christos   const reg_entry *prreg;
    406  1.1  christos 
    407  1.8  christos   prreg = (const reg_entry *) str_hash_find (preg_hash, preg_name);
    408  1.1  christos 
    409  1.1  christos   if (prreg != NULL)
    410  1.1  christos     return prreg->value.preg_val;
    411  1.1  christos 
    412  1.1  christos   return nullpregister;
    413  1.1  christos }
    414  1.1  christos 
    415  1.1  christos /* Get the processor register 'preg_name 32 bit'.  */
    416  1.1  christos 
    417  1.1  christos static preg
    418  1.1  christos get_pregisterp (char *preg_name)
    419  1.1  christos {
    420  1.1  christos   const reg_entry *prreg;
    421  1.1  christos 
    422  1.8  christos   prreg = (const reg_entry *) str_hash_find (pregp_hash, preg_name);
    423  1.1  christos 
    424  1.1  christos   if (prreg != NULL)
    425  1.1  christos     return prreg->value.preg_val;
    426  1.1  christos 
    427  1.1  christos   return nullpregister;
    428  1.1  christos }
    429  1.1  christos 
    430  1.1  christos 
    431  1.1  christos /* Round up a section size to the appropriate boundary.  */
    432  1.1  christos 
    433  1.1  christos valueT
    434  1.1  christos md_section_align (segT seg, valueT val)
    435  1.1  christos {
    436  1.1  christos   /* Round .text section to a multiple of 2.  */
    437  1.1  christos   if (seg == text_section)
    438  1.1  christos     return (val + 1) & ~1;
    439  1.1  christos   return val;
    440  1.1  christos }
    441  1.1  christos 
    442  1.1  christos /* Parse an operand that is machine-specific (remove '*').  */
    443  1.1  christos 
    444  1.1  christos void
    445  1.1  christos md_operand (expressionS * exp)
    446  1.1  christos {
    447  1.1  christos   char c = *input_line_pointer;
    448  1.1  christos 
    449  1.1  christos   switch (c)
    450  1.1  christos     {
    451  1.1  christos     case '*':
    452  1.1  christos       input_line_pointer++;
    453  1.1  christos       expression (exp);
    454  1.1  christos       break;
    455  1.1  christos     default:
    456  1.1  christos       break;
    457  1.1  christos     }
    458  1.1  christos }
    459  1.1  christos 
    460  1.1  christos /* Reset global variables before parsing a new instruction.  */
    461  1.1  christos 
    462  1.1  christos static void
    463  1.1  christos reset_vars (char *op)
    464  1.1  christos {
    465  1.1  christos   cur_arg_num = relocatable = 0;
    466  1.1  christos   memset (& output_opcode, '\0', sizeof (output_opcode));
    467  1.1  christos 
    468  1.1  christos   /* Save a copy of the original OP (used in error messages).  */
    469  1.1  christos   strncpy (ins_parse, op, sizeof ins_parse - 1);
    470  1.1  christos   ins_parse [sizeof ins_parse - 1] = 0;
    471  1.1  christos }
    472  1.1  christos 
    473  1.1  christos /* This macro decides whether a particular reloc is an entry in a
    474  1.1  christos    switch table.  It is used when relaxing, because the linker needs
    475  1.1  christos    to know about all such entries so that it can adjust them if
    476  1.1  christos    necessary.  */
    477  1.1  christos 
    478  1.8  christos #define SWITCH_TABLE(fix)						\
    479  1.8  christos   ((fix)->fx_addsy != NULL						\
    480  1.8  christos    && (fix)->fx_subsy != NULL						\
    481  1.8  christos    && ((fix)->fx_r_type == BFD_RELOC_CR16_NUM8				\
    482  1.8  christos        || (fix)->fx_r_type == BFD_RELOC_CR16_NUM16			\
    483  1.8  christos        || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32			\
    484  1.8  christos        || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32a)			\
    485  1.8  christos    && S_GET_SEGMENT ((fix)->fx_addsy) != undefined_section		\
    486  1.8  christos    && S_GET_SEGMENT ((fix)->fx_addsy) == S_GET_SEGMENT ((fix)->fx_subsy))
    487  1.1  christos 
    488  1.1  christos /* See whether we need to force a relocation into the output file.
    489  1.1  christos    This is used to force out switch and PC relative relocations when
    490  1.1  christos    relaxing.  */
    491  1.1  christos 
    492  1.1  christos int
    493  1.1  christos cr16_force_relocation (fixS *fix)
    494  1.1  christos {
    495  1.1  christos   if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
    496  1.1  christos     return 1;
    497  1.1  christos 
    498  1.1  christos   return 0;
    499  1.1  christos }
    500  1.1  christos 
    501  1.1  christos /* Record a fixup for a cons expression.  */
    502  1.1  christos 
    503  1.1  christos void
    504  1.3  christos cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp,
    505  1.3  christos 		   bfd_reloc_code_real_type rtype)
    506  1.1  christos {
    507  1.1  christos   switch (len)
    508  1.1  christos     {
    509  1.1  christos     default: rtype = BFD_RELOC_NONE; break;
    510  1.1  christos     case 1: rtype = BFD_RELOC_CR16_NUM8 ; break;
    511  1.1  christos     case 2: rtype = BFD_RELOC_CR16_NUM16; break;
    512  1.1  christos     case 4:
    513  1.1  christos       if (code_label)
    514  1.8  christos 	{
    515  1.8  christos 	  rtype = BFD_RELOC_CR16_NUM32a;
    516  1.8  christos 	  code_label = 0;
    517  1.8  christos 	}
    518  1.1  christos       else
    519  1.8  christos 	rtype = BFD_RELOC_CR16_NUM32;
    520  1.1  christos       break;
    521  1.1  christos     }
    522  1.1  christos 
    523  1.1  christos   fix_new_exp (frag, offset, len, exp, 0, rtype);
    524  1.1  christos }
    525  1.1  christos 
    526  1.1  christos /* Generate a relocation entry for a fixup.  */
    527  1.1  christos 
    528  1.1  christos arelent *
    529  1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
    530  1.1  christos {
    531  1.1  christos   arelent * reloc;
    532  1.1  christos 
    533  1.1  christos   /* If symbols are local and resolved, then no relocation needed.  */
    534  1.3  christos   if ( ((fixP->fx_addsy)
    535  1.8  christos 	&& (S_GET_SEGMENT (fixP->fx_addsy) == absolute_section))
    536  1.3  christos        || ((fixP->fx_subsy)
    537  1.1  christos 	   && (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)))
    538  1.8  christos     return NULL;
    539  1.1  christos 
    540  1.5  christos   reloc = XNEW (arelent);
    541  1.5  christos   reloc->sym_ptr_ptr  = XNEW (asymbol *);
    542  1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
    543  1.1  christos   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
    544  1.1  christos   reloc->addend = fixP->fx_offset;
    545  1.1  christos 
    546  1.1  christos   if (fixP->fx_subsy != NULL)
    547  1.1  christos     {
    548  1.1  christos       if (SWITCH_TABLE (fixP))
    549  1.8  christos 	{
    550  1.8  christos 	  /* Keep the current difference in the addend.  */
    551  1.8  christos 	  reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
    552  1.8  christos 			   - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
    553  1.8  christos 
    554  1.8  christos 	  switch (fixP->fx_r_type)
    555  1.8  christos 	    {
    556  1.8  christos 	    case BFD_RELOC_CR16_NUM8:
    557  1.8  christos 	      fixP->fx_r_type = BFD_RELOC_CR16_SWITCH8;
    558  1.8  christos 	      break;
    559  1.8  christos 	    case BFD_RELOC_CR16_NUM16:
    560  1.8  christos 	      fixP->fx_r_type = BFD_RELOC_CR16_SWITCH16;
    561  1.8  christos 	      break;
    562  1.8  christos 	    case BFD_RELOC_CR16_NUM32:
    563  1.8  christos 	      fixP->fx_r_type = BFD_RELOC_CR16_SWITCH32;
    564  1.8  christos 	      break;
    565  1.8  christos 	    case BFD_RELOC_CR16_NUM32a:
    566  1.8  christos 	      fixP->fx_r_type = BFD_RELOC_CR16_NUM32a;
    567  1.8  christos 	      break;
    568  1.8  christos 	    default:
    569  1.8  christos 	      abort ();
    570  1.8  christos 	      break;
    571  1.8  christos 	    }
    572  1.8  christos 	}
    573  1.1  christos       else
    574  1.8  christos 	{
    575  1.8  christos 	  /* We only resolve difference expressions in the same section.  */
    576  1.8  christos 	  as_bad_subtract (fixP);
    577  1.8  christos 	  free (reloc->sym_ptr_ptr);
    578  1.8  christos 	  free (reloc);
    579  1.8  christos 	  return NULL;
    580  1.8  christos 	}
    581  1.1  christos     }
    582  1.1  christos #ifdef OBJ_ELF
    583  1.8  christos   if ((fixP->fx_r_type == BFD_RELOC_CR16_GOT_REGREL20)
    584  1.8  christos       && GOT_symbol
    585  1.8  christos       && fixP->fx_addsy == GOT_symbol)
    586  1.8  christos     {
    587  1.8  christos       reloc->addend = fixP->fx_offset = reloc->address;
    588  1.8  christos     }
    589  1.8  christos   else if ((fixP->fx_r_type == BFD_RELOC_CR16_GOTC_REGREL20)
    590  1.8  christos 	   && GOT_symbol
    591  1.1  christos 	   && fixP->fx_addsy == GOT_symbol)
    592  1.8  christos     {
    593  1.8  christos       reloc->addend = fixP->fx_offset = reloc->address;
    594  1.8  christos     }
    595  1.1  christos #endif
    596  1.1  christos 
    597  1.1  christos   gas_assert ((int) fixP->fx_r_type > 0);
    598  1.1  christos   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
    599  1.1  christos 
    600  1.1  christos   if (reloc->howto == NULL)
    601  1.1  christos     {
    602  1.1  christos       as_bad_where (fixP->fx_file, fixP->fx_line,
    603  1.8  christos 		    _("internal error: reloc %d (`%s') not supported by object file format"),
    604  1.8  christos 		    fixP->fx_r_type,
    605  1.8  christos 		    bfd_get_reloc_code_name (fixP->fx_r_type));
    606  1.1  christos       return NULL;
    607  1.1  christos     }
    608  1.1  christos   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
    609  1.1  christos 
    610  1.1  christos   return reloc;
    611  1.1  christos }
    612  1.1  christos 
    613  1.1  christos /* Prepare machine-dependent frags for relaxation.  */
    614  1.1  christos 
    615  1.1  christos int
    616  1.1  christos md_estimate_size_before_relax (fragS *fragp, asection *seg)
    617  1.1  christos {
    618  1.1  christos   /* If symbol is undefined or located in a different section,
    619  1.1  christos      select the largest supported relocation.  */
    620  1.1  christos   relax_substateT subtype;
    621  1.1  christos   relax_substateT rlx_state[] = {0, 2};
    622  1.1  christos 
    623  1.1  christos   for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
    624  1.1  christos     {
    625  1.1  christos       if (fragp->fr_subtype == rlx_state[subtype]
    626  1.8  christos 	  && (!S_IS_DEFINED (fragp->fr_symbol)
    627  1.8  christos 	      || seg != S_GET_SEGMENT (fragp->fr_symbol)))
    628  1.8  christos 	{
    629  1.8  christos 	  fragp->fr_subtype = rlx_state[subtype + 1];
    630  1.8  christos 	  break;
    631  1.8  christos 	}
    632  1.1  christos     }
    633  1.1  christos 
    634  1.1  christos   if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
    635  1.1  christos     abort ();
    636  1.1  christos 
    637  1.1  christos   return md_relax_table[fragp->fr_subtype].rlx_length;
    638  1.1  christos }
    639  1.1  christos 
    640  1.1  christos void
    641  1.1  christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
    642  1.1  christos {
    643  1.1  christos   /* 'opcode' points to the start of the instruction, whether
    644  1.1  christos      we need to change the instruction's fixed encoding.  */
    645  1.8  christos   char *opcode = &fragP->fr_literal[0] + fragP->fr_fix;
    646  1.1  christos   bfd_reloc_code_real_type reloc;
    647  1.1  christos 
    648  1.1  christos   subseg_change (sec, 0);
    649  1.1  christos 
    650  1.1  christos   switch (fragP->fr_subtype)
    651  1.1  christos     {
    652  1.1  christos     case 0:
    653  1.1  christos       reloc = BFD_RELOC_CR16_DISP8;
    654  1.1  christos       break;
    655  1.1  christos     case 1:
    656  1.1  christos       /* If the subtype is not changed due to :m operand qualifier,
    657  1.8  christos 	 then no need to update the opcode value.  */
    658  1.1  christos       if ((int)opcode[1] != 0x18)
    659  1.8  christos 	{
    660  1.8  christos 	  opcode[0] = (opcode[0] & 0xf0);
    661  1.8  christos 	  opcode[1] = 0x18;
    662  1.8  christos 	}
    663  1.1  christos       reloc = BFD_RELOC_CR16_DISP16;
    664  1.1  christos       break;
    665  1.1  christos     case 2:
    666  1.1  christos       /* If the subtype is not changed due to :l operand qualifier,
    667  1.8  christos 	 then no need to update the opcode value.  */
    668  1.1  christos       if ((int)opcode[1] != 0)
    669  1.8  christos 	{
    670  1.8  christos 	  opcode[2] = opcode[0];
    671  1.8  christos 	  opcode[0] = opcode[1];
    672  1.8  christos 	  opcode[1] = 0x0;
    673  1.8  christos 	}
    674  1.1  christos       reloc = BFD_RELOC_CR16_DISP24;
    675  1.1  christos       break;
    676  1.1  christos     default:
    677  1.1  christos       abort();
    678  1.1  christos     }
    679  1.1  christos 
    680  1.1  christos   fix_new (fragP, fragP->fr_fix,
    681  1.8  christos 	   bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
    682  1.8  christos 	   fragP->fr_symbol, fragP->fr_offset, 1, reloc);
    683  1.1  christos   fragP->fr_var = 0;
    684  1.1  christos   fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
    685  1.1  christos }
    686  1.1  christos 
    687  1.1  christos symbolS *
    688  1.1  christos md_undefined_symbol (char *name)
    689  1.1  christos {
    690  1.1  christos   if (*name == '_' && *(name + 1) == 'G'
    691  1.1  christos       && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
    692  1.8  christos     {
    693  1.8  christos       if (!GOT_symbol)
    694  1.8  christos 	{
    695  1.8  christos 	  if (symbol_find (name))
    696  1.8  christos 	    as_bad (_("GOT already in symbol table"));
    697  1.8  christos 	  GOT_symbol = symbol_new (name, undefined_section,
    698  1.8  christos 				   &zero_address_frag, 0);
    699  1.8  christos 	}
    700  1.8  christos       return GOT_symbol;
    701  1.8  christos     }
    702  1.1  christos   return 0;
    703  1.1  christos }
    704  1.1  christos 
    705  1.1  christos /* Process machine-dependent command line options.  Called once for
    706  1.1  christos    each option on the command line that the machine-independent part of
    707  1.1  christos    GAS does not understand.  */
    708  1.1  christos 
    709  1.1  christos int
    710  1.5  christos md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
    711  1.1  christos {
    712  1.1  christos   return 0;
    713  1.1  christos }
    714  1.1  christos 
    715  1.1  christos /* Machine-dependent usage-output.  */
    716  1.1  christos 
    717  1.1  christos void
    718  1.1  christos md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
    719  1.1  christos {
    720  1.1  christos   return;
    721  1.1  christos }
    722  1.1  christos 
    723  1.5  christos const char *
    724  1.1  christos md_atof (int type, char *litP, int *sizeP)
    725  1.1  christos {
    726  1.1  christos   return ieee_md_atof (type, litP, sizeP, target_big_endian);
    727  1.1  christos }
    728  1.1  christos 
    729  1.1  christos /* Apply a fixS (fixup of an instruction or data that we didn't have
    730  1.1  christos    enough info to complete immediately) to the data in a frag.
    731  1.1  christos    Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
    732  1.1  christos    relaxation of debug sections, this function is called only when
    733  1.1  christos    fixuping relocations of debug sections.  */
    734  1.1  christos 
    735  1.1  christos void
    736  1.1  christos md_apply_fix (fixS *fixP, valueT *valP, segT seg)
    737  1.1  christos {
    738  1.1  christos   valueT val = * valP;
    739  1.1  christos 
    740  1.1  christos   if (fixP->fx_addsy == NULL
    741  1.1  christos       && fixP->fx_pcrel == 0)
    742  1.1  christos     fixP->fx_done = 1;
    743  1.1  christos   else if (fixP->fx_pcrel == 1
    744  1.1  christos       && fixP->fx_addsy != NULL
    745  1.1  christos       && S_GET_SEGMENT (fixP->fx_addsy) == seg)
    746  1.1  christos     fixP->fx_done = 1;
    747  1.1  christos   else
    748  1.1  christos     fixP->fx_done = 0;
    749  1.1  christos 
    750  1.1  christos   if (fixP->fx_addsy != NULL && !fixP->fx_pcrel)
    751  1.1  christos     {
    752  1.1  christos       val = fixP->fx_offset;
    753  1.1  christos       fixP->fx_done = 1;
    754  1.1  christos     }
    755  1.1  christos 
    756  1.1  christos   if (fixP->fx_done)
    757  1.1  christos     {
    758  1.1  christos       char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
    759  1.1  christos 
    760  1.1  christos       fixP->fx_offset = 0;
    761  1.1  christos 
    762  1.1  christos       switch (fixP->fx_r_type)
    763  1.1  christos 	{
    764  1.1  christos 	case BFD_RELOC_CR16_NUM8:
    765  1.1  christos 	  bfd_put_8 (stdoutput, (unsigned char) val, buf);
    766  1.1  christos 	  break;
    767  1.1  christos 	case BFD_RELOC_CR16_NUM16:
    768  1.1  christos 	  bfd_put_16 (stdoutput, val, buf);
    769  1.1  christos 	  break;
    770  1.1  christos 	case BFD_RELOC_CR16_NUM32:
    771  1.1  christos 	  bfd_put_32 (stdoutput, val, buf);
    772  1.1  christos 	  break;
    773  1.1  christos 	case BFD_RELOC_CR16_NUM32a:
    774  1.1  christos 	  bfd_put_32 (stdoutput, val, buf);
    775  1.1  christos 	  break;
    776  1.1  christos 	default:
    777  1.1  christos 	  /* We shouldn't ever get here because linkrelax is nonzero.  */
    778  1.1  christos 	  abort ();
    779  1.1  christos 	  break;
    780  1.1  christos 	}
    781  1.1  christos       fixP->fx_done = 0;
    782  1.1  christos     }
    783  1.1  christos   else
    784  1.1  christos     fixP->fx_offset = * valP;
    785  1.1  christos }
    786  1.1  christos 
    787  1.1  christos /* The location from which a PC relative jump should be calculated,
    788  1.1  christos    given a PC relative reloc.  */
    789  1.1  christos 
    790  1.1  christos long
    791  1.1  christos md_pcrel_from (fixS *fixp)
    792  1.1  christos {
    793  1.1  christos   return fixp->fx_frag->fr_address + fixp->fx_where;
    794  1.1  christos }
    795  1.1  christos 
    796  1.1  christos static void
    797  1.8  christos initialise_reg_hash_table (htab_t *hash_table,
    798  1.8  christos 			   const reg_entry *register_table,
    799  1.8  christos 			   const unsigned int num_entries)
    800  1.1  christos {
    801  1.8  christos   const reg_entry *rreg;
    802  1.1  christos 
    803  1.8  christos   *hash_table = str_htab_create ();
    804  1.1  christos 
    805  1.1  christos   for (rreg = register_table;
    806  1.1  christos        rreg < (register_table + num_entries);
    807  1.1  christos        rreg++)
    808  1.8  christos     if (str_hash_insert (*hash_table, rreg->name, rreg, 0) != NULL)
    809  1.8  christos       as_fatal (_("duplicate %s"), rreg->name);
    810  1.1  christos }
    811  1.1  christos 
    812  1.1  christos /* This function is called once, at assembler startup time.  This should
    813  1.1  christos    set up all the tables, etc that the MD part of the assembler needs.  */
    814  1.1  christos 
    815  1.1  christos void
    816  1.1  christos md_begin (void)
    817  1.1  christos {
    818  1.1  christos   int i = 0;
    819  1.1  christos 
    820  1.1  christos   /* Set up a hash table for the instructions.  */
    821  1.8  christos   cr16_inst_hash = str_htab_create ();
    822  1.1  christos 
    823  1.1  christos   while (cr16_instruction[i].mnemonic != NULL)
    824  1.1  christos     {
    825  1.1  christos       const char *mnemonic = cr16_instruction[i].mnemonic;
    826  1.1  christos 
    827  1.8  christos       if (str_hash_insert (cr16_inst_hash, mnemonic, cr16_instruction + i, 0))
    828  1.8  christos 	as_fatal (_("duplicate %s"), mnemonic);
    829  1.1  christos 
    830  1.1  christos       /* Insert unique names into hash table.  The CR16 instruction set
    831  1.8  christos 	 has many identical opcode names that have different opcodes based
    832  1.8  christos 	 on the operands.  This hash table then provides a quick index to
    833  1.8  christos 	 the first opcode with a particular name in the opcode table.  */
    834  1.1  christos       do
    835  1.8  christos 	{
    836  1.8  christos 	  ++i;
    837  1.8  christos 	}
    838  1.1  christos       while (cr16_instruction[i].mnemonic != NULL
    839  1.8  christos 	     && streq (cr16_instruction[i].mnemonic, mnemonic));
    840  1.1  christos     }
    841  1.1  christos 
    842  1.1  christos   /* Initialize reg_hash hash table.  */
    843  1.1  christos   initialise_reg_hash_table (& reg_hash, cr16_regtab, NUMREGS);
    844  1.1  christos   /* Initialize regp_hash hash table.  */
    845  1.1  christos   initialise_reg_hash_table (& regp_hash, cr16_regptab, NUMREGPS);
    846  1.1  christos   /* Initialize preg_hash hash table.  */
    847  1.1  christos   initialise_reg_hash_table (& preg_hash, cr16_pregtab, NUMPREGS);
    848  1.1  christos   /* Initialize pregp_hash hash table.  */
    849  1.1  christos   initialise_reg_hash_table (& pregp_hash, cr16_pregptab, NUMPREGPS);
    850  1.1  christos 
    851  1.1  christos   /*  Set linkrelax here to avoid fixups in most sections.  */
    852  1.1  christos   linkrelax = 1;
    853  1.1  christos }
    854  1.1  christos 
    855  1.1  christos /* Process constants (immediate/absolute)
    856  1.1  christos    and labels (jump targets/Memory locations).  */
    857  1.1  christos 
    858  1.1  christos static void
    859  1.1  christos process_label_constant (char *str, ins * cr16_ins)
    860  1.1  christos {
    861  1.1  christos   char *saved_input_line_pointer;
    862  1.1  christos   int symbol_with_at = 0;
    863  1.1  christos   int symbol_with_s = 0;
    864  1.1  christos   int symbol_with_m = 0;
    865  1.1  christos   int symbol_with_l = 0;
    866  1.1  christos   int symbol_with_at_got = 0;
    867  1.1  christos   int symbol_with_at_gotc = 0;
    868  1.1  christos   argument *cur_arg = cr16_ins->arg + cur_arg_num;  /* Current argument.  */
    869  1.1  christos 
    870  1.1  christos   saved_input_line_pointer = input_line_pointer;
    871  1.1  christos   input_line_pointer = str;
    872  1.1  christos 
    873  1.1  christos   expression (&cr16_ins->exp);
    874  1.1  christos 
    875  1.1  christos   switch (cr16_ins->exp.X_op)
    876  1.1  christos     {
    877  1.1  christos     case O_big:
    878  1.1  christos     case O_absent:
    879  1.1  christos       /* Missing or bad expr becomes absolute 0.  */
    880  1.1  christos       as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
    881  1.8  christos 	      str);
    882  1.1  christos       cr16_ins->exp.X_op = O_constant;
    883  1.1  christos       cr16_ins->exp.X_add_number = 0;
    884  1.1  christos       cr16_ins->exp.X_add_symbol = NULL;
    885  1.1  christos       cr16_ins->exp.X_op_symbol = NULL;
    886  1.1  christos       /* Fall through.  */
    887  1.1  christos 
    888  1.1  christos     case O_constant:
    889  1.1  christos       cur_arg->X_op = O_constant;
    890  1.1  christos       cur_arg->constant = cr16_ins->exp.X_add_number;
    891  1.1  christos       break;
    892  1.1  christos 
    893  1.1  christos     case O_symbol:
    894  1.1  christos     case O_subtract:
    895  1.1  christos     case O_add:
    896  1.1  christos       cur_arg->X_op = O_symbol;
    897  1.1  christos       cur_arg->constant = cr16_ins->exp.X_add_number;
    898  1.1  christos       cr16_ins->exp.X_add_number = 0;
    899  1.1  christos       cr16_ins->rtype = BFD_RELOC_NONE;
    900  1.1  christos       relocatable = 1;
    901  1.1  christos 
    902  1.8  christos       if (startswith (input_line_pointer, "@c"))
    903  1.8  christos 	symbol_with_at = 1;
    904  1.1  christos 
    905  1.8  christos       if (startswith (input_line_pointer, "@l")
    906  1.8  christos 	  || startswith (input_line_pointer, ":l"))
    907  1.8  christos 	symbol_with_l = 1;
    908  1.8  christos 
    909  1.8  christos       if (startswith (input_line_pointer, "@m")
    910  1.8  christos 	  || startswith (input_line_pointer, ":m"))
    911  1.8  christos 	symbol_with_m = 1;
    912  1.8  christos 
    913  1.8  christos       if (startswith (input_line_pointer, "@s")
    914  1.8  christos 	  || startswith (input_line_pointer, ":s"))
    915  1.8  christos 	symbol_with_s = 1;
    916  1.1  christos 
    917  1.8  christos       if (startswith (input_line_pointer, "@cGOT")
    918  1.8  christos 	  || startswith (input_line_pointer, "@cgot"))
    919  1.1  christos 	{
    920  1.1  christos 	  if (GOT_symbol == NULL)
    921  1.8  christos 	    GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
    922  1.1  christos 
    923  1.8  christos 	  symbol_with_at_gotc = 1;
    924  1.1  christos 	}
    925  1.8  christos       else if (startswith (input_line_pointer, "@GOT")
    926  1.8  christos 	       || startswith (input_line_pointer, "@got"))
    927  1.1  christos 	{
    928  1.8  christos 	  if ((startswith (input_line_pointer, "+"))
    929  1.8  christos 	      || (startswith (input_line_pointer, "-")))
    930  1.8  christos 	    as_warn (_("GOT bad expression with %s."), input_line_pointer);
    931  1.1  christos 
    932  1.1  christos 	  if (GOT_symbol == NULL)
    933  1.8  christos 	    GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
    934  1.1  christos 
    935  1.8  christos 	  symbol_with_at_got = 1;
    936  1.1  christos 	}
    937  1.1  christos 
    938  1.1  christos       switch (cur_arg->type)
    939  1.8  christos 	{
    940  1.8  christos 	case arg_cr:
    941  1.8  christos 	  if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
    942  1.8  christos 	    {
    943  1.1  christos 	      if (symbol_with_at_got)
    944  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
    945  1.1  christos 	      else if (symbol_with_at_gotc)
    946  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
    947  1.1  christos 	      else if (cur_arg->size == 20)
    948  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
    949  1.8  christos 	      else
    950  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
    951  1.1  christos 	    }
    952  1.8  christos 	  break;
    953  1.8  christos 
    954  1.8  christos 	case arg_crp:
    955  1.8  christos 	  if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
    956  1.8  christos 	    {
    957  1.8  christos 	      if (symbol_with_at_got)
    958  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
    959  1.8  christos 	      else if (symbol_with_at_gotc)
    960  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
    961  1.8  christos 	    } else {
    962  1.8  christos 	    switch (instruction->size)
    963  1.8  christos 	      {
    964  1.8  christos 	      case 1:
    965  1.8  christos 		switch (cur_arg->size)
    966  1.8  christos 		  {
    967  1.8  christos 		  case 0:
    968  1.8  christos 		    cr16_ins->rtype = BFD_RELOC_CR16_REGREL0;
    969  1.8  christos 		    break;
    970  1.8  christos 		  case 4:
    971  1.8  christos 		    if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb"))
    972  1.8  christos 		      cr16_ins->rtype = BFD_RELOC_CR16_REGREL4;
    973  1.8  christos 		    else
    974  1.8  christos 		      cr16_ins->rtype = BFD_RELOC_CR16_REGREL4a;
    975  1.8  christos 		    break;
    976  1.8  christos 		  default: break;
    977  1.8  christos 		  }
    978  1.8  christos 		break;
    979  1.8  christos 	      case 2:
    980  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_REGREL16;
    981  1.8  christos 		break;
    982  1.8  christos 	      case 3:
    983  1.8  christos 		if (cur_arg->size == 20)
    984  1.8  christos 		  cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
    985  1.8  christos 		else
    986  1.8  christos 		  cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
    987  1.8  christos 		break;
    988  1.8  christos 	      default:
    989  1.8  christos 		break;
    990  1.8  christos 	      }
    991  1.8  christos 	  }
    992  1.8  christos 	  break;
    993  1.1  christos 
    994  1.8  christos 	case arg_idxr:
    995  1.8  christos 	  if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
    996  1.1  christos 	    {
    997  1.1  christos 	      if (symbol_with_at_got)
    998  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
    999  1.1  christos 	      else if (symbol_with_at_gotc)
   1000  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
   1001  1.1  christos 	      else
   1002  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
   1003  1.1  christos 	    }
   1004  1.8  christos 	  break;
   1005  1.1  christos 
   1006  1.8  christos 	case arg_idxrp:
   1007  1.8  christos 	  if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
   1008  1.1  christos 	    {
   1009  1.8  christos 	      if (symbol_with_at_got)
   1010  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
   1011  1.8  christos 	      else if (symbol_with_at_gotc)
   1012  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
   1013  1.8  christos 	      else {
   1014  1.8  christos 		switch (instruction->size)
   1015  1.8  christos 		  {
   1016  1.8  christos 		  case 1: cr16_ins->rtype = BFD_RELOC_CR16_REGREL0; break;
   1017  1.8  christos 		  case 2: cr16_ins->rtype = BFD_RELOC_CR16_REGREL14; break;
   1018  1.8  christos 		  case 3: cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; break;
   1019  1.8  christos 		  default: break;
   1020  1.8  christos 		  }
   1021  1.8  christos 	      }
   1022  1.1  christos 	    }
   1023  1.8  christos 	  break;
   1024  1.1  christos 
   1025  1.8  christos 	case arg_c:
   1026  1.8  christos 	  if (IS_INSN_MNEMONIC ("bal"))
   1027  1.8  christos 	    cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
   1028  1.8  christos 	  else if (IS_INSN_TYPE (BRANCH_INS))
   1029  1.8  christos 	    {
   1030  1.8  christos 	      if (symbol_with_l)
   1031  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
   1032  1.8  christos 	      else if (symbol_with_m)
   1033  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_DISP16;
   1034  1.8  christos 	      else
   1035  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_DISP8;
   1036  1.8  christos 	    }
   1037  1.8  christos 	  else if (IS_INSN_TYPE (STOR_IMM_INS) || IS_INSN_TYPE (LD_STOR_INS)
   1038  1.8  christos 		   || IS_INSN_TYPE (CSTBIT_INS))
   1039  1.8  christos 	    {
   1040  1.1  christos 	      if (symbol_with_s)
   1041  1.8  christos 		as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num + 1, str);
   1042  1.1  christos 	      if (symbol_with_at_got)
   1043  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
   1044  1.1  christos 	      else if (symbol_with_at_gotc)
   1045  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
   1046  1.1  christos 	      else if (symbol_with_m)
   1047  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_ABS20;
   1048  1.8  christos 	      else /* Default to (symbol_with_l) */
   1049  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_ABS24;
   1050  1.8  christos 	    }
   1051  1.8  christos 	  else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
   1052  1.8  christos 	    cr16_ins->rtype = BFD_RELOC_CR16_DISP4;
   1053  1.8  christos 	  break;
   1054  1.8  christos 
   1055  1.8  christos 	case arg_ic:
   1056  1.8  christos 	  if (IS_INSN_TYPE (ARITH_INS))
   1057  1.8  christos 	    {
   1058  1.1  christos 	      if (symbol_with_at_got)
   1059  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
   1060  1.1  christos 	      else if (symbol_with_at_gotc)
   1061  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
   1062  1.1  christos 	      else if (symbol_with_s)
   1063  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_IMM4;
   1064  1.8  christos 	      else if (symbol_with_m)
   1065  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_IMM20;
   1066  1.8  christos 	      else if (symbol_with_at)
   1067  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_IMM32a;
   1068  1.8  christos 	      else /* Default to (symbol_with_l) */
   1069  1.8  christos 		cr16_ins->rtype = BFD_RELOC_CR16_IMM32;
   1070  1.8  christos 	    }
   1071  1.8  christos 	  else if (IS_INSN_TYPE (ARITH_BYTE_INS))
   1072  1.8  christos 	    {
   1073  1.8  christos 	      cr16_ins->rtype = BFD_RELOC_CR16_IMM16;
   1074  1.8  christos 	    }
   1075  1.8  christos 	  break;
   1076  1.8  christos 	default:
   1077  1.8  christos 	  break;
   1078  1.8  christos 	}
   1079  1.1  christos       break;
   1080  1.1  christos 
   1081  1.1  christos     default:
   1082  1.1  christos       cur_arg->X_op = cr16_ins->exp.X_op;
   1083  1.1  christos       break;
   1084  1.1  christos     }
   1085  1.1  christos 
   1086  1.1  christos   input_line_pointer = saved_input_line_pointer;
   1087  1.1  christos   return;
   1088  1.1  christos }
   1089  1.1  christos 
   1090  1.1  christos /* Retrieve the opcode image of a given register.
   1091  1.1  christos    If the register is illegal for the current instruction,
   1092  1.1  christos    issue an error.  */
   1093  1.1  christos 
   1094  1.1  christos static int
   1095  1.1  christos getreg_image (reg r)
   1096  1.1  christos {
   1097  1.1  christos   const reg_entry *rreg;
   1098  1.1  christos   char *reg_name;
   1099  1.1  christos   int is_procreg = 0; /* Nonzero means argument should be processor reg.  */
   1100  1.1  christos 
   1101  1.1  christos   /* Check whether the register is in registers table.  */
   1102  1.1  christos   if (r < MAX_REG)
   1103  1.1  christos     rreg = cr16_regtab + r;
   1104  1.1  christos   else /* Register not found.  */
   1105  1.1  christos     {
   1106  1.1  christos       as_bad (_("Unknown register: `%d'"), r);
   1107  1.1  christos       return 0;
   1108  1.1  christos     }
   1109  1.1  christos 
   1110  1.1  christos   reg_name = rreg->name;
   1111  1.1  christos 
   1112  1.8  christos   /* Issue a error message when register is illegal.  */
   1113  1.8  christos #define IMAGE_ERR						\
   1114  1.8  christos   as_bad (_("Illegal register (`%s') in Instruction: `%s'"),	\
   1115  1.6  christos 	  reg_name, ins_parse);
   1116  1.1  christos 
   1117  1.1  christos   switch (rreg->type)
   1118  1.1  christos     {
   1119  1.1  christos     case CR16_R_REGTYPE:
   1120  1.1  christos       if (! is_procreg)
   1121  1.8  christos 	return rreg->image;
   1122  1.1  christos       else
   1123  1.8  christos 	IMAGE_ERR;
   1124  1.6  christos       break;
   1125  1.1  christos 
   1126  1.1  christos     case CR16_P_REGTYPE:
   1127  1.1  christos       return rreg->image;
   1128  1.1  christos       break;
   1129  1.1  christos 
   1130  1.1  christos     default:
   1131  1.1  christos       IMAGE_ERR;
   1132  1.6  christos       break;
   1133  1.1  christos     }
   1134  1.1  christos 
   1135  1.1  christos   return 0;
   1136  1.1  christos }
   1137  1.1  christos 
   1138  1.1  christos /* Parsing different types of operands
   1139  1.1  christos    -> constants             Immediate/Absolute/Relative numbers
   1140  1.1  christos    -> Labels                Relocatable symbols
   1141  1.1  christos    -> (reg pair base)       Register pair base
   1142  1.1  christos    -> (rbase)               Register base
   1143  1.1  christos    -> disp(rbase)           Register relative
   1144  1.1  christos    -> [rinx]disp(reg pair)  Register index with reg pair mode
   1145  1.1  christos    -> disp(rbase,ridx,scl)  Register index mode.  */
   1146  1.1  christos 
   1147  1.1  christos static void
   1148  1.1  christos set_operand (char *operand, ins * cr16_ins)
   1149  1.1  christos {
   1150  1.6  christos   char *operandS; /* Pointer to start of sub-operand.  */
   1151  1.6  christos   char *operandE; /* Pointer to end of sub-operand.  */
   1152  1.1  christos 
   1153  1.1  christos   argument *cur_arg = &cr16_ins->arg[cur_arg_num]; /* Current argument.  */
   1154  1.1  christos 
   1155  1.1  christos   /* Initialize pointers.  */
   1156  1.1  christos   operandS = operandE = operand;
   1157  1.1  christos 
   1158  1.1  christos   switch (cur_arg->type)
   1159  1.1  christos     {
   1160  1.1  christos     case arg_ic:    /* Case $0x18.  */
   1161  1.1  christos       operandS++;
   1162  1.6  christos       /* Fall through.  */
   1163  1.1  christos     case arg_c:     /* Case 0x18.  */
   1164  1.1  christos       /* Set constant.  */
   1165  1.1  christos       process_label_constant (operandS, cr16_ins);
   1166  1.1  christos 
   1167  1.1  christos       if (cur_arg->type != arg_ic)
   1168  1.8  christos 	cur_arg->type = arg_c;
   1169  1.1  christos       break;
   1170  1.1  christos 
   1171  1.1  christos     case arg_icr:   /* Case $0x18(r1).  */
   1172  1.1  christos       operandS++;
   1173  1.1  christos     case arg_cr:    /* Case 0x18(r1).   */
   1174  1.1  christos       /* Set displacement constant.  */
   1175  1.1  christos       while (*operandE != '(')
   1176  1.8  christos 	operandE++;
   1177  1.1  christos       *operandE = '\0';
   1178  1.1  christos       process_label_constant (operandS, cr16_ins);
   1179  1.1  christos       operandS = operandE;
   1180  1.6  christos       /* Fall through.  */
   1181  1.1  christos     case arg_rbase: /* Case (r1) or (r1,r0).  */
   1182  1.1  christos       operandS++;
   1183  1.1  christos       /* Set register base.  */
   1184  1.1  christos       while (*operandE != ')')
   1185  1.8  christos 	operandE++;
   1186  1.1  christos       *operandE = '\0';
   1187  1.1  christos       if ((cur_arg->r = get_register (operandS)) == nullregister)
   1188  1.8  christos 	as_bad (_("Illegal register `%s' in Instruction `%s'"),
   1189  1.8  christos 		operandS, ins_parse);
   1190  1.1  christos 
   1191  1.1  christos       /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
   1192  1.1  christos       if ((cur_arg->type != arg_rbase)
   1193  1.8  christos 	  && ((getreg_image (cur_arg->r) == 12)
   1194  1.8  christos 	      || (getreg_image (cur_arg->r) == 13)
   1195  1.8  christos 	      || (getreg_image (cur_arg->r) == 14)
   1196  1.8  christos 	      || (getreg_image (cur_arg->r) == 15)))
   1197  1.8  christos 	{
   1198  1.8  christos 	  cur_arg->type = arg_crp;
   1199  1.8  christos 	  cur_arg->rp = cur_arg->r;
   1200  1.8  christos 	}
   1201  1.1  christos       break;
   1202  1.1  christos 
   1203  1.1  christos     case arg_crp:    /* Case 0x18(r1,r0).   */
   1204  1.1  christos       /* Set displacement constant.  */
   1205  1.1  christos       while (*operandE != '(')
   1206  1.8  christos 	operandE++;
   1207  1.1  christos       *operandE = '\0';
   1208  1.1  christos       process_label_constant (operandS, cr16_ins);
   1209  1.1  christos       operandS = operandE;
   1210  1.1  christos       operandS++;
   1211  1.1  christos       /* Set register pair base.  */
   1212  1.1  christos       while (*operandE != ')')
   1213  1.8  christos 	operandE++;
   1214  1.1  christos       *operandE = '\0';
   1215  1.1  christos       if ((cur_arg->rp = get_register_pair (operandS)) == nullregister)
   1216  1.8  christos 	as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
   1217  1.8  christos 		operandS, ins_parse);
   1218  1.1  christos       break;
   1219  1.1  christos 
   1220  1.1  christos     case arg_idxr:
   1221  1.1  christos       /* Set register pair base.  */
   1222  1.1  christos       if ((strchr (operandS,'(') != NULL))
   1223  1.8  christos 	{
   1224  1.8  christos 	  while ((*operandE != '(') && (! ISSPACE (*operandE)))
   1225  1.8  christos 	    operandE++;
   1226  1.8  christos 	  if ((cur_arg->rp = get_index_register_pair (operandE)) == nullregister)
   1227  1.8  christos 	    as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
   1228  1.8  christos 		    operandS, ins_parse);
   1229  1.8  christos 	  *operandE++ = '\0';
   1230  1.8  christos 	  cur_arg->type = arg_idxrp;
   1231  1.8  christos 	}
   1232  1.1  christos       else
   1233  1.8  christos 	cur_arg->rp = -1;
   1234  1.1  christos 
   1235  1.8  christos       operandE = operandS;
   1236  1.1  christos       /* Set displacement constant.  */
   1237  1.1  christos       while (*operandE != ']')
   1238  1.8  christos 	operandE++;
   1239  1.1  christos       process_label_constant (++operandE, cr16_ins);
   1240  1.1  christos       *operandE++ = '\0';
   1241  1.1  christos       operandE = operandS;
   1242  1.1  christos 
   1243  1.1  christos       /* Set index register .  */
   1244  1.1  christos       operandS = strchr (operandE,'[');
   1245  1.1  christos       if (operandS != NULL)
   1246  1.8  christos 	{ /* Eliminate '[', detach from rest of operand.  */
   1247  1.8  christos 	  *operandS++ = '\0';
   1248  1.1  christos 
   1249  1.8  christos 	  operandE = strchr (operandS, ']');
   1250  1.1  christos 
   1251  1.8  christos 	  if (operandE == NULL)
   1252  1.8  christos 	    as_bad (_("unmatched '['"));
   1253  1.8  christos 	  else
   1254  1.8  christos 	    { /* Eliminate ']' and make sure it was the last thing
   1255  1.8  christos 		 in the string.  */
   1256  1.8  christos 	      *operandE = '\0';
   1257  1.8  christos 	      if (*(operandE + 1) != '\0')
   1258  1.8  christos 		as_bad (_("garbage after index spec ignored"));
   1259  1.8  christos 	    }
   1260  1.8  christos 	}
   1261  1.1  christos 
   1262  1.1  christos       if ((cur_arg->i_r = get_index_register (operandS)) == nullregister)
   1263  1.8  christos 	as_bad (_("Illegal register `%s' in Instruction `%s'"),
   1264  1.8  christos 		operandS, ins_parse);
   1265  1.1  christos       *operandE = '\0';
   1266  1.1  christos       *operandS = '\0';
   1267  1.1  christos       break;
   1268  1.1  christos 
   1269  1.1  christos     default:
   1270  1.1  christos       break;
   1271  1.1  christos     }
   1272  1.1  christos }
   1273  1.1  christos 
   1274  1.1  christos /* Parse a single operand.
   1275  1.1  christos    operand - Current operand to parse.
   1276  1.1  christos    cr16_ins - Current assembled instruction.  */
   1277  1.1  christos 
   1278  1.1  christos static void
   1279  1.1  christos parse_operand (char *operand, ins * cr16_ins)
   1280  1.1  christos {
   1281  1.1  christos   int ret_val;
   1282  1.1  christos   argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument.  */
   1283  1.1  christos 
   1284  1.1  christos   /* Initialize the type to NULL before parsing.  */
   1285  1.1  christos   cur_arg->type = nullargs;
   1286  1.1  christos 
   1287  1.1  christos   /* Check whether this is a condition code .  */
   1288  1.1  christos   if ((IS_INSN_MNEMONIC ("b")) && ((ret_val = get_cc (operand)) != -1))
   1289  1.1  christos     {
   1290  1.1  christos       cur_arg->type = arg_cc;
   1291  1.1  christos       cur_arg->cc = ret_val;
   1292  1.1  christos       cur_arg->X_op = O_register;
   1293  1.1  christos       return;
   1294  1.1  christos     }
   1295  1.1  christos 
   1296  1.1  christos   /* Check whether this is a general processor register.  */
   1297  1.1  christos   if ((ret_val = get_register (operand)) != nullregister)
   1298  1.1  christos     {
   1299  1.1  christos       cur_arg->type = arg_r;
   1300  1.1  christos       cur_arg->r = ret_val;
   1301  1.1  christos       cur_arg->X_op = 0;
   1302  1.1  christos       return;
   1303  1.1  christos     }
   1304  1.1  christos 
   1305  1.1  christos   /* Check whether this is a general processor register pair.  */
   1306  1.1  christos   if ((operand[0] == '(')
   1307  1.1  christos       && ((ret_val = get_register_pair (operand)) != nullregister))
   1308  1.1  christos     {
   1309  1.1  christos       cur_arg->type = arg_rp;
   1310  1.1  christos       cur_arg->rp = ret_val;
   1311  1.1  christos       cur_arg->X_op = O_register;
   1312  1.1  christos       return;
   1313  1.1  christos     }
   1314  1.1  christos 
   1315  1.1  christos   /* Check whether the operand is a processor register.
   1316  1.1  christos      For "lprd" and "sprd" instruction, only 32 bit
   1317  1.1  christos      processor registers used.  */
   1318  1.1  christos   if (!(IS_INSN_MNEMONIC ("lprd") || (IS_INSN_MNEMONIC ("sprd")))
   1319  1.1  christos       && ((ret_val = get_pregister (operand)) != nullpregister))
   1320  1.1  christos     {
   1321  1.1  christos       cur_arg->type = arg_pr;
   1322  1.1  christos       cur_arg->pr = ret_val;
   1323  1.1  christos       cur_arg->X_op = O_register;
   1324  1.1  christos       return;
   1325  1.1  christos     }
   1326  1.1  christos 
   1327  1.1  christos   /* Check whether this is a processor register - 32 bit.  */
   1328  1.1  christos   if ((ret_val = get_pregisterp (operand)) != nullpregister)
   1329  1.1  christos     {
   1330  1.1  christos       cur_arg->type = arg_prp;
   1331  1.1  christos       cur_arg->prp = ret_val;
   1332  1.1  christos       cur_arg->X_op = O_register;
   1333  1.1  christos       return;
   1334  1.1  christos     }
   1335  1.1  christos 
   1336  1.1  christos   /* Deal with special characters.  */
   1337  1.1  christos   switch (operand[0])
   1338  1.1  christos     {
   1339  1.1  christos     case '$':
   1340  1.1  christos       if (strchr (operand, '(') != NULL)
   1341  1.8  christos 	cur_arg->type = arg_icr;
   1342  1.1  christos       else
   1343  1.8  christos 	cur_arg->type = arg_ic;
   1344  1.1  christos       goto set_params;
   1345  1.1  christos       break;
   1346  1.1  christos 
   1347  1.1  christos     case '(':
   1348  1.1  christos       cur_arg->type = arg_rbase;
   1349  1.1  christos       goto set_params;
   1350  1.1  christos       break;
   1351  1.1  christos 
   1352  1.1  christos     case '[':
   1353  1.1  christos       cur_arg->type = arg_idxr;
   1354  1.1  christos       goto set_params;
   1355  1.1  christos       break;
   1356  1.1  christos 
   1357  1.1  christos     default:
   1358  1.1  christos       break;
   1359  1.1  christos     }
   1360  1.1  christos 
   1361  1.1  christos   if (strchr (operand, '(') != NULL)
   1362  1.1  christos     {
   1363  1.1  christos       if (strchr (operand, ',') != NULL
   1364  1.8  christos 	  && (strchr (operand, ',') > strchr (operand, '(')))
   1365  1.8  christos 	cur_arg->type = arg_crp;
   1366  1.1  christos       else
   1367  1.8  christos 	cur_arg->type = arg_cr;
   1368  1.1  christos     }
   1369  1.1  christos   else
   1370  1.1  christos     cur_arg->type = arg_c;
   1371  1.1  christos 
   1372  1.8  christos   /* Parse an operand according to its type.  */
   1373  1.1  christos  set_params:
   1374  1.1  christos   cur_arg->constant = 0;
   1375  1.1  christos   set_operand (operand, cr16_ins);
   1376  1.1  christos }
   1377  1.1  christos 
   1378  1.1  christos /* Parse the various operands. Each operand is then analyzed to fillup
   1379  1.1  christos    the fields in the cr16_ins data structure.  */
   1380  1.1  christos 
   1381  1.1  christos static void
   1382  1.1  christos parse_operands (ins * cr16_ins, char *operands)
   1383  1.1  christos {
   1384  1.1  christos   char *operandS;            /* Operands string.  */
   1385  1.1  christos   char *operandH, *operandT; /* Single operand head/tail pointers.  */
   1386  1.1  christos   int allocated = 0;         /* Indicates a new operands string was allocated.*/
   1387  1.1  christos   char *operand[MAX_OPERANDS];/* Separating the operands.  */
   1388  1.1  christos   int op_num = 0;             /* Current operand number we are parsing.  */
   1389  1.1  christos   int bracket_flag = 0;       /* Indicates a bracket '(' was found.  */
   1390  1.1  christos   int sq_bracket_flag = 0;    /* Indicates a square bracket '[' was found.  */
   1391  1.1  christos 
   1392  1.1  christos   /* Preprocess the list of registers, if necessary.  */
   1393  1.1  christos   operandS = operandH = operandT = operands;
   1394  1.1  christos 
   1395  1.1  christos   while (*operandT != '\0')
   1396  1.1  christos     {
   1397  1.1  christos       if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
   1398  1.8  christos 	{
   1399  1.8  christos 	  *operandT++ = '\0';
   1400  1.8  christos 	  operand[op_num++] = strdup (operandH);
   1401  1.8  christos 	  operandH = operandT;
   1402  1.8  christos 	  continue;
   1403  1.8  christos 	}
   1404  1.1  christos 
   1405  1.1  christos       if (*operandT == ' ')
   1406  1.8  christos 	as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
   1407  1.1  christos 
   1408  1.1  christos       if (*operandT == '(')
   1409  1.8  christos 	bracket_flag = 1;
   1410  1.1  christos       else if (*operandT == '[')
   1411  1.8  christos 	sq_bracket_flag = 1;
   1412  1.1  christos 
   1413  1.1  christos       if (*operandT == ')')
   1414  1.8  christos 	{
   1415  1.8  christos 	  if (bracket_flag)
   1416  1.8  christos 	    bracket_flag = 0;
   1417  1.8  christos 	  else
   1418  1.8  christos 	    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
   1419  1.8  christos 	}
   1420  1.1  christos       else if (*operandT == ']')
   1421  1.8  christos 	{
   1422  1.8  christos 	  if (sq_bracket_flag)
   1423  1.8  christos 	    sq_bracket_flag = 0;
   1424  1.8  christos 	  else
   1425  1.8  christos 	    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
   1426  1.8  christos 	}
   1427  1.1  christos 
   1428  1.1  christos       if (bracket_flag == 1 && *operandT == ')')
   1429  1.8  christos 	bracket_flag = 0;
   1430  1.1  christos       else if (sq_bracket_flag == 1 && *operandT == ']')
   1431  1.8  christos 	sq_bracket_flag = 0;
   1432  1.1  christos 
   1433  1.1  christos       operandT++;
   1434  1.1  christos     }
   1435  1.1  christos 
   1436  1.1  christos   /* Adding the last operand.  */
   1437  1.1  christos   operand[op_num++] = strdup (operandH);
   1438  1.1  christos   cr16_ins->nargs = op_num;
   1439  1.1  christos 
   1440  1.1  christos   /* Verifying correct syntax of operands (all brackets should be closed).  */
   1441  1.1  christos   if (bracket_flag || sq_bracket_flag)
   1442  1.1  christos     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
   1443  1.1  christos 
   1444  1.1  christos   /* Now we parse each operand separately.  */
   1445  1.1  christos   for (op_num = 0; op_num < cr16_ins->nargs; op_num++)
   1446  1.1  christos     {
   1447  1.1  christos       cur_arg_num = op_num;
   1448  1.1  christos       parse_operand (operand[op_num], cr16_ins);
   1449  1.1  christos       free (operand[op_num]);
   1450  1.1  christos     }
   1451  1.1  christos 
   1452  1.1  christos   if (allocated)
   1453  1.1  christos     free (operandS);
   1454  1.1  christos }
   1455  1.1  christos 
   1456  1.1  christos /* Get the trap index in dispatch table, given its name.
   1457  1.1  christos    This routine is used by assembling the 'excp' instruction.  */
   1458  1.1  christos 
   1459  1.1  christos static int
   1460  1.1  christos gettrap (char *s)
   1461  1.1  christos {
   1462  1.1  christos   const trap_entry *trap;
   1463  1.1  christos 
   1464  1.1  christos   for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
   1465  1.1  christos     if (strcasecmp (trap->name, s) == 0)
   1466  1.1  christos       return trap->entry;
   1467  1.1  christos 
   1468  1.6  christos   /* To make compatible with CR16 4.1 tools, the below 3-lines of
   1469  1.1  christos    * code added. Refer: Development Tracker item #123 */
   1470  1.1  christos   for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
   1471  1.1  christos     if (trap->entry  == (unsigned int) atoi (s))
   1472  1.1  christos       return trap->entry;
   1473  1.1  christos 
   1474  1.1  christos   as_bad (_("Unknown exception: `%s'"), s);
   1475  1.1  christos   return 0;
   1476  1.1  christos }
   1477  1.1  christos 
   1478  1.1  christos /* Top level module where instruction parsing starts.
   1479  1.1  christos    cr16_ins - data structure holds some information.
   1480  1.1  christos    operands - holds the operands part of the whole instruction.  */
   1481  1.1  christos 
   1482  1.1  christos static void
   1483  1.1  christos parse_insn (ins *insn, char *operands)
   1484  1.1  christos {
   1485  1.1  christos   int i;
   1486  1.1  christos 
   1487  1.1  christos   /* Handle instructions with no operands.  */
   1488  1.1  christos   for (i = 0; cr16_no_op_insn[i] != NULL; i++)
   1489  1.1  christos   {
   1490  1.1  christos     if (streq (cr16_no_op_insn[i], instruction->mnemonic))
   1491  1.1  christos     {
   1492  1.1  christos       insn->nargs = 0;
   1493  1.1  christos       return;
   1494  1.1  christos     }
   1495  1.1  christos   }
   1496  1.1  christos 
   1497  1.1  christos   /* Handle 'excp' instructions.  */
   1498  1.1  christos   if (IS_INSN_MNEMONIC ("excp"))
   1499  1.1  christos     {
   1500  1.1  christos       insn->nargs = 1;
   1501  1.1  christos       insn->arg[0].type = arg_ic;
   1502  1.1  christos       insn->arg[0].constant = gettrap (operands);
   1503  1.1  christos       insn->arg[0].X_op = O_constant;
   1504  1.1  christos       return;
   1505  1.1  christos     }
   1506  1.1  christos 
   1507  1.1  christos   if (operands != NULL)
   1508  1.1  christos     parse_operands (insn, operands);
   1509  1.1  christos }
   1510  1.1  christos 
   1511  1.1  christos /* bCC instruction requires special handling.  */
   1512  1.1  christos static char *
   1513  1.1  christos get_b_cc (char * op)
   1514  1.1  christos {
   1515  1.1  christos   unsigned int i;
   1516  1.1  christos 
   1517  1.8  christos   if (op[1] == 0 || (op[2] != 0 && op[3] != 0))
   1518  1.8  christos     return NULL;
   1519  1.1  christos 
   1520  1.1  christos   for (i = 0; i < cr16_num_cc ; i++)
   1521  1.8  christos     if (streq (op + 1, cr16_b_cond_tab[i]))
   1522  1.1  christos       return (char *) cr16_b_cond_tab[i];
   1523  1.1  christos 
   1524  1.1  christos    return NULL;
   1525  1.1  christos }
   1526  1.1  christos 
   1527  1.1  christos /* bCC instruction requires special handling.  */
   1528  1.1  christos static int
   1529  1.1  christos is_bcc_insn (char * op)
   1530  1.1  christos {
   1531  1.1  christos   if (!(streq (op, "bal") || streq (op, "beq0b") || streq (op, "bnq0b")
   1532  1.8  christos 	|| streq (op, "beq0w") || streq (op, "bnq0w")))
   1533  1.1  christos     if ((op[0] == 'b') && (get_b_cc (op) != NULL))
   1534  1.1  christos       return 1;
   1535  1.1  christos   return 0;
   1536  1.1  christos }
   1537  1.1  christos 
   1538  1.1  christos /* Cinv instruction requires special handling.  */
   1539  1.1  christos 
   1540  1.1  christos static void
   1541  1.1  christos check_cinv_options (char * operand)
   1542  1.1  christos {
   1543  1.1  christos   char *p = operand;
   1544  1.1  christos 
   1545  1.1  christos   while (*++p != ']')
   1546  1.1  christos     {
   1547  1.1  christos       switch (*p)
   1548  1.1  christos 	{
   1549  1.1  christos 	case ',':
   1550  1.1  christos 	case ' ':
   1551  1.1  christos 	case 'i':
   1552  1.1  christos 	case 'u':
   1553  1.1  christos 	case 'd':
   1554  1.1  christos 	  break;
   1555  1.1  christos 	default:
   1556  1.1  christos 	  as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
   1557  1.1  christos 	}
   1558  1.1  christos     }
   1559  1.1  christos }
   1560  1.1  christos 
   1561  1.1  christos /* Retrieve the opcode image of a given register pair.
   1562  1.1  christos    If the register is illegal for the current instruction,
   1563  1.1  christos    issue an error.  */
   1564  1.1  christos 
   1565  1.1  christos static int
   1566  1.1  christos getregp_image (reg r)
   1567  1.1  christos {
   1568  1.1  christos   const reg_entry *rreg;
   1569  1.1  christos   char *reg_name;
   1570  1.1  christos 
   1571  1.1  christos   /* Check whether the register is in registers table.  */
   1572  1.1  christos   if (r < MAX_REG)
   1573  1.1  christos     rreg = cr16_regptab + r;
   1574  1.1  christos   /* Register not found.  */
   1575  1.1  christos   else
   1576  1.1  christos     {
   1577  1.1  christos       as_bad (_("Unknown register pair: `%d'"), r);
   1578  1.1  christos       return 0;
   1579  1.1  christos     }
   1580  1.1  christos 
   1581  1.1  christos   reg_name = rreg->name;
   1582  1.1  christos 
   1583  1.8  christos   /* Issue a error message when register  pair is illegal.  */
   1584  1.8  christos #define RPAIR_IMAGE_ERR							\
   1585  1.8  christos   as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"),	\
   1586  1.8  christos 	  reg_name, ins_parse);						\
   1587  1.1  christos   break;
   1588  1.1  christos 
   1589  1.1  christos   switch (rreg->type)
   1590  1.1  christos     {
   1591  1.1  christos     case CR16_RP_REGTYPE:
   1592  1.1  christos       return rreg->image;
   1593  1.1  christos     default:
   1594  1.1  christos       RPAIR_IMAGE_ERR;
   1595  1.1  christos     }
   1596  1.1  christos 
   1597  1.1  christos   return 0;
   1598  1.1  christos }
   1599  1.1  christos 
   1600  1.1  christos /* Retrieve the opcode image of a given index register pair.
   1601  1.1  christos    If the register is illegal for the current instruction,
   1602  1.1  christos    issue an error.  */
   1603  1.1  christos 
   1604  1.1  christos static int
   1605  1.1  christos getidxregp_image (reg r)
   1606  1.1  christos {
   1607  1.1  christos   const reg_entry *rreg;
   1608  1.1  christos   char *reg_name;
   1609  1.1  christos 
   1610  1.1  christos   /* Check whether the register is in registers table.  */
   1611  1.1  christos   if (r < MAX_REG)
   1612  1.1  christos     rreg = cr16_regptab + r;
   1613  1.1  christos   /* Register not found.  */
   1614  1.1  christos   else
   1615  1.1  christos     {
   1616  1.1  christos       as_bad (_("Unknown register pair: `%d'"), r);
   1617  1.1  christos       return 0;
   1618  1.1  christos     }
   1619  1.1  christos 
   1620  1.1  christos   reg_name = rreg->name;
   1621  1.1  christos 
   1622  1.8  christos   /* Issue a error message when register  pair is illegal.  */
   1623  1.8  christos #define IDX_RPAIR_IMAGE_ERR						\
   1624  1.1  christos   as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
   1625  1.8  christos 	  reg_name, ins_parse);						\
   1626  1.1  christos 
   1627  1.1  christos   if (rreg->type == CR16_RP_REGTYPE)
   1628  1.1  christos     {
   1629  1.1  christos       switch (rreg->image)
   1630  1.8  christos 	{
   1631  1.8  christos 	case 0:  return 0; break;
   1632  1.8  christos 	case 2:  return 1; break;
   1633  1.8  christos 	case 4:  return 2; break;
   1634  1.8  christos 	case 6:  return 3; break;
   1635  1.8  christos 	case 8:  return 4; break;
   1636  1.8  christos 	case 10: return 5; break;
   1637  1.8  christos 	case 3:  return 6; break;
   1638  1.8  christos 	case 5:  return 7; break;
   1639  1.8  christos 	default:
   1640  1.8  christos 	  break;
   1641  1.8  christos 	}
   1642  1.1  christos     }
   1643  1.1  christos 
   1644  1.1  christos   IDX_RPAIR_IMAGE_ERR;
   1645  1.1  christos   return 0;
   1646  1.1  christos }
   1647  1.1  christos 
   1648  1.6  christos /* Retrieve the opcode image of a given processor register.
   1649  1.1  christos    If the register is illegal for the current instruction,
   1650  1.1  christos    issue an error.  */
   1651  1.1  christos static int
   1652  1.1  christos getprocreg_image (int r)
   1653  1.1  christos {
   1654  1.1  christos   const reg_entry *rreg;
   1655  1.1  christos   char *reg_name;
   1656  1.1  christos 
   1657  1.1  christos   /* Check whether the register is in registers table.  */
   1658  1.1  christos   if (r >= MAX_REG && r < MAX_PREG)
   1659  1.1  christos     rreg = &cr16_pregtab[r - MAX_REG];
   1660  1.1  christos   /* Register not found.  */
   1661  1.1  christos   else
   1662  1.1  christos     {
   1663  1.1  christos       as_bad (_("Unknown processor register : `%d'"), r);
   1664  1.1  christos       return 0;
   1665  1.1  christos     }
   1666  1.1  christos 
   1667  1.1  christos   reg_name = rreg->name;
   1668  1.1  christos 
   1669  1.8  christos   /* Issue a error message when register  pair is illegal.  */
   1670  1.8  christos #define PROCREG_IMAGE_ERR						\
   1671  1.8  christos   as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"),	\
   1672  1.8  christos 	  reg_name, ins_parse);						\
   1673  1.1  christos   break;
   1674  1.1  christos 
   1675  1.1  christos   switch (rreg->type)
   1676  1.1  christos     {
   1677  1.1  christos     case CR16_P_REGTYPE:
   1678  1.1  christos       return rreg->image;
   1679  1.1  christos     default:
   1680  1.1  christos       PROCREG_IMAGE_ERR;
   1681  1.1  christos     }
   1682  1.1  christos 
   1683  1.1  christos   return 0;
   1684  1.1  christos }
   1685  1.1  christos 
   1686  1.6  christos /* Retrieve the opcode image of a given processor register.
   1687  1.1  christos    If the register is illegal for the current instruction,
   1688  1.1  christos    issue an error.  */
   1689  1.1  christos static int
   1690  1.1  christos getprocregp_image (int r)
   1691  1.1  christos {
   1692  1.1  christos   const reg_entry *rreg;
   1693  1.1  christos   char *reg_name;
   1694  1.1  christos   int pregptab_disp = 0;
   1695  1.1  christos 
   1696  1.1  christos   /* Check whether the register is in registers table.  */
   1697  1.1  christos   if (r >= MAX_REG && r < MAX_PREG)
   1698  1.1  christos     {
   1699  1.1  christos       r = r - MAX_REG;
   1700  1.1  christos       switch (r)
   1701  1.8  christos 	{
   1702  1.8  christos 	case 4: pregptab_disp = 1;  break;
   1703  1.8  christos 	case 6: pregptab_disp = 2;  break;
   1704  1.8  christos 	case 8:
   1705  1.8  christos 	case 9:
   1706  1.8  christos 	case 10:
   1707  1.8  christos 	  pregptab_disp = 3;  break;
   1708  1.8  christos 	case 12:
   1709  1.8  christos 	  pregptab_disp = 4;  break;
   1710  1.8  christos 	case 14:
   1711  1.8  christos 	  pregptab_disp = 5;  break;
   1712  1.8  christos 	default: break;
   1713  1.8  christos 	}
   1714  1.1  christos       rreg = &cr16_pregptab[r - pregptab_disp];
   1715  1.1  christos     }
   1716  1.1  christos   /* Register not found.  */
   1717  1.1  christos   else
   1718  1.1  christos     {
   1719  1.1  christos       as_bad (_("Unknown processor register (32 bit) : `%d'"), r);
   1720  1.1  christos       return 0;
   1721  1.1  christos     }
   1722  1.1  christos 
   1723  1.1  christos   reg_name = rreg->name;
   1724  1.1  christos 
   1725  1.8  christos   /* Issue a error message when register  pair is illegal.  */
   1726  1.8  christos #define PROCREGP_IMAGE_ERR						\
   1727  1.8  christos   as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"), \
   1728  1.8  christos 	  reg_name, ins_parse);						\
   1729  1.1  christos   break;
   1730  1.1  christos 
   1731  1.1  christos   switch (rreg->type)
   1732  1.1  christos     {
   1733  1.1  christos     case CR16_P_REGTYPE:
   1734  1.1  christos       return rreg->image;
   1735  1.1  christos     default:
   1736  1.1  christos       PROCREGP_IMAGE_ERR;
   1737  1.1  christos     }
   1738  1.1  christos 
   1739  1.1  christos   return 0;
   1740  1.1  christos }
   1741  1.1  christos 
   1742  1.1  christos /* Routine used to represent integer X using NBITS bits.  */
   1743  1.1  christos 
   1744  1.1  christos static long
   1745  1.1  christos getconstant (long x, int nbits)
   1746  1.1  christos {
   1747  1.8  christos   if ((unsigned) nbits >= sizeof (x) * CHAR_BIT)
   1748  1.8  christos     return x;
   1749  1.8  christos   return x & ((1UL << nbits) - 1);
   1750  1.1  christos }
   1751  1.1  christos 
   1752  1.1  christos /* Print a constant value to 'output_opcode':
   1753  1.1  christos    ARG holds the operand's type and value.
   1754  1.1  christos    SHIFT represents the location of the operand to be print into.
   1755  1.1  christos    NBITS determines the size (in bits) of the constant.  */
   1756  1.1  christos 
   1757  1.1  christos static void
   1758  1.1  christos print_constant (int nbits, int shift, argument *arg)
   1759  1.1  christos {
   1760  1.1  christos   unsigned long mask = 0;
   1761  1.8  christos   unsigned long constant = getconstant (arg->constant, nbits);
   1762  1.1  christos 
   1763  1.1  christos   switch (nbits)
   1764  1.1  christos     {
   1765  1.1  christos     case 32:
   1766  1.1  christos     case 28:
   1767  1.1  christos       /* mask the upper part of the constant, that is, the bits
   1768  1.8  christos 	 going to the lowest byte of output_opcode[0].
   1769  1.8  christos 	 The upper part of output_opcode[1] is always filled,
   1770  1.8  christos 	 therefore it is always masked with 0xFFFF.  */
   1771  1.1  christos       mask = (1 << (nbits - 16)) - 1;
   1772  1.1  christos       /* Divide the constant between two consecutive words :
   1773  1.8  christos 	 0        1         2         3
   1774  1.8  christos 	 +---------+---------+---------+---------+
   1775  1.8  christos 	 |         | X X X X | x X x X |         |
   1776  1.8  christos 	 +---------+---------+---------+---------+
   1777  1.8  christos 	 output_opcode[0]    output_opcode[1]     */
   1778  1.1  christos 
   1779  1.1  christos       CR16_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
   1780  1.8  christos       CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
   1781  1.1  christos       break;
   1782  1.1  christos 
   1783  1.1  christos     case 21:
   1784  1.6  christos       if ((nbits == 21) && (IS_INSN_TYPE (LD_STOR_INS)))
   1785  1.6  christos 	nbits = 20;
   1786  1.6  christos       /* Fall through.  */
   1787  1.1  christos     case 24:
   1788  1.1  christos     case 22:
   1789  1.1  christos     case 20:
   1790  1.1  christos       /* mask the upper part of the constant, that is, the bits
   1791  1.8  christos 	 going to the lowest byte of output_opcode[0].
   1792  1.8  christos 	 The upper part of output_opcode[1] is always filled,
   1793  1.8  christos 	 therefore it is always masked with 0xFFFF.  */
   1794  1.1  christos       mask = (1 << (nbits - 16)) - 1;
   1795  1.1  christos       /* Divide the constant between two consecutive words :
   1796  1.8  christos 	 0        1         2          3
   1797  1.8  christos 	 +---------+---------+---------+---------+
   1798  1.8  christos 	 |         | X X X X | - X - X |         |
   1799  1.8  christos 	 +---------+---------+---------+---------+
   1800  1.8  christos 	 output_opcode[0]    output_opcode[1]     */
   1801  1.8  christos 
   1802  1.8  christos       if (instruction->size > 2 && shift == WORD_SHIFT)
   1803  1.8  christos 	{
   1804  1.8  christos 	  if (arg->type == arg_idxrp)
   1805  1.8  christos 	    {
   1806  1.8  christos 	      CR16_PRINT (0, ((constant >> WORD_SHIFT) & mask) << 8, 0);
   1807  1.8  christos 	      CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
   1808  1.8  christos 	    }
   1809  1.8  christos 	  else
   1810  1.8  christos 	    {
   1811  1.8  christos 	      CR16_PRINT (0,
   1812  1.8  christos 			  ((((constant >> WORD_SHIFT) & mask & 0xf) << 8)
   1813  1.8  christos 			   | (((constant >> WORD_SHIFT) & mask & 0xf0) >> 4)),
   1814  1.8  christos 			  0);
   1815  1.8  christos 	      CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
   1816  1.8  christos 	    }
   1817  1.8  christos 	}
   1818  1.1  christos       else
   1819  1.8  christos 	CR16_PRINT (0, constant, shift);
   1820  1.1  christos       break;
   1821  1.1  christos 
   1822  1.1  christos     case 14:
   1823  1.1  christos       if (arg->type == arg_idxrp)
   1824  1.8  christos 	{
   1825  1.8  christos 	  if (instruction->size == 2)
   1826  1.8  christos 	    {
   1827  1.8  christos 	      CR16_PRINT (0, (constant)      & 0xf, shift);      /* 0-3 bits.  */
   1828  1.8  christos 	      CR16_PRINT (0, (constant >> 4) & 0x3, shift + 20); /* 4-5 bits.  */
   1829  1.8  christos 	      CR16_PRINT (0, (constant >> 6) & 0x3, shift + 14); /* 6-7 bits.  */
   1830  1.8  christos 	      CR16_PRINT (0, (constant >> 8) & 0x3f, shift + 8); /* 8-13 bits.  */
   1831  1.8  christos 	    }
   1832  1.8  christos 	  else
   1833  1.8  christos 	    CR16_PRINT (0, constant, shift);
   1834  1.8  christos 	}
   1835  1.1  christos       break;
   1836  1.1  christos 
   1837  1.1  christos     case 16:
   1838  1.1  christos     case 12:
   1839  1.1  christos       /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
   1840  1.8  christos 	 always filling the upper part of output_opcode[1]. If we mistakenly
   1841  1.8  christos 	 write it to output_opcode[0], the constant prefix (that is, 'match')
   1842  1.8  christos 	 will be overridden.
   1843  1.8  christos 	 0        1         2         3
   1844  1.8  christos 	 +---------+---------+---------+---------+
   1845  1.8  christos 	 | 'match' |         | X X X X |         |
   1846  1.8  christos 	 +---------+---------+---------+---------+
   1847  1.8  christos 	 output_opcode[0]    output_opcode[1]     */
   1848  1.1  christos 
   1849  1.8  christos       if (instruction->size > 2 && shift == WORD_SHIFT)
   1850  1.8  christos 	CR16_PRINT (1, constant, WORD_SHIFT);
   1851  1.1  christos       else
   1852  1.8  christos 	CR16_PRINT (0, constant, shift);
   1853  1.1  christos       break;
   1854  1.1  christos 
   1855  1.1  christos     case 8:
   1856  1.8  christos       CR16_PRINT (0, (constant / 2) & 0xf, shift);
   1857  1.8  christos       CR16_PRINT (0, (constant / 2) >> 4, shift + 8);
   1858  1.1  christos       break;
   1859  1.1  christos 
   1860  1.1  christos     default:
   1861  1.8  christos       CR16_PRINT (0, constant, shift);
   1862  1.1  christos       break;
   1863  1.1  christos     }
   1864  1.1  christos }
   1865  1.1  christos 
   1866  1.1  christos /* Print an operand to 'output_opcode', which later on will be
   1867  1.1  christos    printed to the object file:
   1868  1.1  christos    ARG holds the operand's type, size and value.
   1869  1.1  christos    SHIFT represents the printing location of operand.
   1870  1.1  christos    NBITS determines the size (in bits) of a constant operand.  */
   1871  1.1  christos 
   1872  1.1  christos static void
   1873  1.1  christos print_operand (int nbits, int shift, argument *arg)
   1874  1.1  christos {
   1875  1.1  christos   switch (arg->type)
   1876  1.1  christos     {
   1877  1.1  christos     case arg_cc:
   1878  1.1  christos       CR16_PRINT (0, arg->cc, shift);
   1879  1.1  christos       break;
   1880  1.1  christos 
   1881  1.1  christos     case arg_r:
   1882  1.1  christos       CR16_PRINT (0, getreg_image (arg->r), shift);
   1883  1.1  christos       break;
   1884  1.1  christos 
   1885  1.1  christos     case arg_rp:
   1886  1.1  christos       CR16_PRINT (0, getregp_image (arg->rp), shift);
   1887  1.1  christos       break;
   1888  1.1  christos 
   1889  1.1  christos     case arg_pr:
   1890  1.1  christos       CR16_PRINT (0, getprocreg_image (arg->pr), shift);
   1891  1.1  christos       break;
   1892  1.1  christos 
   1893  1.1  christos     case arg_prp:
   1894  1.1  christos       CR16_PRINT (0, getprocregp_image (arg->prp), shift);
   1895  1.1  christos       break;
   1896  1.1  christos 
   1897  1.1  christos     case arg_idxrp:
   1898  1.1  christos       /*    16      12      8    6      0
   1899  1.8  christos 	    +-----------------------------+
   1900  1.8  christos 	    | r_index | disp  | rp_base   |
   1901  1.8  christos 	    +-----------------------------+          */
   1902  1.1  christos 
   1903  1.1  christos       if (instruction->size == 3)
   1904  1.8  christos 	{
   1905  1.8  christos 	  CR16_PRINT (0, getidxregp_image (arg->rp), 0);
   1906  1.8  christos 	  CR16_PRINT (0, getreg_image (arg->i_r) & 1, 3);
   1907  1.8  christos 	}
   1908  1.1  christos       else
   1909  1.8  christos 	{
   1910  1.8  christos 	  CR16_PRINT (0, getidxregp_image (arg->rp), 16);
   1911  1.8  christos 	  CR16_PRINT (0, getreg_image (arg->i_r) & 1, 19);
   1912  1.8  christos 	}
   1913  1.1  christos       print_constant (nbits, shift, arg);
   1914  1.1  christos       break;
   1915  1.1  christos 
   1916  1.1  christos     case arg_idxr:
   1917  1.8  christos       CR16_PRINT (0, getreg_image (arg->i_r) & 1,
   1918  1.8  christos 		  (IS_INSN_TYPE (CSTBIT_INS)
   1919  1.8  christos 		   && instruction->mnemonic[4] == 'b') ? 23 : 24);
   1920  1.1  christos       print_constant (nbits, shift, arg);
   1921  1.1  christos       break;
   1922  1.1  christos 
   1923  1.1  christos     case arg_ic:
   1924  1.1  christos     case arg_c:
   1925  1.1  christos       print_constant (nbits, shift, arg);
   1926  1.1  christos       break;
   1927  1.1  christos 
   1928  1.1  christos     case arg_rbase:
   1929  1.1  christos       CR16_PRINT (0, getreg_image (arg->r), shift);
   1930  1.1  christos       break;
   1931  1.1  christos 
   1932  1.1  christos     case arg_cr:
   1933  1.8  christos       print_constant (nbits, shift, arg);
   1934  1.1  christos       /* Add the register argument to the output_opcode.  */
   1935  1.8  christos       CR16_PRINT (0, getreg_image (arg->r), shift - 16);
   1936  1.1  christos       break;
   1937  1.1  christos 
   1938  1.1  christos     case arg_crp:
   1939  1.8  christos       print_constant (nbits, shift, arg);
   1940  1.8  christos       if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
   1941  1.8  christos 	  && instruction->size == 1)
   1942  1.8  christos 	CR16_PRINT (0, getregp_image (arg->rp), 16);
   1943  1.8  christos       else if (instruction->size > 1)
   1944  1.8  christos 	CR16_PRINT (0, getregp_image (arg->rp), (shift + 16) & 31);
   1945  1.1  christos       else
   1946  1.8  christos 	CR16_PRINT (0, getregp_image (arg->rp), shift);
   1947  1.1  christos       break;
   1948  1.1  christos 
   1949  1.1  christos     default:
   1950  1.1  christos       break;
   1951  1.1  christos     }
   1952  1.1  christos }
   1953  1.1  christos 
   1954  1.1  christos /* Retrieve the number of operands for the current assembled instruction.  */
   1955  1.1  christos 
   1956  1.1  christos static int
   1957  1.1  christos get_number_of_operands (void)
   1958  1.1  christos {
   1959  1.1  christos   int i;
   1960  1.1  christos 
   1961  1.1  christos   for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
   1962  1.1  christos     ;
   1963  1.1  christos   return i;
   1964  1.1  christos }
   1965  1.1  christos 
   1966  1.1  christos /* Verify that the number NUM can be represented in BITS bits (that is,
   1967  1.1  christos    within its permitted range), based on the instruction's FLAGS.
   1968  1.1  christos    If UPDATE is nonzero, update the value of NUM if necessary.
   1969  1.1  christos    Return OP_LEGAL upon success, actual error type upon failure.  */
   1970  1.1  christos 
   1971  1.1  christos static op_err
   1972  1.1  christos check_range (long *num, int bits, int unsigned flags, int update)
   1973  1.1  christos {
   1974  1.8  christos   int32_t min, max;
   1975  1.5  christos   op_err retval = OP_LEGAL;
   1976  1.8  christos   int32_t value = *num;
   1977  1.1  christos 
   1978  1.1  christos   /* Verify operand value is even.  */
   1979  1.1  christos   if (flags & OP_EVEN)
   1980  1.1  christos     {
   1981  1.1  christos       if (value % 2)
   1982  1.8  christos 	return OP_NOT_EVEN;
   1983  1.1  christos     }
   1984  1.1  christos 
   1985  1.1  christos   if (flags & OP_DEC)
   1986  1.1  christos     {
   1987  1.1  christos       value -= 1;
   1988  1.1  christos       if (update)
   1989  1.8  christos 	*num = value;
   1990  1.1  christos     }
   1991  1.1  christos 
   1992  1.1  christos   if (flags & OP_SHIFT)
   1993  1.1  christos     {
   1994  1.1  christos       value >>= 1;
   1995  1.1  christos       if (update)
   1996  1.8  christos 	*num = value;
   1997  1.1  christos     }
   1998  1.1  christos   else if (flags & OP_SHIFT_DEC)
   1999  1.1  christos     {
   2000  1.1  christos       value = (value >> 1) - 1;
   2001  1.1  christos       if (update)
   2002  1.8  christos 	*num = value;
   2003  1.1  christos     }
   2004  1.1  christos 
   2005  1.1  christos   if (flags & OP_ABS20)
   2006  1.1  christos     {
   2007  1.1  christos       if (value > 0xEFFFF)
   2008  1.8  christos 	return OP_OUT_OF_RANGE;
   2009  1.1  christos     }
   2010  1.1  christos 
   2011  1.1  christos   if (flags & OP_ESC)
   2012  1.1  christos     {
   2013  1.1  christos       if (value == 0xB || value == 0x9)
   2014  1.8  christos 	return OP_OUT_OF_RANGE;
   2015  1.1  christos       else if (value == -1)
   2016  1.8  christos 	{
   2017  1.8  christos 	  if (update)
   2018  1.8  christos 	    *num = 9;
   2019  1.8  christos 	  return retval;
   2020  1.8  christos 	}
   2021  1.1  christos     }
   2022  1.1  christos 
   2023  1.1  christos   if (flags & OP_ESC1)
   2024  1.1  christos     {
   2025  1.1  christos       if (value > 13)
   2026  1.8  christos 	return OP_OUT_OF_RANGE;
   2027  1.1  christos     }
   2028  1.1  christos 
   2029  1.8  christos   if (bits == 0)
   2030  1.8  christos     {
   2031  1.8  christos       if (value != 0)
   2032  1.8  christos 	retval = OP_OUT_OF_RANGE;
   2033  1.8  christos       return retval;
   2034  1.8  christos     }
   2035  1.8  christos 
   2036  1.8  christos   if (flags & OP_SIGNED)
   2037  1.8  christos     {
   2038  1.8  christos       max = (1U << (bits - 1)) - 1;
   2039  1.8  christos       min = - (1U << (bits - 1));
   2040  1.8  christos       if (value > max || value < min)
   2041  1.8  christos 	retval = OP_OUT_OF_RANGE;
   2042  1.8  christos     }
   2043  1.8  christos   else if (flags & OP_UNSIGNED)
   2044  1.8  christos     {
   2045  1.8  christos       max = (1U << (bits - 1) << 1) - 1;
   2046  1.8  christos       if ((uint32_t) value > (uint32_t) max)
   2047  1.8  christos 	retval = OP_OUT_OF_RANGE;
   2048  1.8  christos     }
   2049  1.8  christos   else if (flags & OP_NEG)
   2050  1.8  christos     {
   2051  1.8  christos       min = - ((1U << (bits - 1)) - 1);
   2052  1.8  christos       if (value < min)
   2053  1.8  christos 	retval = OP_OUT_OF_RANGE;
   2054  1.8  christos     }
   2055  1.8  christos   return retval;
   2056  1.1  christos }
   2057  1.1  christos 
   2058  1.6  christos /* Bunch of error checking.
   2059  1.1  christos    The checks are made after a matching instruction was found.  */
   2060  1.1  christos 
   2061  1.1  christos static void
   2062  1.1  christos warn_if_needed (ins *insn)
   2063  1.1  christos {
   2064  1.1  christos   /* If the post-increment address mode is used and the load/store
   2065  1.1  christos      source register is the same as rbase, the result of the
   2066  1.1  christos      instruction is undefined.  */
   2067  1.1  christos   if (IS_INSN_TYPE (LD_STOR_INS_INC))
   2068  1.1  christos     {
   2069  1.1  christos       /* Enough to verify that one of the arguments is a simple reg.  */
   2070  1.1  christos       if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
   2071  1.8  christos 	if (insn->arg[0].r == insn->arg[1].r)
   2072  1.8  christos 	  as_bad (_("Same src/dest register is used (`r%d'), "
   2073  1.8  christos 		    "result is undefined"), insn->arg[0].r);
   2074  1.1  christos     }
   2075  1.1  christos 
   2076  1.1  christos   if (IS_INSN_MNEMONIC ("pop")
   2077  1.1  christos       || IS_INSN_MNEMONIC ("push")
   2078  1.1  christos       || IS_INSN_MNEMONIC ("popret"))
   2079  1.1  christos     {
   2080  1.1  christos       unsigned int count = insn->arg[0].constant, reg_val;
   2081  1.1  christos 
   2082  1.6  christos       /* Check if count operand caused to save/retrieve the RA twice
   2083  1.8  christos 	 to generate warning message.  */
   2084  1.8  christos       if (insn->nargs > 2)
   2085  1.8  christos 	{
   2086  1.8  christos 	  reg_val = getreg_image (insn->arg[1].r);
   2087  1.8  christos 
   2088  1.8  christos 	  if (   ((reg_val == 9) &&  (count > 7))
   2089  1.8  christos 		 || ((reg_val == 10) && (count > 6))
   2090  1.8  christos 		 || ((reg_val == 11) && (count > 5))
   2091  1.8  christos 		 || ((reg_val == 12) && (count > 4))
   2092  1.8  christos 		 || ((reg_val == 13) && (count > 2))
   2093  1.8  christos 		 || ((reg_val == 14) && (count > 0)))
   2094  1.8  christos 	    as_warn (_("RA register is saved twice."));
   2095  1.8  christos 
   2096  1.8  christos 	  /* Check if the third operand is "RA" or "ra" */
   2097  1.8  christos 	  if (!(((insn->arg[2].r) == ra) || ((insn->arg[2].r) == RA)))
   2098  1.8  christos 	    as_bad (_("`%s' Illegal use of registers."), ins_parse);
   2099  1.8  christos 	}
   2100  1.1  christos 
   2101  1.1  christos       if (insn->nargs > 1)
   2102  1.8  christos 	{
   2103  1.8  christos 	  reg_val = getreg_image (insn->arg[1].r);
   2104  1.1  christos 
   2105  1.8  christos 	  /* If register is a register pair ie r12/r13/r14 in operand1, then
   2106  1.8  christos 	     the count constant should be validated.  */
   2107  1.8  christos 	  if (((reg_val == 11) && (count > 7))
   2108  1.8  christos 	      || ((reg_val == 12) && (count > 6))
   2109  1.8  christos 	      || ((reg_val == 13) && (count > 4))
   2110  1.8  christos 	      || ((reg_val == 14) && (count > 2))
   2111  1.8  christos 	      || ((reg_val == 15) && (count > 0)))
   2112  1.8  christos 	    as_bad (_("`%s' Illegal count-register combination."), ins_parse);
   2113  1.8  christos 	}
   2114  1.8  christos       else
   2115  1.8  christos 	{
   2116  1.8  christos 	  /* Check if the operand is "RA" or "ra" */
   2117  1.8  christos 	  if (!(((insn->arg[0].r) == ra) || ((insn->arg[0].r) == RA)))
   2118  1.8  christos 	    as_bad (_("`%s' Illegal use of register."), ins_parse);
   2119  1.8  christos 	}
   2120  1.1  christos     }
   2121  1.1  christos 
   2122  1.1  christos   /* Some instruction assume the stack pointer as rptr operand.
   2123  1.1  christos      Issue an error when the register to be loaded is also SP.  */
   2124  1.1  christos   if (instruction->flags & NO_SP)
   2125  1.1  christos     {
   2126  1.1  christos       if (getreg_image (insn->arg[1].r) == getreg_image (sp))
   2127  1.8  christos 	as_bad (_("`%s' has undefined result"), ins_parse);
   2128  1.1  christos     }
   2129  1.1  christos 
   2130  1.1  christos   /* If the rptr register is specified as one of the registers to be loaded,
   2131  1.1  christos      the final contents of rptr are undefined. Thus, we issue an error.  */
   2132  1.1  christos   if (instruction->flags & NO_RPTR)
   2133  1.1  christos     {
   2134  1.1  christos       if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
   2135  1.8  christos 	as_bad (_("Same src/dest register is used (`r%d'),result is undefined"),
   2136  1.8  christos 		getreg_image (insn->arg[0].r));
   2137  1.1  christos     }
   2138  1.1  christos }
   2139  1.1  christos 
   2140  1.1  christos /* In some cases, we need to adjust the instruction pointer although a
   2141  1.1  christos    match was already found. Here, we gather all these cases.
   2142  1.1  christos    Returns 1 if instruction pointer was adjusted, otherwise 0.  */
   2143  1.1  christos 
   2144  1.1  christos static int
   2145  1.1  christos adjust_if_needed (ins *insn ATTRIBUTE_UNUSED)
   2146  1.1  christos {
   2147  1.1  christos   int ret_value = 0;
   2148  1.1  christos 
   2149  1.1  christos   if ((IS_INSN_TYPE (CSTBIT_INS)) || (IS_INSN_TYPE (LD_STOR_INS)))
   2150  1.1  christos     {
   2151  1.1  christos       if ((instruction->operands[0].op_type == abs24)
   2152  1.8  christos 	  && ((insn->arg[0].constant) > 0xF00000))
   2153  1.8  christos 	{
   2154  1.8  christos 	  insn->arg[0].constant &= 0xFFFFF;
   2155  1.8  christos 	  instruction--;
   2156  1.8  christos 	  ret_value = 1;
   2157  1.8  christos 	}
   2158  1.1  christos     }
   2159  1.1  christos 
   2160  1.1  christos   return ret_value;
   2161  1.1  christos }
   2162  1.1  christos 
   2163  1.1  christos /* Assemble a single instruction:
   2164  1.1  christos    INSN is already parsed (that is, all operand values and types are set).
   2165  1.1  christos    For instruction to be assembled, we need to find an appropriate template in
   2166  1.1  christos    the instruction table, meeting the following conditions:
   2167  1.1  christos     1: Has the same number of operands.
   2168  1.1  christos     2: Has the same operand types.
   2169  1.1  christos     3: Each operand size is sufficient to represent the instruction's values.
   2170  1.1  christos    Returns 1 upon success, 0 upon failure.  */
   2171  1.1  christos 
   2172  1.1  christos static int
   2173  1.5  christos assemble_insn (const char *mnemonic, ins *insn)
   2174  1.1  christos {
   2175  1.1  christos   /* Type of each operand in the current template.  */
   2176  1.1  christos   argtype cur_type[MAX_OPERANDS];
   2177  1.1  christos   /* Size (in bits) of each operand in the current template.  */
   2178  1.1  christos   unsigned int cur_size[MAX_OPERANDS];
   2179  1.1  christos   /* Flags of each operand in the current template.  */
   2180  1.1  christos   unsigned int cur_flags[MAX_OPERANDS];
   2181  1.1  christos   /* Instruction type to match.  */
   2182  1.1  christos   unsigned int ins_type;
   2183  1.1  christos   /* Boolean flag to mark whether a match was found.  */
   2184  1.1  christos   int match = 0;
   2185  1.1  christos   int i;
   2186  1.1  christos   /* Nonzero if an instruction with same number of operands was found.  */
   2187  1.1  christos   int found_same_number_of_operands = 0;
   2188  1.1  christos   /* Nonzero if an instruction with same argument types was found.  */
   2189  1.1  christos   int found_same_argument_types = 0;
   2190  1.1  christos   /* Nonzero if a constant was found within the required range.  */
   2191  1.1  christos   int found_const_within_range  = 0;
   2192  1.1  christos   /* Argument number of an operand with invalid type.  */
   2193  1.1  christos   int invalid_optype = -1;
   2194  1.1  christos   /* Argument number of an operand with invalid constant value.  */
   2195  1.1  christos   int invalid_const  = -1;
   2196  1.1  christos   /* Operand error (used for issuing various constant error messages).  */
   2197  1.1  christos   op_err op_error, const_err = OP_LEGAL;
   2198  1.1  christos 
   2199  1.8  christos   /* Retrieve data (based on FUNC) for each operand of a given instruction.  */
   2200  1.8  christos #define GET_CURRENT_DATA(FUNC, ARRAY)			\
   2201  1.8  christos   for (i = 0; i < insn->nargs; i++)			\
   2202  1.1  christos     ARRAY[i] = FUNC (instruction->operands[i].op_type)
   2203  1.1  christos 
   2204  1.1  christos #define GET_CURRENT_TYPE    GET_CURRENT_DATA (get_optype, cur_type)
   2205  1.1  christos #define GET_CURRENT_SIZE    GET_CURRENT_DATA (get_opbits, cur_size)
   2206  1.1  christos #define GET_CURRENT_FLAGS   GET_CURRENT_DATA (get_opflags, cur_flags)
   2207  1.1  christos 
   2208  1.1  christos   /* Instruction has no operands -> only copy the constant opcode.   */
   2209  1.1  christos   if (insn->nargs == 0)
   2210  1.1  christos     {
   2211  1.1  christos       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
   2212  1.1  christos       return 1;
   2213  1.1  christos     }
   2214  1.1  christos 
   2215  1.1  christos   /* In some case, same mnemonic can appear with different instruction types.
   2216  1.1  christos      For example, 'storb' is supported with 3 different types :
   2217  1.1  christos      LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
   2218  1.1  christos      We assume that when reaching this point, the instruction type was
   2219  1.1  christos      pre-determined. We need to make sure that the type stays the same
   2220  1.1  christos      during a search for matching instruction.  */
   2221  1.1  christos   ins_type = CR16_INS_TYPE (instruction->flags);
   2222  1.1  christos 
   2223  1.1  christos   while (/* Check that match is still not found.  */
   2224  1.8  christos 	 match != 1
   2225  1.8  christos 	 /* Check we didn't get to end of table.  */
   2226  1.8  christos 	 && instruction->mnemonic != NULL
   2227  1.8  christos 	 /* Check that the actual mnemonic is still available.  */
   2228  1.8  christos 	 && IS_INSN_MNEMONIC (mnemonic)
   2229  1.8  christos 	 /* Check that the instruction type wasn't changed.  */
   2230  1.8  christos 	 && IS_INSN_TYPE (ins_type))
   2231  1.1  christos     {
   2232  1.1  christos       /* Check whether number of arguments is legal.  */
   2233  1.1  christos       if (get_number_of_operands () != insn->nargs)
   2234  1.8  christos 	goto next_insn;
   2235  1.1  christos       found_same_number_of_operands = 1;
   2236  1.1  christos 
   2237  1.1  christos       /* Initialize arrays with data of each operand in current template.  */
   2238  1.1  christos       GET_CURRENT_TYPE;
   2239  1.1  christos       GET_CURRENT_SIZE;
   2240  1.1  christos       GET_CURRENT_FLAGS;
   2241  1.1  christos 
   2242  1.1  christos       /* Check for type compatibility.  */
   2243  1.1  christos       for (i = 0; i < insn->nargs; i++)
   2244  1.8  christos 	{
   2245  1.8  christos 	  if (cur_type[i] != insn->arg[i].type)
   2246  1.8  christos 	    {
   2247  1.8  christos 	      if (invalid_optype == -1)
   2248  1.8  christos 		invalid_optype = i + 1;
   2249  1.8  christos 	      goto next_insn;
   2250  1.8  christos 	    }
   2251  1.8  christos 	}
   2252  1.1  christos       found_same_argument_types = 1;
   2253  1.1  christos 
   2254  1.1  christos       for (i = 0; i < insn->nargs; i++)
   2255  1.8  christos 	{
   2256  1.8  christos 	  /* If 'bal' instruction size is '2' and reg operand is not 'ra'
   2257  1.8  christos 	     then goto next instruction.  */
   2258  1.8  christos 	  if (IS_INSN_MNEMONIC ("bal") && (i == 0)
   2259  1.8  christos 	      && (instruction->size == 2) && (insn->arg[i].rp != 14))
   2260  1.8  christos 	    goto next_insn;
   2261  1.8  christos 
   2262  1.8  christos 	  /* If 'storb' instruction with 'sp' reg and 16-bit disp of
   2263  1.8  christos 	   * reg-pair, leads to undefined trap, so this should use
   2264  1.8  christos 	   * 20-bit disp of reg-pair.  */
   2265  1.8  christos 	  if (IS_INSN_MNEMONIC ("storb") && (instruction->size == 2)
   2266  1.8  christos 	      && (insn->arg[i].r == 15) && (insn->arg[i + 1].type == arg_crp))
   2267  1.8  christos 	    goto next_insn;
   2268  1.8  christos 
   2269  1.8  christos 	  /* Only check range - don't update the constant's value, since the
   2270  1.8  christos 	     current instruction may not be the last we try to match.
   2271  1.8  christos 	     The constant's value will be updated later, right before printing
   2272  1.8  christos 	     it to the object file.  */
   2273  1.8  christos 	  if ((insn->arg[i].X_op == O_constant)
   2274  1.8  christos 	      && (op_error = check_range (&insn->arg[i].constant, cur_size[i],
   2275  1.8  christos 					  cur_flags[i], 0)))
   2276  1.8  christos 	    {
   2277  1.8  christos 	      if (invalid_const == -1)
   2278  1.8  christos 		{
   2279  1.8  christos 		  invalid_const = i + 1;
   2280  1.8  christos 		  const_err = op_error;
   2281  1.8  christos 		}
   2282  1.8  christos 	      goto next_insn;
   2283  1.8  christos 	    }
   2284  1.8  christos 	  /* For symbols, we make sure the relocation size (which was already
   2285  1.8  christos 	     determined) is sufficient.  */
   2286  1.8  christos 	  else if ((insn->arg[i].X_op == O_symbol)
   2287  1.8  christos 		   && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
   2288  1.8  christos 		       > cur_size[i]))
   2289  1.8  christos 	    goto next_insn;
   2290  1.8  christos 	}
   2291  1.1  christos       found_const_within_range = 1;
   2292  1.1  christos 
   2293  1.1  christos       /* If we got till here -> Full match is found.  */
   2294  1.1  christos       match = 1;
   2295  1.1  christos       break;
   2296  1.1  christos 
   2297  1.8  christos       /* Try again with next instruction.  */
   2298  1.8  christos     next_insn:
   2299  1.1  christos       instruction++;
   2300  1.1  christos     }
   2301  1.1  christos 
   2302  1.1  christos   if (!match)
   2303  1.1  christos     {
   2304  1.1  christos       /* We haven't found a match - instruction can't be assembled.  */
   2305  1.1  christos       if (!found_same_number_of_operands)
   2306  1.8  christos 	as_bad (_("Incorrect number of operands"));
   2307  1.1  christos       else if (!found_same_argument_types)
   2308  1.8  christos 	as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
   2309  1.1  christos       else if (!found_const_within_range)
   2310  1.8  christos 	{
   2311  1.8  christos 	  switch (const_err)
   2312  1.8  christos 	    {
   2313  1.8  christos 	    case OP_OUT_OF_RANGE:
   2314  1.8  christos 	      as_bad (_("Operand out of range (arg %d)"), invalid_const);
   2315  1.8  christos 	      break;
   2316  1.8  christos 	    case OP_NOT_EVEN:
   2317  1.8  christos 	      as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
   2318  1.8  christos 	      break;
   2319  1.8  christos 	    default:
   2320  1.8  christos 	      as_bad (_("Illegal operand (arg %d)"), invalid_const);
   2321  1.8  christos 	      break;
   2322  1.8  christos 	    }
   2323  1.8  christos 	}
   2324  1.1  christos 
   2325  1.8  christos       return 0;
   2326  1.1  christos     }
   2327  1.1  christos   else
   2328  1.1  christos     /* Full match - print the encoding to output file.  */
   2329  1.1  christos     {
   2330  1.6  christos       /* Make further checking (such that couldn't be made earlier).
   2331  1.8  christos 	 Warn the user if necessary.  */
   2332  1.1  christos       warn_if_needed (insn);
   2333  1.1  christos 
   2334  1.1  christos       /* Check whether we need to adjust the instruction pointer.  */
   2335  1.1  christos       if (adjust_if_needed (insn))
   2336  1.8  christos 	/* If instruction pointer was adjusted, we need to update
   2337  1.8  christos 	   the size of the current template operands.  */
   2338  1.8  christos 	GET_CURRENT_SIZE;
   2339  1.1  christos 
   2340  1.1  christos       for (i = 0; i < insn->nargs; i++)
   2341  1.8  christos 	{
   2342  1.8  christos 	  int j = instruction->flags & REVERSE_MATCH ?
   2343  1.8  christos 	    i == 0 ? 1 :
   2344  1.8  christos 	    i == 1 ? 0 : i :
   2345  1.8  christos 	    i;
   2346  1.8  christos 
   2347  1.8  christos 	  /* This time, update constant value before printing it.  */
   2348  1.8  christos 	  if ((insn->arg[j].X_op == O_constant)
   2349  1.8  christos 	      && (check_range (&insn->arg[j].constant, cur_size[j],
   2350  1.8  christos 			       cur_flags[j], 1) != OP_LEGAL))
   2351  1.8  christos 	    as_fatal (_("Illegal operand (arg %d)"), j+1);
   2352  1.8  christos 	}
   2353  1.1  christos 
   2354  1.1  christos       /* First, copy the instruction's opcode.  */
   2355  1.1  christos       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
   2356  1.1  christos 
   2357  1.1  christos       for (i = 0; i < insn->nargs; i++)
   2358  1.8  christos 	{
   2359  1.8  christos 	  /* For BAL (ra),disp17 instruction only. And also set the
   2360  1.8  christos 	     DISP24a relocation type.  */
   2361  1.8  christos 	  if (IS_INSN_MNEMONIC ("bal") && (instruction->size == 2) && i == 0)
   2362  1.8  christos 	    {
   2363  1.8  christos 	      insn->rtype = BFD_RELOC_CR16_DISP24a;
   2364  1.8  christos 	      continue;
   2365  1.8  christos 	    }
   2366  1.8  christos 	  cur_arg_num = i;
   2367  1.8  christos 	  print_operand (cur_size[i], instruction->operands[i].shift,
   2368  1.8  christos 			 &insn->arg[i]);
   2369  1.8  christos 	}
   2370  1.1  christos     }
   2371  1.1  christos 
   2372  1.1  christos   return 1;
   2373  1.1  christos }
   2374  1.1  christos 
   2375  1.1  christos /* Print the instruction.
   2376  1.1  christos    Handle also cases where the instruction is relaxable/relocatable.  */
   2377  1.1  christos 
   2378  1.1  christos static void
   2379  1.1  christos print_insn (ins *insn)
   2380  1.1  christos {
   2381  1.1  christos   unsigned int i, j, insn_size;
   2382  1.1  christos   char *this_frag;
   2383  1.1  christos   unsigned short words[4];
   2384  1.1  christos   int addr_mod;
   2385  1.1  christos 
   2386  1.1  christos   /* Arrange the insn encodings in a WORD size array.  */
   2387  1.1  christos   for (i = 0, j = 0; i < 2; i++)
   2388  1.1  christos     {
   2389  1.1  christos       words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
   2390  1.1  christos       words[j++] = output_opcode[i] & 0xFFFF;
   2391  1.1  christos     }
   2392  1.1  christos 
   2393  1.8  christos   /* Handle relocation.  */
   2394  1.8  christos   if ((instruction->flags & RELAXABLE) && relocatable)
   2395  1.8  christos     {
   2396  1.8  christos       int relax_subtype;
   2397  1.8  christos       /* Write the maximal instruction size supported.  */
   2398  1.8  christos       insn_size = INSN_MAX_SIZE;
   2399  1.8  christos 
   2400  1.8  christos       if (IS_INSN_TYPE (BRANCH_INS))
   2401  1.8  christos 	{
   2402  1.8  christos 	  switch (insn->rtype)
   2403  1.8  christos 	    {
   2404  1.8  christos 	    case BFD_RELOC_CR16_DISP24:
   2405  1.8  christos 	      relax_subtype = 2;
   2406  1.8  christos 	      break;
   2407  1.8  christos 	    case BFD_RELOC_CR16_DISP16:
   2408  1.8  christos 	      relax_subtype = 1;
   2409  1.8  christos 	      break;
   2410  1.8  christos 	    default:
   2411  1.8  christos 	      relax_subtype = 0;
   2412  1.8  christos 	      break;
   2413  1.8  christos 	    }
   2414  1.8  christos 	}
   2415  1.8  christos       else
   2416  1.8  christos 	abort ();
   2417  1.8  christos 
   2418  1.8  christos       this_frag = frag_var (rs_machine_dependent, insn_size *2,
   2419  1.8  christos 			    4, relax_subtype,
   2420  1.8  christos 			    insn->exp.X_add_symbol,
   2421  1.8  christos 			    0,
   2422  1.8  christos 			    0);
   2423  1.8  christos     }
   2424  1.8  christos   else
   2425  1.8  christos     {
   2426  1.8  christos       insn_size = instruction->size;
   2427  1.8  christos       this_frag = frag_more (insn_size * 2);
   2428  1.8  christos 
   2429  1.8  christos       if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
   2430  1.8  christos 	{
   2431  1.8  christos 	  reloc_howto_type *reloc_howto;
   2432  1.8  christos 	  int size;
   2433  1.8  christos 
   2434  1.8  christos 	  reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
   2435  1.8  christos 
   2436  1.8  christos 	  if (!reloc_howto)
   2437  1.8  christos 	    abort ();
   2438  1.8  christos 
   2439  1.8  christos 	  size = bfd_get_reloc_size (reloc_howto);
   2440  1.8  christos 
   2441  1.8  christos 	  if (size < 1 || size > 4)
   2442  1.8  christos 	    abort ();
   2443  1.8  christos 
   2444  1.8  christos 	  fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
   2445  1.8  christos 		       size, &insn->exp, reloc_howto->pc_relative,
   2446  1.8  christos 		       insn->rtype);
   2447  1.8  christos 	}
   2448  1.8  christos     }
   2449  1.1  christos 
   2450  1.1  christos   /* Verify a 2-byte code alignment.  */
   2451  1.1  christos   addr_mod = frag_now_fix () & 1;
   2452  1.1  christos   if (frag_now->has_code && frag_now->insn_addr != addr_mod)
   2453  1.1  christos     as_bad (_("instruction address is not a multiple of 2"));
   2454  1.1  christos   frag_now->insn_addr = addr_mod;
   2455  1.1  christos   frag_now->has_code = 1;
   2456  1.1  christos 
   2457  1.1  christos   /* Write the instruction encoding to frag.  */
   2458  1.1  christos   for (i = 0; i < insn_size; i++)
   2459  1.1  christos     {
   2460  1.1  christos       md_number_to_chars (this_frag, (valueT) words[i], 2);
   2461  1.1  christos       this_frag += 2;
   2462  1.1  christos     }
   2463  1.1  christos }
   2464  1.1  christos 
   2465  1.5  christos /* Actually assemble an instruction.  */
   2466  1.5  christos 
   2467  1.5  christos static void
   2468  1.5  christos cr16_assemble (const char *op, char *param)
   2469  1.5  christos {
   2470  1.5  christos   ins cr16_ins;
   2471  1.5  christos 
   2472  1.5  christos   /* Find the instruction.  */
   2473  1.8  christos   instruction = (const inst *) str_hash_find (cr16_inst_hash, op);
   2474  1.5  christos   if (instruction == NULL)
   2475  1.5  christos     {
   2476  1.5  christos       as_bad (_("Unknown opcode: `%s'"), op);
   2477  1.5  christos       return;
   2478  1.5  christos     }
   2479  1.5  christos 
   2480  1.5  christos   /* Tie dwarf2 debug info to the address at the start of the insn.  */
   2481  1.5  christos   dwarf2_emit_insn (0);
   2482  1.5  christos 
   2483  1.5  christos   /* Parse the instruction's operands.  */
   2484  1.5  christos   parse_insn (&cr16_ins, param);
   2485  1.5  christos 
   2486  1.5  christos   /* Assemble the instruction - return upon failure.  */
   2487  1.5  christos   if (assemble_insn (op, &cr16_ins) == 0)
   2488  1.5  christos     return;
   2489  1.5  christos 
   2490  1.5  christos   /* Print the instruction.  */
   2491  1.5  christos   print_insn (&cr16_ins);
   2492  1.5  christos }
   2493  1.5  christos 
   2494  1.1  christos /* This is the guts of the machine-dependent assembler.  OP points to a
   2495  1.1  christos    machine dependent instruction.  This function is supposed to emit
   2496  1.1  christos    the frags/bytes it assembles to.  */
   2497  1.1  christos 
   2498  1.1  christos void
   2499  1.1  christos md_assemble (char *op)
   2500  1.1  christos {
   2501  1.1  christos   ins cr16_ins;
   2502  1.1  christos   char *param, param1[32];
   2503  1.1  christos 
   2504  1.1  christos   /* Reset global variables for a new instruction.  */
   2505  1.1  christos   reset_vars (op);
   2506  1.1  christos 
   2507  1.1  christos   /* Strip the mnemonic.  */
   2508  1.1  christos   for (param = op; *param != 0 && !ISSPACE (*param); param++)
   2509  1.1  christos     ;
   2510  1.1  christos   *param++ = '\0';
   2511  1.1  christos 
   2512  1.6  christos   /* bCC instructions and adjust the mnemonic by adding extra white spaces.  */
   2513  1.1  christos   if (is_bcc_insn (op))
   2514  1.1  christos     {
   2515  1.1  christos       strcpy (param1, get_b_cc (op));
   2516  1.1  christos       strcat (param1,",");
   2517  1.1  christos       strcat (param1, param);
   2518  1.1  christos       param = (char *) &param1;
   2519  1.5  christos       cr16_assemble ("b", param);
   2520  1.5  christos       return;
   2521  1.1  christos     }
   2522  1.1  christos 
   2523  1.1  christos   /* Checking the cinv options and adjust the mnemonic by removing the
   2524  1.1  christos      extra white spaces.  */
   2525  1.1  christos   if (streq ("cinv", op))
   2526  1.1  christos     {
   2527  1.8  christos       /* Validate the cinv options.  */
   2528  1.8  christos       unsigned int op_len, param_len;
   2529  1.1  christos       check_cinv_options (param);
   2530  1.8  christos       op_len = strlen (op);
   2531  1.8  christos       param_len = strlen (param) + 1;
   2532  1.8  christos       memmove (op + op_len, param, param_len);
   2533  1.1  christos     }
   2534  1.1  christos 
   2535  1.1  christos   /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
   2536  1.1  christos      lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
   2537  1.6  christos      as CR16 core doesn't support lsh[b/w] right shift operations.  */
   2538  1.1  christos   if ((streq ("lshb", op) || streq ("lshw", op) || streq ("lshd", op))
   2539  1.1  christos       && (param [0] == '$'))
   2540  1.1  christos     {
   2541  1.1  christos       strcpy (param1, param);
   2542  1.1  christos       /* Find the instruction.  */
   2543  1.8  christos       instruction = (const inst *) str_hash_find (cr16_inst_hash, op);
   2544  1.8  christos       parse_operands (&cr16_ins, param1);
   2545  1.1  christos       if (((&cr16_ins)->arg[0].type == arg_ic)
   2546  1.8  christos 	  && ((&cr16_ins)->arg[0].constant >= 0))
   2547  1.8  christos 	{
   2548  1.8  christos 	  if (streq ("lshb", op))
   2549  1.8  christos 	    cr16_assemble ("ashub", param);
   2550  1.8  christos 	  else if (streq ("lshd", op))
   2551  1.8  christos 	    cr16_assemble ("ashud", param);
   2552  1.8  christos 	  else
   2553  1.8  christos 	    cr16_assemble ("ashuw", param);
   2554  1.8  christos 	  return;
   2555  1.8  christos 	}
   2556  1.1  christos     }
   2557  1.1  christos 
   2558  1.5  christos   cr16_assemble (op, param);
   2559  1.1  christos }
   2560