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