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