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