Home | History | Annotate | Line # | Download | only in config
tc-crx.c revision 1.1.1.5
      1      1.1     skrll /* tc-crx.c -- Assembler code for the CRX CPU core.
      2  1.1.1.5  christos    Copyright (C) 2004-2016 Free Software Foundation, Inc.
      3      1.1     skrll 
      4      1.1     skrll    Contributed by Tomer Levi, NSC, Israel.
      5      1.1     skrll    Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
      6      1.1     skrll    Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
      7      1.1     skrll 
      8      1.1     skrll    This file is part of GAS, the GNU Assembler.
      9      1.1     skrll 
     10      1.1     skrll    GAS is free software; you can redistribute it and/or modify
     11      1.1     skrll    it under the terms of the GNU General Public License as published by
     12      1.1     skrll    the Free Software Foundation; either version 3, or (at your option)
     13      1.1     skrll    any later version.
     14      1.1     skrll 
     15      1.1     skrll    GAS is distributed in the hope that it will be useful,
     16      1.1     skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     17      1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18      1.1     skrll    GNU General Public License for more details.
     19      1.1     skrll 
     20      1.1     skrll    You should have received a copy of the GNU General Public License
     21      1.1     skrll    along with GAS; see the file COPYING.  If not, write to the
     22      1.1     skrll    Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
     23      1.1     skrll    MA 02110-1301, USA.  */
     24      1.1     skrll 
     25      1.1     skrll #include "as.h"
     26  1.1.1.3  christos #include "bfd_stdint.h"
     27      1.1     skrll #include "safe-ctype.h"
     28      1.1     skrll #include "dwarf2dbg.h"
     29      1.1     skrll #include "opcode/crx.h"
     30      1.1     skrll #include "elf/crx.h"
     31      1.1     skrll 
     32      1.1     skrll /* Word is considered here as a 16-bit unsigned short int.  */
     33      1.1     skrll #define WORD_SHIFT  16
     34      1.1     skrll 
     35      1.1     skrll /* Register is 4-bit size.  */
     36      1.1     skrll #define REG_SIZE   4
     37      1.1     skrll 
     38      1.1     skrll /* Maximum size of a single instruction (in words).  */
     39      1.1     skrll #define INSN_MAX_SIZE   3
     40      1.1     skrll 
     41      1.1     skrll /* Maximum bits which may be set in a `mask16' operand.  */
     42      1.1     skrll #define MAX_REGS_IN_MASK16  8
     43      1.1     skrll 
     44      1.1     skrll /* Utility macros for string comparison.  */
     45      1.1     skrll #define streq(a, b)           (strcmp (a, b) == 0)
     46      1.1     skrll #define strneq(a, b, c)       (strncmp (a, b, c) == 0)
     47      1.1     skrll 
     48      1.1     skrll /* Assign a number NUM, shifted by SHIFT bytes, into a location
     49      1.1     skrll    pointed by index BYTE of array 'output_opcode'.  */
     50      1.1     skrll #define CRX_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM << SHIFT)
     51      1.1     skrll 
     52      1.1     skrll /* Operand errors.  */
     53      1.1     skrll typedef enum
     54      1.1     skrll   {
     55      1.1     skrll     OP_LEGAL = 0,	/* Legal operand.  */
     56      1.1     skrll     OP_OUT_OF_RANGE,	/* Operand not within permitted range.  */
     57      1.1     skrll     OP_NOT_EVEN,	/* Operand is Odd number, should be even.  */
     58      1.1     skrll     OP_ILLEGAL_DISPU4,	/* Operand is not within DISPU4 range.  */
     59      1.1     skrll     OP_ILLEGAL_CST4,	/* Operand is not within CST4 range.  */
     60  1.1.1.4  christos     OP_NOT_UPPER_64KB	/* Operand is not within the upper 64KB
     61      1.1     skrll 			   (0xFFFF0000-0xFFFFFFFF).  */
     62      1.1     skrll   }
     63      1.1     skrll op_err;
     64      1.1     skrll 
     65      1.1     skrll /* Opcode mnemonics hash table.  */
     66      1.1     skrll static struct hash_control *crx_inst_hash;
     67      1.1     skrll /* CRX registers hash table.  */
     68      1.1     skrll static struct hash_control *reg_hash;
     69      1.1     skrll /* CRX coprocessor registers hash table.  */
     70      1.1     skrll static struct hash_control *copreg_hash;
     71      1.1     skrll /* Current instruction we're assembling.  */
     72      1.1     skrll const inst *instruction;
     73      1.1     skrll 
     74      1.1     skrll /* Global variables.  */
     75      1.1     skrll 
     76      1.1     skrll /* Array to hold an instruction encoding.  */
     77      1.1     skrll long output_opcode[2];
     78      1.1     skrll 
     79      1.1     skrll /* Nonzero means a relocatable symbol.  */
     80      1.1     skrll int relocatable;
     81      1.1     skrll 
     82      1.1     skrll /* A copy of the original instruction (used in error messages).  */
     83      1.1     skrll char ins_parse[MAX_INST_LEN];
     84      1.1     skrll 
     85      1.1     skrll /* The current processed argument number.  */
     86      1.1     skrll int cur_arg_num;
     87      1.1     skrll 
     88      1.1     skrll /* Generic assembler global variables which must be defined by all targets.  */
     89      1.1     skrll 
     90      1.1     skrll /* Characters which always start a comment.  */
     91      1.1     skrll const char comment_chars[] = "#";
     92      1.1     skrll 
     93      1.1     skrll /* Characters which start a comment at the beginning of a line.  */
     94      1.1     skrll const char line_comment_chars[] = "#";
     95      1.1     skrll 
     96      1.1     skrll /* This array holds machine specific line separator characters.  */
     97      1.1     skrll const char line_separator_chars[] = ";";
     98      1.1     skrll 
     99      1.1     skrll /* Chars that can be used to separate mant from exp in floating point nums.  */
    100      1.1     skrll const char EXP_CHARS[] = "eE";
    101      1.1     skrll 
    102      1.1     skrll /* Chars that mean this number is a floating point constant as in 0f12.456  */
    103      1.1     skrll const char FLT_CHARS[] = "f'";
    104      1.1     skrll 
    105      1.1     skrll /* Target-specific multicharacter options, not const-declared at usage.  */
    106      1.1     skrll const char *md_shortopts = "";
    107      1.1     skrll struct option md_longopts[] =
    108      1.1     skrll {
    109      1.1     skrll   {NULL, no_argument, NULL, 0}
    110      1.1     skrll };
    111      1.1     skrll size_t md_longopts_size = sizeof (md_longopts);
    112      1.1     skrll 
    113      1.1     skrll /* This table describes all the machine specific pseudo-ops
    114      1.1     skrll    the assembler has to support.  The fields are:
    115      1.1     skrll    *** Pseudo-op name without dot.
    116      1.1     skrll    *** Function to call to execute this pseudo-op.
    117      1.1     skrll    *** Integer arg to pass to the function.  */
    118      1.1     skrll 
    119      1.1     skrll const pseudo_typeS md_pseudo_table[] =
    120      1.1     skrll {
    121      1.1     skrll   /* In CRX machine, align is in bytes (not a ptwo boundary).  */
    122      1.1     skrll   {"align", s_align_bytes, 0},
    123      1.1     skrll   {0, 0, 0}
    124      1.1     skrll };
    125      1.1     skrll 
    126      1.1     skrll /* CRX relaxation table.  */
    127      1.1     skrll const relax_typeS md_relax_table[] =
    128      1.1     skrll {
    129      1.1     skrll   /* bCC  */
    130      1.1     skrll   {0xfa, -0x100, 2, 1},			/*  8 */
    131      1.1     skrll   {0xfffe, -0x10000, 4, 2},		/* 16 */
    132      1.1     skrll   {0xfffffffe, -0xfffffffe, 6, 0},	/* 32 */
    133      1.1     skrll 
    134      1.1     skrll   /* bal  */
    135      1.1     skrll   {0xfffe, -0x10000, 4, 4},		/* 16 */
    136      1.1     skrll   {0xfffffffe, -0xfffffffe, 6, 0},	/* 32 */
    137      1.1     skrll 
    138      1.1     skrll   /* cmpbr/bcop  */
    139      1.1     skrll   {0xfe, -0x100, 4, 6},			/*  8 */
    140      1.1     skrll   {0xfffffe, -0x1000000, 6, 0}		/* 24 */
    141      1.1     skrll };
    142      1.1     skrll 
    143      1.1     skrll static void    reset_vars	        (char *);
    144      1.1     skrll static reg     get_register	        (char *);
    145      1.1     skrll static copreg  get_copregister	        (char *);
    146      1.1     skrll static argtype get_optype	        (operand_type);
    147      1.1     skrll static int     get_opbits	        (operand_type);
    148      1.1     skrll static int     get_opflags	        (operand_type);
    149      1.1     skrll static int     get_number_of_operands   (void);
    150      1.1     skrll static void    parse_operand	        (char *, ins *);
    151  1.1.1.2  christos static int     gettrap		        (const char *);
    152  1.1.1.2  christos static void    handle_LoadStor	        (const char *);
    153  1.1.1.2  christos static int     get_cinv_parameters      (const char *);
    154      1.1     skrll static long    getconstant		(long, int);
    155      1.1     skrll static op_err  check_range		(long *, int, unsigned int, int);
    156      1.1     skrll static int     getreg_image	        (reg);
    157      1.1     skrll static void    parse_operands	        (ins *, char *);
    158      1.1     skrll static void    parse_insn	        (ins *, char *);
    159      1.1     skrll static void    print_operand	        (int, int, argument *);
    160      1.1     skrll static void    print_constant	        (int, int, argument *);
    161      1.1     skrll static int     exponent2scale	        (int);
    162      1.1     skrll static void    mask_reg		        (int, unsigned short *);
    163      1.1     skrll static void    process_label_constant   (char *, ins *);
    164      1.1     skrll static void    set_operand	        (char *, ins *);
    165      1.1     skrll static char *  preprocess_reglist       (char *, int *);
    166      1.1     skrll static int     assemble_insn	        (char *, ins *);
    167      1.1     skrll static void    print_insn	        (ins *);
    168      1.1     skrll static void    warn_if_needed		(ins *);
    169      1.1     skrll static int     adjust_if_needed		(ins *);
    170      1.1     skrll 
    171      1.1     skrll /* Return the bit size for a given operand.  */
    172      1.1     skrll 
    173      1.1     skrll static int
    174      1.1     skrll get_opbits (operand_type op)
    175      1.1     skrll {
    176      1.1     skrll   if (op < MAX_OPRD)
    177      1.1     skrll     return crx_optab[op].bit_size;
    178      1.1     skrll   else
    179      1.1     skrll     return 0;
    180      1.1     skrll }
    181      1.1     skrll 
    182      1.1     skrll /* Return the argument type of a given operand.  */
    183      1.1     skrll 
    184      1.1     skrll static argtype
    185      1.1     skrll get_optype (operand_type op)
    186      1.1     skrll {
    187      1.1     skrll   if (op < MAX_OPRD)
    188      1.1     skrll     return crx_optab[op].arg_type;
    189      1.1     skrll   else
    190      1.1     skrll     return nullargs;
    191      1.1     skrll }
    192      1.1     skrll 
    193      1.1     skrll /* Return the flags of a given operand.  */
    194      1.1     skrll 
    195      1.1     skrll static int
    196      1.1     skrll get_opflags (operand_type op)
    197      1.1     skrll {
    198      1.1     skrll   if (op < MAX_OPRD)
    199      1.1     skrll     return crx_optab[op].flags;
    200      1.1     skrll   else
    201      1.1     skrll     return 0;
    202      1.1     skrll }
    203      1.1     skrll 
    204      1.1     skrll /* Get the core processor register 'reg_name'.  */
    205      1.1     skrll 
    206      1.1     skrll static reg
    207      1.1     skrll get_register (char *reg_name)
    208      1.1     skrll {
    209  1.1.1.2  christos   const reg_entry *rreg;
    210      1.1     skrll 
    211  1.1.1.2  christos   rreg = (const reg_entry *) hash_find (reg_hash, reg_name);
    212      1.1     skrll 
    213  1.1.1.2  christos   if (rreg != NULL)
    214  1.1.1.2  christos     return rreg->value.reg_val;
    215      1.1     skrll   else
    216      1.1     skrll     return nullregister;
    217      1.1     skrll }
    218      1.1     skrll 
    219      1.1     skrll /* Get the coprocessor register 'copreg_name'.  */
    220      1.1     skrll 
    221      1.1     skrll static copreg
    222      1.1     skrll get_copregister (char *copreg_name)
    223      1.1     skrll {
    224  1.1.1.2  christos   const reg_entry *coreg;
    225      1.1     skrll 
    226  1.1.1.2  christos   coreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
    227      1.1     skrll 
    228  1.1.1.2  christos   if (coreg != NULL)
    229  1.1.1.2  christos     return coreg->value.copreg_val;
    230      1.1     skrll   else
    231      1.1     skrll     return nullcopregister;
    232      1.1     skrll }
    233      1.1     skrll 
    234      1.1     skrll /* Round up a section size to the appropriate boundary.  */
    235      1.1     skrll 
    236      1.1     skrll valueT
    237      1.1     skrll md_section_align (segT seg, valueT val)
    238      1.1     skrll {
    239      1.1     skrll   /* Round .text section to a multiple of 2.  */
    240      1.1     skrll   if (seg == text_section)
    241      1.1     skrll     return (val + 1) & ~1;
    242      1.1     skrll   return val;
    243      1.1     skrll }
    244      1.1     skrll 
    245      1.1     skrll /* Parse an operand that is machine-specific (remove '*').  */
    246      1.1     skrll 
    247      1.1     skrll void
    248      1.1     skrll md_operand (expressionS * exp)
    249      1.1     skrll {
    250      1.1     skrll   char c = *input_line_pointer;
    251      1.1     skrll 
    252      1.1     skrll   switch (c)
    253      1.1     skrll     {
    254      1.1     skrll     case '*':
    255      1.1     skrll       input_line_pointer++;
    256      1.1     skrll       expression (exp);
    257      1.1     skrll       break;
    258      1.1     skrll     default:
    259      1.1     skrll       break;
    260      1.1     skrll     }
    261      1.1     skrll }
    262      1.1     skrll 
    263      1.1     skrll /* Reset global variables before parsing a new instruction.  */
    264      1.1     skrll 
    265      1.1     skrll static void
    266      1.1     skrll reset_vars (char *op)
    267      1.1     skrll {
    268      1.1     skrll   cur_arg_num = relocatable = 0;
    269      1.1     skrll   memset (& output_opcode, '\0', sizeof (output_opcode));
    270      1.1     skrll 
    271      1.1     skrll   /* Save a copy of the original OP (used in error messages).  */
    272      1.1     skrll   strncpy (ins_parse, op, sizeof ins_parse - 1);
    273      1.1     skrll   ins_parse [sizeof ins_parse - 1] = 0;
    274      1.1     skrll }
    275      1.1     skrll 
    276      1.1     skrll /* This macro decides whether a particular reloc is an entry in a
    277      1.1     skrll    switch table.  It is used when relaxing, because the linker needs
    278      1.1     skrll    to know about all such entries so that it can adjust them if
    279      1.1     skrll    necessary.  */
    280      1.1     skrll 
    281      1.1     skrll #define SWITCH_TABLE(fix)				  \
    282      1.1     skrll   (   (fix)->fx_addsy != NULL				  \
    283      1.1     skrll    && (fix)->fx_subsy != NULL				  \
    284      1.1     skrll    && S_GET_SEGMENT ((fix)->fx_addsy) ==		  \
    285      1.1     skrll       S_GET_SEGMENT ((fix)->fx_subsy)			  \
    286      1.1     skrll    && S_GET_SEGMENT (fix->fx_addsy) != undefined_section  \
    287      1.1     skrll    && (   (fix)->fx_r_type == BFD_RELOC_CRX_NUM8	  \
    288      1.1     skrll        || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16	  \
    289      1.1     skrll        || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
    290      1.1     skrll 
    291      1.1     skrll /* See whether we need to force a relocation into the output file.
    292      1.1     skrll    This is used to force out switch and PC relative relocations when
    293      1.1     skrll    relaxing.  */
    294      1.1     skrll 
    295      1.1     skrll int
    296      1.1     skrll crx_force_relocation (fixS *fix)
    297      1.1     skrll {
    298      1.1     skrll   if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
    299      1.1     skrll     return 1;
    300      1.1     skrll 
    301      1.1     skrll   return 0;
    302      1.1     skrll }
    303      1.1     skrll 
    304      1.1     skrll /* Generate a relocation entry for a fixup.  */
    305      1.1     skrll 
    306      1.1     skrll arelent *
    307      1.1     skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
    308      1.1     skrll {
    309      1.1     skrll   arelent * reloc;
    310      1.1     skrll 
    311  1.1.1.5  christos   reloc = XNEW (arelent);
    312  1.1.1.5  christos   reloc->sym_ptr_ptr  = XNEW (asymbol *);
    313      1.1     skrll   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
    314      1.1     skrll   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
    315      1.1     skrll   reloc->addend = fixP->fx_offset;
    316      1.1     skrll 
    317      1.1     skrll   if (fixP->fx_subsy != NULL)
    318      1.1     skrll     {
    319      1.1     skrll       if (SWITCH_TABLE (fixP))
    320      1.1     skrll 	{
    321      1.1     skrll 	  /* Keep the current difference in the addend.  */
    322      1.1     skrll 	  reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
    323      1.1     skrll 			   - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
    324      1.1     skrll 
    325      1.1     skrll 	  switch (fixP->fx_r_type)
    326      1.1     skrll 	    {
    327      1.1     skrll 	    case BFD_RELOC_CRX_NUM8:
    328      1.1     skrll 	      fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
    329      1.1     skrll 	      break;
    330      1.1     skrll 	    case BFD_RELOC_CRX_NUM16:
    331      1.1     skrll 	      fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
    332      1.1     skrll 	      break;
    333      1.1     skrll 	    case BFD_RELOC_CRX_NUM32:
    334      1.1     skrll 	      fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
    335      1.1     skrll 	      break;
    336      1.1     skrll 	    default:
    337      1.1     skrll 	      abort ();
    338      1.1     skrll 	      break;
    339      1.1     skrll 	    }
    340      1.1     skrll 	}
    341      1.1     skrll       else
    342      1.1     skrll 	{
    343      1.1     skrll 	  /* We only resolve difference expressions in the same section.  */
    344      1.1     skrll 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    345      1.1     skrll 			_("can't resolve `%s' {%s section} - `%s' {%s section}"),
    346      1.1     skrll 			fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
    347      1.1     skrll 			segment_name (fixP->fx_addsy
    348      1.1     skrll 				      ? S_GET_SEGMENT (fixP->fx_addsy)
    349      1.1     skrll 				      : absolute_section),
    350      1.1     skrll 			S_GET_NAME (fixP->fx_subsy),
    351      1.1     skrll 			segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
    352      1.1     skrll 	}
    353      1.1     skrll     }
    354      1.1     skrll 
    355  1.1.1.2  christos   gas_assert ((int) fixP->fx_r_type > 0);
    356      1.1     skrll   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
    357      1.1     skrll 
    358      1.1     skrll   if (reloc->howto == (reloc_howto_type *) NULL)
    359      1.1     skrll     {
    360      1.1     skrll       as_bad_where (fixP->fx_file, fixP->fx_line,
    361      1.1     skrll 		    _("internal error: reloc %d (`%s') not supported by object file format"),
    362      1.1     skrll 		    fixP->fx_r_type,
    363      1.1     skrll 		    bfd_get_reloc_code_name (fixP->fx_r_type));
    364      1.1     skrll       return NULL;
    365      1.1     skrll     }
    366  1.1.1.2  christos   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
    367      1.1     skrll 
    368      1.1     skrll   return reloc;
    369      1.1     skrll }
    370      1.1     skrll 
    371      1.1     skrll /* Prepare machine-dependent frags for relaxation.  */
    372      1.1     skrll 
    373      1.1     skrll int
    374      1.1     skrll md_estimate_size_before_relax (fragS *fragp, asection *seg)
    375      1.1     skrll {
    376      1.1     skrll   /* If symbol is undefined or located in a different section,
    377      1.1     skrll      select the largest supported relocation.  */
    378      1.1     skrll   relax_substateT subtype;
    379      1.1     skrll   relax_substateT rlx_state[] = {0, 2,
    380      1.1     skrll 				 3, 4,
    381      1.1     skrll 				 5, 6};
    382      1.1     skrll 
    383      1.1     skrll   for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
    384      1.1     skrll     {
    385      1.1     skrll       if (fragp->fr_subtype == rlx_state[subtype]
    386      1.1     skrll 	  && (!S_IS_DEFINED (fragp->fr_symbol)
    387      1.1     skrll 	      || seg != S_GET_SEGMENT (fragp->fr_symbol)))
    388      1.1     skrll 	{
    389      1.1     skrll 	  fragp->fr_subtype = rlx_state[subtype + 1];
    390      1.1     skrll 	  break;
    391      1.1     skrll 	}
    392      1.1     skrll     }
    393      1.1     skrll 
    394      1.1     skrll   if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
    395      1.1     skrll     abort ();
    396      1.1     skrll 
    397      1.1     skrll   return md_relax_table[fragp->fr_subtype].rlx_length;
    398      1.1     skrll }
    399      1.1     skrll 
    400      1.1     skrll void
    401      1.1     skrll md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
    402      1.1     skrll {
    403      1.1     skrll   /* 'opcode' points to the start of the instruction, whether
    404      1.1     skrll      we need to change the instruction's fixed encoding.  */
    405      1.1     skrll   char *opcode = fragP->fr_literal + fragP->fr_fix;
    406      1.1     skrll   bfd_reloc_code_real_type reloc;
    407      1.1     skrll 
    408      1.1     skrll   subseg_change (sec, 0);
    409      1.1     skrll 
    410      1.1     skrll   switch (fragP->fr_subtype)
    411      1.1     skrll     {
    412      1.1     skrll     case 0:
    413      1.1     skrll       reloc = BFD_RELOC_CRX_REL8;
    414      1.1     skrll       break;
    415      1.1     skrll     case 1:
    416      1.1     skrll       *opcode = 0x7e;
    417      1.1     skrll       reloc = BFD_RELOC_CRX_REL16;
    418      1.1     skrll       break;
    419      1.1     skrll     case 2:
    420      1.1     skrll       *opcode = 0x7f;
    421      1.1     skrll       reloc = BFD_RELOC_CRX_REL32;
    422      1.1     skrll       break;
    423      1.1     skrll     case 3:
    424      1.1     skrll       reloc = BFD_RELOC_CRX_REL16;
    425      1.1     skrll       break;
    426      1.1     skrll     case 4:
    427      1.1     skrll       *++opcode = 0x31;
    428      1.1     skrll       reloc = BFD_RELOC_CRX_REL32;
    429      1.1     skrll       break;
    430      1.1     skrll     case 5:
    431      1.1     skrll       reloc = BFD_RELOC_CRX_REL8_CMP;
    432      1.1     skrll       break;
    433      1.1     skrll     case 6:
    434      1.1     skrll       *++opcode = 0x31;
    435      1.1     skrll       reloc = BFD_RELOC_CRX_REL24;
    436      1.1     skrll       break;
    437      1.1     skrll     default:
    438      1.1     skrll       abort ();
    439      1.1     skrll       break;
    440      1.1     skrll     }
    441      1.1     skrll 
    442      1.1     skrll     fix_new (fragP, fragP->fr_fix,
    443      1.1     skrll 	     bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
    444      1.1     skrll 	     fragP->fr_symbol, fragP->fr_offset, 1, reloc);
    445      1.1     skrll     fragP->fr_var = 0;
    446      1.1     skrll     fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
    447      1.1     skrll }
    448      1.1     skrll 
    449      1.1     skrll /* Process machine-dependent command line options.  Called once for
    450      1.1     skrll    each option on the command line that the machine-independent part of
    451      1.1     skrll    GAS does not understand.  */
    452      1.1     skrll 
    453      1.1     skrll int
    454  1.1.1.5  christos md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
    455      1.1     skrll {
    456      1.1     skrll   return 0;
    457      1.1     skrll }
    458      1.1     skrll 
    459      1.1     skrll /* Machine-dependent usage-output.  */
    460      1.1     skrll 
    461      1.1     skrll void
    462      1.1     skrll md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
    463      1.1     skrll {
    464      1.1     skrll   return;
    465      1.1     skrll }
    466      1.1     skrll 
    467  1.1.1.5  christos const char *
    468      1.1     skrll md_atof (int type, char *litP, int *sizeP)
    469      1.1     skrll {
    470      1.1     skrll   return ieee_md_atof (type, litP, sizeP, target_big_endian);
    471      1.1     skrll }
    472      1.1     skrll 
    473      1.1     skrll /* Apply a fixS (fixup of an instruction or data that we didn't have
    474      1.1     skrll    enough info to complete immediately) to the data in a frag.
    475      1.1     skrll    Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
    476      1.1     skrll    relaxation of debug sections, this function is called only when
    477      1.1     skrll    fixuping relocations of debug sections.  */
    478      1.1     skrll 
    479      1.1     skrll void
    480      1.1     skrll md_apply_fix (fixS *fixP, valueT *valP, segT seg)
    481      1.1     skrll {
    482      1.1     skrll   valueT val = * valP;
    483      1.1     skrll   char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
    484      1.1     skrll   fixP->fx_offset = 0;
    485      1.1     skrll 
    486      1.1     skrll   switch (fixP->fx_r_type)
    487      1.1     skrll     {
    488      1.1     skrll     case BFD_RELOC_CRX_NUM8:
    489      1.1     skrll       bfd_put_8 (stdoutput, (unsigned char) val, buf);
    490      1.1     skrll       break;
    491      1.1     skrll     case BFD_RELOC_CRX_NUM16:
    492      1.1     skrll       bfd_put_16 (stdoutput, val, buf);
    493      1.1     skrll       break;
    494      1.1     skrll     case BFD_RELOC_CRX_NUM32:
    495      1.1     skrll       bfd_put_32 (stdoutput, val, buf);
    496      1.1     skrll       break;
    497      1.1     skrll     default:
    498      1.1     skrll       /* We shouldn't ever get here because linkrelax is nonzero.  */
    499      1.1     skrll       abort ();
    500      1.1     skrll       break;
    501      1.1     skrll     }
    502      1.1     skrll 
    503      1.1     skrll   fixP->fx_done = 0;
    504      1.1     skrll 
    505      1.1     skrll   if (fixP->fx_addsy == NULL
    506      1.1     skrll       && fixP->fx_pcrel == 0)
    507      1.1     skrll     fixP->fx_done = 1;
    508      1.1     skrll 
    509      1.1     skrll   if (fixP->fx_pcrel == 1
    510      1.1     skrll       && fixP->fx_addsy != NULL
    511      1.1     skrll       && S_GET_SEGMENT (fixP->fx_addsy) == seg)
    512      1.1     skrll     fixP->fx_done = 1;
    513      1.1     skrll }
    514      1.1     skrll 
    515      1.1     skrll /* The location from which a PC relative jump should be calculated,
    516      1.1     skrll    given a PC relative reloc.  */
    517      1.1     skrll 
    518      1.1     skrll long
    519      1.1     skrll md_pcrel_from (fixS *fixp)
    520      1.1     skrll {
    521      1.1     skrll   return fixp->fx_frag->fr_address + fixp->fx_where;
    522      1.1     skrll }
    523      1.1     skrll 
    524      1.1     skrll /* This function is called once, at assembler startup time.  This should
    525      1.1     skrll    set up all the tables, etc that the MD part of the assembler needs.  */
    526      1.1     skrll 
    527      1.1     skrll void
    528      1.1     skrll md_begin (void)
    529      1.1     skrll {
    530      1.1     skrll   const char *hashret = NULL;
    531      1.1     skrll   int i = 0;
    532      1.1     skrll 
    533      1.1     skrll   /* Set up a hash table for the instructions.  */
    534      1.1     skrll   if ((crx_inst_hash = hash_new ()) == NULL)
    535      1.1     skrll     as_fatal (_("Virtual memory exhausted"));
    536  1.1.1.4  christos 
    537      1.1     skrll   while (crx_instruction[i].mnemonic != NULL)
    538      1.1     skrll     {
    539      1.1     skrll       const char *mnemonic = crx_instruction[i].mnemonic;
    540      1.1     skrll 
    541      1.1     skrll       hashret = hash_insert (crx_inst_hash, mnemonic,
    542      1.1     skrll 			     (void *) &crx_instruction[i]);
    543      1.1     skrll 
    544      1.1     skrll       if (hashret != NULL && *hashret != '\0')
    545      1.1     skrll 	as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
    546      1.1     skrll 		  *hashret == 0 ? _("(unknown reason)") : hashret);
    547      1.1     skrll 
    548      1.1     skrll       /* Insert unique names into hash table.  The CRX instruction set
    549      1.1     skrll 	 has many identical opcode names that have different opcodes based
    550      1.1     skrll 	 on the operands.  This hash table then provides a quick index to
    551      1.1     skrll 	 the first opcode with a particular name in the opcode table.  */
    552      1.1     skrll       do
    553      1.1     skrll 	{
    554      1.1     skrll 	  ++i;
    555      1.1     skrll 	}
    556      1.1     skrll       while (crx_instruction[i].mnemonic != NULL
    557      1.1     skrll 	     && streq (crx_instruction[i].mnemonic, mnemonic));
    558      1.1     skrll     }
    559      1.1     skrll 
    560      1.1     skrll   /* Initialize reg_hash hash table.  */
    561      1.1     skrll   if ((reg_hash = hash_new ()) == NULL)
    562      1.1     skrll     as_fatal (_("Virtual memory exhausted"));
    563      1.1     skrll 
    564      1.1     skrll   {
    565      1.1     skrll     const reg_entry *regtab;
    566      1.1     skrll 
    567      1.1     skrll     for (regtab = crx_regtab;
    568      1.1     skrll 	 regtab < (crx_regtab + NUMREGS); regtab++)
    569      1.1     skrll       {
    570      1.1     skrll 	hashret = hash_insert (reg_hash, regtab->name, (void *) regtab);
    571      1.1     skrll 	if (hashret)
    572      1.1     skrll 	  as_fatal (_("Internal Error:  Can't hash %s: %s"),
    573      1.1     skrll 		    regtab->name,
    574      1.1     skrll 		    hashret);
    575      1.1     skrll       }
    576      1.1     skrll   }
    577      1.1     skrll 
    578      1.1     skrll   /* Initialize copreg_hash hash table.  */
    579      1.1     skrll   if ((copreg_hash = hash_new ()) == NULL)
    580      1.1     skrll     as_fatal (_("Virtual memory exhausted"));
    581      1.1     skrll 
    582      1.1     skrll   {
    583      1.1     skrll     const reg_entry *copregtab;
    584      1.1     skrll 
    585      1.1     skrll     for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
    586      1.1     skrll 	 copregtab++)
    587      1.1     skrll       {
    588      1.1     skrll 	hashret = hash_insert (copreg_hash, copregtab->name,
    589      1.1     skrll 			       (void *) copregtab);
    590      1.1     skrll 	if (hashret)
    591      1.1     skrll 	  as_fatal (_("Internal Error:  Can't hash %s: %s"),
    592      1.1     skrll 		    copregtab->name,
    593      1.1     skrll 		    hashret);
    594      1.1     skrll       }
    595      1.1     skrll   }
    596      1.1     skrll   /*  Set linkrelax here to avoid fixups in most sections.  */
    597      1.1     skrll   linkrelax = 1;
    598      1.1     skrll }
    599      1.1     skrll 
    600  1.1.1.4  christos /* Process constants (immediate/absolute)
    601      1.1     skrll    and labels (jump targets/Memory locations).  */
    602      1.1     skrll 
    603      1.1     skrll static void
    604      1.1     skrll process_label_constant (char *str, ins * crx_ins)
    605      1.1     skrll {
    606      1.1     skrll   char *saved_input_line_pointer;
    607      1.1     skrll   argument *cur_arg = &crx_ins->arg[cur_arg_num];  /* Current argument.  */
    608      1.1     skrll 
    609      1.1     skrll   saved_input_line_pointer = input_line_pointer;
    610      1.1     skrll   input_line_pointer = str;
    611      1.1     skrll 
    612      1.1     skrll   expression (&crx_ins->exp);
    613  1.1.1.4  christos 
    614      1.1     skrll   switch (crx_ins->exp.X_op)
    615      1.1     skrll     {
    616      1.1     skrll     case O_big:
    617      1.1     skrll     case O_absent:
    618      1.1     skrll       /* Missing or bad expr becomes absolute 0.  */
    619      1.1     skrll       as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
    620      1.1     skrll 	      str);
    621      1.1     skrll       crx_ins->exp.X_op = O_constant;
    622      1.1     skrll       crx_ins->exp.X_add_number = 0;
    623      1.1     skrll       crx_ins->exp.X_add_symbol = (symbolS *) 0;
    624      1.1     skrll       crx_ins->exp.X_op_symbol = (symbolS *) 0;
    625      1.1     skrll       /* Fall through.  */
    626      1.1     skrll 
    627      1.1     skrll     case O_constant:
    628      1.1     skrll       cur_arg->X_op = O_constant;
    629      1.1     skrll       cur_arg->constant = crx_ins->exp.X_add_number;
    630      1.1     skrll       break;
    631      1.1     skrll 
    632      1.1     skrll     case O_symbol:
    633      1.1     skrll     case O_subtract:
    634      1.1     skrll     case O_add:
    635      1.1     skrll       cur_arg->X_op = O_symbol;
    636      1.1     skrll       crx_ins->rtype = BFD_RELOC_NONE;
    637      1.1     skrll       relocatable = 1;
    638      1.1     skrll 
    639      1.1     skrll       switch (cur_arg->type)
    640      1.1     skrll 	{
    641      1.1     skrll 	case arg_cr:
    642      1.1     skrll           if (IS_INSN_TYPE (LD_STOR_INS_INC))
    643      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
    644      1.1     skrll           else if (IS_INSN_TYPE (CSTBIT_INS)
    645      1.1     skrll 		   || IS_INSN_TYPE (STOR_IMM_INS))
    646      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
    647      1.1     skrll           else
    648      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
    649      1.1     skrll 	  break;
    650      1.1     skrll 
    651      1.1     skrll 	case arg_idxr:
    652      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
    653      1.1     skrll 	  break;
    654  1.1.1.4  christos 
    655      1.1     skrll 	case arg_c:
    656      1.1     skrll           if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
    657      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_REL16;
    658      1.1     skrll 	  else if (IS_INSN_TYPE (BRANCH_INS))
    659      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_REL8;
    660      1.1     skrll           else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
    661      1.1     skrll 		   || IS_INSN_TYPE (CSTBIT_INS))
    662      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_ABS32;
    663      1.1     skrll 	  else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
    664      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_REL4;
    665      1.1     skrll           else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
    666      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
    667      1.1     skrll 	  break;
    668  1.1.1.4  christos 
    669      1.1     skrll 	case arg_ic:
    670      1.1     skrll           if (IS_INSN_TYPE (ARITH_INS))
    671      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_IMM32;
    672      1.1     skrll 	  else if (IS_INSN_TYPE (ARITH_BYTE_INS))
    673      1.1     skrll 	    crx_ins->rtype = BFD_RELOC_CRX_IMM16;
    674      1.1     skrll 	  break;
    675      1.1     skrll 	default:
    676      1.1     skrll 	  break;
    677      1.1     skrll       }
    678      1.1     skrll       break;
    679      1.1     skrll 
    680      1.1     skrll     default:
    681      1.1     skrll       cur_arg->X_op = crx_ins->exp.X_op;
    682      1.1     skrll       break;
    683      1.1     skrll     }
    684      1.1     skrll 
    685      1.1     skrll   input_line_pointer = saved_input_line_pointer;
    686      1.1     skrll   return;
    687      1.1     skrll }
    688      1.1     skrll 
    689      1.1     skrll /* Get the values of the scale to be encoded -
    690      1.1     skrll    used for the scaled index mode of addressing.  */
    691      1.1     skrll 
    692      1.1     skrll static int
    693      1.1     skrll exponent2scale (int val)
    694      1.1     skrll {
    695      1.1     skrll   int exponent;
    696      1.1     skrll 
    697      1.1     skrll   /* If 'val' is 0, the following 'for' will be an endless loop.  */
    698      1.1     skrll   if (val == 0)
    699      1.1     skrll     return 0;
    700      1.1     skrll 
    701      1.1     skrll   for (exponent = 0; (val != 1); val >>= 1, exponent++)
    702      1.1     skrll     ;
    703      1.1     skrll 
    704      1.1     skrll   return exponent;
    705      1.1     skrll }
    706      1.1     skrll 
    707      1.1     skrll /* Parsing different types of operands
    708      1.1     skrll    -> constants		    Immediate/Absolute/Relative numbers
    709      1.1     skrll    -> Labels		    Relocatable symbols
    710      1.1     skrll    -> (rbase)		    Register base
    711      1.1     skrll    -> disp(rbase)	    Register relative
    712      1.1     skrll    -> disp(rbase)+	    Post-increment mode
    713      1.1     skrll    -> disp(rbase,ridx,scl)  Register index mode  */
    714      1.1     skrll 
    715      1.1     skrll static void
    716      1.1     skrll set_operand (char *operand, ins * crx_ins)
    717      1.1     skrll {
    718      1.1     skrll   char *operandS; /* Pointer to start of sub-opearand.  */
    719      1.1     skrll   char *operandE; /* Pointer to end of sub-opearand.  */
    720      1.1     skrll   expressionS scale;
    721      1.1     skrll   int scale_val;
    722      1.1     skrll   char *input_save, c;
    723      1.1     skrll   argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument.  */
    724      1.1     skrll 
    725      1.1     skrll   /* Initialize pointers.  */
    726      1.1     skrll   operandS = operandE = operand;
    727      1.1     skrll 
    728      1.1     skrll   switch (cur_arg->type)
    729      1.1     skrll     {
    730      1.1     skrll     case arg_sc:    /* Case *+0x18.  */
    731      1.1     skrll     case arg_ic:    /* Case $0x18.  */
    732      1.1     skrll       operandS++;
    733      1.1     skrll     case arg_c:	    /* Case 0x18.  */
    734      1.1     skrll       /* Set constant.  */
    735      1.1     skrll       process_label_constant (operandS, crx_ins);
    736  1.1.1.4  christos 
    737      1.1     skrll       if (cur_arg->type != arg_ic)
    738      1.1     skrll 	cur_arg->type = arg_c;
    739      1.1     skrll       break;
    740      1.1     skrll 
    741      1.1     skrll     case arg_icr:   /* Case $0x18(r1).  */
    742      1.1     skrll       operandS++;
    743      1.1     skrll     case arg_cr:    /* Case 0x18(r1).   */
    744      1.1     skrll       /* Set displacement constant.  */
    745      1.1     skrll       while (*operandE != '(')
    746      1.1     skrll 	operandE++;
    747      1.1     skrll       *operandE = '\0';
    748      1.1     skrll       process_label_constant (operandS, crx_ins);
    749  1.1.1.4  christos       operandS = operandE;
    750      1.1     skrll     case arg_rbase: /* Case (r1).  */
    751      1.1     skrll       operandS++;
    752      1.1     skrll       /* Set register base.  */
    753      1.1     skrll       while (*operandE != ')')
    754      1.1     skrll 	operandE++;
    755      1.1     skrll       *operandE = '\0';
    756      1.1     skrll       if ((cur_arg->r = get_register (operandS)) == nullregister)
    757      1.1     skrll 	as_bad (_("Illegal register `%s' in Instruction `%s'"),
    758      1.1     skrll 		operandS, ins_parse);
    759      1.1     skrll 
    760      1.1     skrll       if (cur_arg->type != arg_rbase)
    761      1.1     skrll 	cur_arg->type = arg_cr;
    762      1.1     skrll       break;
    763      1.1     skrll 
    764      1.1     skrll     case arg_idxr:
    765      1.1     skrll       /* Set displacement constant.  */
    766      1.1     skrll       while (*operandE != '(')
    767      1.1     skrll 	operandE++;
    768      1.1     skrll       *operandE = '\0';
    769      1.1     skrll       process_label_constant (operandS, crx_ins);
    770      1.1     skrll       operandS = ++operandE;
    771  1.1.1.4  christos 
    772      1.1     skrll       /* Set register base.  */
    773      1.1     skrll       while ((*operandE != ',') && (! ISSPACE (*operandE)))
    774      1.1     skrll 	operandE++;
    775      1.1     skrll       *operandE++ = '\0';
    776      1.1     skrll       if ((cur_arg->r = get_register (operandS)) == nullregister)
    777      1.1     skrll 	as_bad (_("Illegal register `%s' in Instruction `%s'"),
    778      1.1     skrll 		operandS, ins_parse);
    779      1.1     skrll 
    780      1.1     skrll       /* Skip leading white space.  */
    781      1.1     skrll       while (ISSPACE (*operandE))
    782      1.1     skrll 	operandE++;
    783      1.1     skrll       operandS = operandE;
    784      1.1     skrll 
    785      1.1     skrll       /* Set register index.  */
    786      1.1     skrll       while ((*operandE != ')') && (*operandE != ','))
    787      1.1     skrll 	operandE++;
    788      1.1     skrll       c = *operandE;
    789      1.1     skrll       *operandE++ = '\0';
    790      1.1     skrll 
    791      1.1     skrll       if ((cur_arg->i_r = get_register (operandS)) == nullregister)
    792      1.1     skrll 	as_bad (_("Illegal register `%s' in Instruction `%s'"),
    793      1.1     skrll 		operandS, ins_parse);
    794      1.1     skrll 
    795      1.1     skrll       /* Skip leading white space.  */
    796      1.1     skrll       while (ISSPACE (*operandE))
    797      1.1     skrll 	operandE++;
    798      1.1     skrll       operandS = operandE;
    799      1.1     skrll 
    800      1.1     skrll       /* Set the scale.  */
    801      1.1     skrll       if (c == ')')
    802      1.1     skrll 	cur_arg->scale = 0;
    803      1.1     skrll       else
    804      1.1     skrll         {
    805      1.1     skrll 	  while (*operandE != ')')
    806      1.1     skrll 	    operandE++;
    807      1.1     skrll 	  *operandE = '\0';
    808      1.1     skrll 
    809      1.1     skrll 	  /* Preprocess the scale string.  */
    810      1.1     skrll 	  input_save = input_line_pointer;
    811      1.1     skrll 	  input_line_pointer = operandS;
    812      1.1     skrll 	  expression (&scale);
    813      1.1     skrll 	  input_line_pointer = input_save;
    814      1.1     skrll 
    815      1.1     skrll 	  scale_val = scale.X_add_number;
    816      1.1     skrll 
    817      1.1     skrll 	  /* Check if the scale value is legal.  */
    818      1.1     skrll           if (scale_val != 1 && scale_val != 2
    819      1.1     skrll               && scale_val != 4 && scale_val != 8)
    820      1.1     skrll 	    as_bad (_("Illegal Scale - `%d'"), scale_val);
    821      1.1     skrll 
    822      1.1     skrll 	  cur_arg->scale = exponent2scale (scale_val);
    823      1.1     skrll         }
    824      1.1     skrll       break;
    825      1.1     skrll 
    826      1.1     skrll     default:
    827      1.1     skrll       break;
    828      1.1     skrll     }
    829      1.1     skrll }
    830      1.1     skrll 
    831      1.1     skrll /* Parse a single operand.
    832      1.1     skrll    operand - Current operand to parse.
    833      1.1     skrll    crx_ins - Current assembled instruction.  */
    834      1.1     skrll 
    835      1.1     skrll static void
    836      1.1     skrll parse_operand (char *operand, ins * crx_ins)
    837      1.1     skrll {
    838      1.1     skrll   int ret_val;
    839      1.1     skrll   argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument.  */
    840      1.1     skrll 
    841      1.1     skrll   /* Initialize the type to NULL before parsing.  */
    842      1.1     skrll   cur_arg->type = nullargs;
    843      1.1     skrll 
    844      1.1     skrll   /* Check whether this is a general processor register.  */
    845      1.1     skrll   if ((ret_val = get_register (operand)) != nullregister)
    846      1.1     skrll     {
    847      1.1     skrll       cur_arg->type = arg_r;
    848      1.1     skrll       cur_arg->r = ret_val;
    849      1.1     skrll       cur_arg->X_op = O_register;
    850      1.1     skrll       return;
    851      1.1     skrll     }
    852      1.1     skrll 
    853      1.1     skrll   /* Check whether this is a core [special] coprocessor register.  */
    854      1.1     skrll   if ((ret_val = get_copregister (operand)) != nullcopregister)
    855      1.1     skrll     {
    856      1.1     skrll       cur_arg->type = arg_copr;
    857      1.1     skrll       if (ret_val >= cs0)
    858      1.1     skrll 	cur_arg->type = arg_copsr;
    859      1.1     skrll       cur_arg->cr = ret_val;
    860      1.1     skrll       cur_arg->X_op = O_register;
    861      1.1     skrll       return;
    862      1.1     skrll     }
    863      1.1     skrll 
    864      1.1     skrll   /* Deal with special characters.  */
    865      1.1     skrll   switch (operand[0])
    866      1.1     skrll     {
    867      1.1     skrll     case '$':
    868      1.1     skrll       if (strchr (operand, '(') != NULL)
    869      1.1     skrll 	cur_arg->type = arg_icr;
    870      1.1     skrll       else
    871      1.1     skrll         cur_arg->type = arg_ic;
    872      1.1     skrll       goto set_params;
    873      1.1     skrll       break;
    874      1.1     skrll 
    875      1.1     skrll     case '*':
    876      1.1     skrll       cur_arg->type = arg_sc;
    877      1.1     skrll       goto set_params;
    878      1.1     skrll       break;
    879      1.1     skrll 
    880      1.1     skrll     case '(':
    881      1.1     skrll       cur_arg->type = arg_rbase;
    882      1.1     skrll       goto set_params;
    883      1.1     skrll       break;
    884      1.1     skrll 
    885      1.1     skrll     default:
    886      1.1     skrll 	break;
    887      1.1     skrll     }
    888  1.1.1.4  christos 
    889      1.1     skrll   if (strchr (operand, '(') != NULL)
    890      1.1     skrll     {
    891      1.1     skrll       if (strchr (operand, ',') != NULL
    892      1.1     skrll           && (strchr (operand, ',') > strchr (operand, '(')))
    893      1.1     skrll 	    cur_arg->type = arg_idxr;
    894      1.1     skrll       else
    895      1.1     skrll 	cur_arg->type = arg_cr;
    896      1.1     skrll     }
    897      1.1     skrll   else
    898      1.1     skrll     cur_arg->type = arg_c;
    899      1.1     skrll   goto set_params;
    900      1.1     skrll 
    901      1.1     skrll /* Parse an operand according to its type.  */
    902      1.1     skrll set_params:
    903      1.1     skrll   cur_arg->constant = 0;
    904      1.1     skrll   set_operand (operand, crx_ins);
    905      1.1     skrll }
    906      1.1     skrll 
    907  1.1.1.4  christos /* Parse the various operands. Each operand is then analyzed to fillup
    908      1.1     skrll    the fields in the crx_ins data structure.  */
    909      1.1     skrll 
    910      1.1     skrll static void
    911      1.1     skrll parse_operands (ins * crx_ins, char *operands)
    912      1.1     skrll {
    913      1.1     skrll   char *operandS;	       /* Operands string.  */
    914      1.1     skrll   char *operandH, *operandT;   /* Single operand head/tail pointers.  */
    915      1.1     skrll   int allocated = 0;	       /* Indicates a new operands string was allocated.  */
    916      1.1     skrll   char *operand[MAX_OPERANDS]; /* Separating the operands.  */
    917      1.1     skrll   int op_num = 0;	       /* Current operand number we are parsing.  */
    918      1.1     skrll   int bracket_flag = 0;	       /* Indicates a bracket '(' was found.  */
    919      1.1     skrll   int sq_bracket_flag = 0;     /* Indicates a square bracket '[' was found.  */
    920      1.1     skrll 
    921      1.1     skrll   /* Preprocess the list of registers, if necessary.  */
    922      1.1     skrll   operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
    923      1.1     skrll     preprocess_reglist (operands, &allocated) : operands;
    924      1.1     skrll 
    925      1.1     skrll   while (*operandT != '\0')
    926      1.1     skrll     {
    927      1.1     skrll       if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
    928      1.1     skrll         {
    929      1.1     skrll 	  *operandT++ = '\0';
    930      1.1     skrll 	  operand[op_num++] = strdup (operandH);
    931      1.1     skrll           operandH = operandT;
    932      1.1     skrll           continue;
    933      1.1     skrll         }
    934      1.1     skrll 
    935      1.1     skrll       if (*operandT == ' ')
    936      1.1     skrll 	as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
    937      1.1     skrll 
    938      1.1     skrll       if (*operandT == '(')
    939      1.1     skrll 	bracket_flag = 1;
    940      1.1     skrll       else if (*operandT == '[')
    941      1.1     skrll 	sq_bracket_flag = 1;
    942      1.1     skrll 
    943      1.1     skrll       if (*operandT == ')')
    944      1.1     skrll 	{
    945      1.1     skrll 	  if (bracket_flag)
    946      1.1     skrll 	    bracket_flag = 0;
    947      1.1     skrll 	  else
    948      1.1     skrll 	    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
    949      1.1     skrll 	}
    950      1.1     skrll       else if (*operandT == ']')
    951      1.1     skrll 	{
    952      1.1     skrll 	  if (sq_bracket_flag)
    953      1.1     skrll 	    sq_bracket_flag = 0;
    954      1.1     skrll 	  else
    955      1.1     skrll 	    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
    956      1.1     skrll 	}
    957      1.1     skrll 
    958      1.1     skrll       if (bracket_flag == 1 && *operandT == ')')
    959      1.1     skrll 	bracket_flag = 0;
    960      1.1     skrll       else if (sq_bracket_flag == 1 && *operandT == ']')
    961      1.1     skrll 	sq_bracket_flag = 0;
    962      1.1     skrll 
    963      1.1     skrll       operandT++;
    964      1.1     skrll     }
    965      1.1     skrll 
    966      1.1     skrll   /* Adding the last operand.  */
    967      1.1     skrll   operand[op_num++] = strdup (operandH);
    968      1.1     skrll   crx_ins->nargs = op_num;
    969      1.1     skrll 
    970      1.1     skrll   /* Verifying correct syntax of operands (all brackets should be closed).  */
    971      1.1     skrll   if (bracket_flag || sq_bracket_flag)
    972      1.1     skrll     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
    973      1.1     skrll 
    974      1.1     skrll   /* Now we parse each operand separately.  */
    975      1.1     skrll   for (op_num = 0; op_num < crx_ins->nargs; op_num++)
    976      1.1     skrll     {
    977      1.1     skrll       cur_arg_num = op_num;
    978      1.1     skrll       parse_operand (operand[op_num], crx_ins);
    979      1.1     skrll       free (operand[op_num]);
    980      1.1     skrll     }
    981      1.1     skrll 
    982      1.1     skrll   if (allocated)
    983      1.1     skrll     free (operandS);
    984      1.1     skrll }
    985      1.1     skrll 
    986      1.1     skrll /* Get the trap index in dispatch table, given its name.
    987      1.1     skrll    This routine is used by assembling the 'excp' instruction.  */
    988      1.1     skrll 
    989      1.1     skrll static int
    990  1.1.1.2  christos gettrap (const char *s)
    991      1.1     skrll {
    992      1.1     skrll   const trap_entry *trap;
    993      1.1     skrll 
    994      1.1     skrll   for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
    995      1.1     skrll     if (strcasecmp (trap->name, s) == 0)
    996      1.1     skrll       return trap->entry;
    997      1.1     skrll 
    998      1.1     skrll   as_bad (_("Unknown exception: `%s'"), s);
    999      1.1     skrll   return 0;
   1000      1.1     skrll }
   1001      1.1     skrll 
   1002  1.1.1.4  christos /* Post-Increment instructions, as well as Store-Immediate instructions, are a
   1003  1.1.1.4  christos    sub-group within load/stor instruction groups.
   1004  1.1.1.4  christos    Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
   1005  1.1.1.4  christos    advance the instruction pointer to the start of that sub-group (that is, up
   1006      1.1     skrll    to the first instruction of that type).
   1007      1.1     skrll    Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS.  */
   1008      1.1     skrll 
   1009      1.1     skrll static void
   1010  1.1.1.2  christos handle_LoadStor (const char *operands)
   1011      1.1     skrll {
   1012  1.1.1.4  christos   /* Post-Increment instructions precede Store-Immediate instructions in
   1013  1.1.1.4  christos      CRX instruction table, hence they are handled before.
   1014      1.1     skrll      This synchronization should be kept.  */
   1015      1.1     skrll 
   1016      1.1     skrll   /* Assuming Post-Increment insn has the following format :
   1017      1.1     skrll      'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
   1018      1.1     skrll      LD_STOR_INS_INC are the only store insns containing a plus sign (+).  */
   1019      1.1     skrll   if (strstr (operands, ")+") != NULL)
   1020      1.1     skrll     {
   1021      1.1     skrll       while (! IS_INSN_TYPE (LD_STOR_INS_INC))
   1022      1.1     skrll 	instruction++;
   1023      1.1     skrll       return;
   1024      1.1     skrll     }
   1025      1.1     skrll 
   1026      1.1     skrll   /* Assuming Store-Immediate insn has the following format :
   1027      1.1     skrll      'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
   1028      1.1     skrll      STOR_IMM_INS are the only store insns containing a dollar sign ($).  */
   1029      1.1     skrll   if (strstr (operands, "$") != NULL)
   1030      1.1     skrll     while (! IS_INSN_TYPE (STOR_IMM_INS))
   1031      1.1     skrll       instruction++;
   1032      1.1     skrll }
   1033      1.1     skrll 
   1034      1.1     skrll /* Top level module where instruction parsing starts.
   1035      1.1     skrll    crx_ins - data structure holds some information.
   1036      1.1     skrll    operands - holds the operands part of the whole instruction.  */
   1037      1.1     skrll 
   1038      1.1     skrll static void
   1039      1.1     skrll parse_insn (ins *insn, char *operands)
   1040      1.1     skrll {
   1041      1.1     skrll   int i;
   1042      1.1     skrll 
   1043      1.1     skrll   /* Handle instructions with no operands.  */
   1044      1.1     skrll   for (i = 0; no_op_insn[i] != NULL; i++)
   1045      1.1     skrll   {
   1046      1.1     skrll     if (streq (no_op_insn[i], instruction->mnemonic))
   1047      1.1     skrll     {
   1048      1.1     skrll       insn->nargs = 0;
   1049      1.1     skrll       return;
   1050      1.1     skrll     }
   1051      1.1     skrll   }
   1052      1.1     skrll 
   1053      1.1     skrll   /* Handle 'excp'/'cinv' instructions.  */
   1054      1.1     skrll   if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
   1055      1.1     skrll     {
   1056      1.1     skrll       insn->nargs = 1;
   1057      1.1     skrll       insn->arg[0].type = arg_ic;
   1058      1.1     skrll       insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
   1059      1.1     skrll 	gettrap (operands) : get_cinv_parameters (operands);
   1060      1.1     skrll       insn->arg[0].X_op = O_constant;
   1061      1.1     skrll       return;
   1062      1.1     skrll     }
   1063      1.1     skrll 
   1064      1.1     skrll   /* Handle load/stor unique instructions before parsing.  */
   1065      1.1     skrll   if (IS_INSN_TYPE (LD_STOR_INS))
   1066      1.1     skrll     handle_LoadStor (operands);
   1067      1.1     skrll 
   1068      1.1     skrll   if (operands != NULL)
   1069      1.1     skrll     parse_operands (insn, operands);
   1070      1.1     skrll }
   1071      1.1     skrll 
   1072      1.1     skrll /* Cinv instruction requires special handling.  */
   1073      1.1     skrll 
   1074      1.1     skrll static int
   1075  1.1.1.2  christos get_cinv_parameters (const char *operand)
   1076      1.1     skrll {
   1077  1.1.1.2  christos   const char *p = operand;
   1078      1.1     skrll   int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
   1079      1.1     skrll 
   1080      1.1     skrll   while (*++p != ']')
   1081      1.1     skrll     {
   1082      1.1     skrll       if (*p == ',' || *p == ' ')
   1083      1.1     skrll 	continue;
   1084      1.1     skrll 
   1085      1.1     skrll       if (*p == 'd')
   1086      1.1     skrll 	d_used = 1;
   1087      1.1     skrll       else if (*p == 'i')
   1088      1.1     skrll 	i_used = 1;
   1089      1.1     skrll       else if (*p == 'u')
   1090      1.1     skrll 	u_used = 1;
   1091      1.1     skrll       else if (*p == 'b')
   1092      1.1     skrll 	b_used = 1;
   1093      1.1     skrll       else
   1094      1.1     skrll 	as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
   1095      1.1     skrll     }
   1096      1.1     skrll 
   1097      1.1     skrll   return ((b_used ? 8 : 0)
   1098      1.1     skrll 	+ (d_used ? 4 : 0)
   1099      1.1     skrll 	+ (i_used ? 2 : 0)
   1100      1.1     skrll 	+ (u_used ? 1 : 0));
   1101      1.1     skrll }
   1102      1.1     skrll 
   1103      1.1     skrll /* Retrieve the opcode image of a given register.
   1104      1.1     skrll    If the register is illegal for the current instruction,
   1105      1.1     skrll    issue an error.  */
   1106      1.1     skrll 
   1107      1.1     skrll static int
   1108      1.1     skrll getreg_image (reg r)
   1109      1.1     skrll {
   1110  1.1.1.2  christos   const reg_entry *rreg;
   1111      1.1     skrll   char *reg_name;
   1112      1.1     skrll   int is_procreg = 0; /* Nonzero means argument should be processor reg.  */
   1113      1.1     skrll 
   1114      1.1     skrll   if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
   1115      1.1     skrll       || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
   1116      1.1     skrll     is_procreg = 1;
   1117      1.1     skrll 
   1118      1.1     skrll   /* Check whether the register is in registers table.  */
   1119      1.1     skrll   if (r < MAX_REG)
   1120  1.1.1.2  christos     rreg = &crx_regtab[r];
   1121      1.1     skrll   /* Check whether the register is in coprocessor registers table.  */
   1122  1.1.1.2  christos   else if (r < (int) MAX_COPREG)
   1123  1.1.1.2  christos     rreg = &crx_copregtab[r-MAX_REG];
   1124      1.1     skrll   /* Register not found.  */
   1125      1.1     skrll   else
   1126      1.1     skrll     {
   1127      1.1     skrll       as_bad (_("Unknown register: `%d'"), r);
   1128      1.1     skrll       return 0;
   1129      1.1     skrll     }
   1130      1.1     skrll 
   1131  1.1.1.2  christos   reg_name = rreg->name;
   1132      1.1     skrll 
   1133      1.1     skrll /* Issue a error message when register is illegal.  */
   1134      1.1     skrll #define IMAGE_ERR \
   1135      1.1     skrll   as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
   1136      1.1     skrll 	    reg_name, ins_parse);			     \
   1137      1.1     skrll   break;
   1138      1.1     skrll 
   1139  1.1.1.2  christos   switch (rreg->type)
   1140      1.1     skrll   {
   1141      1.1     skrll     case CRX_U_REGTYPE:
   1142      1.1     skrll       if (is_procreg || (instruction->flags & USER_REG))
   1143  1.1.1.2  christos 	return rreg->image;
   1144      1.1     skrll       else
   1145      1.1     skrll 	IMAGE_ERR;
   1146      1.1     skrll 
   1147      1.1     skrll     case CRX_CFG_REGTYPE:
   1148      1.1     skrll       if (is_procreg)
   1149  1.1.1.2  christos 	return rreg->image;
   1150      1.1     skrll       else
   1151      1.1     skrll 	IMAGE_ERR;
   1152      1.1     skrll 
   1153      1.1     skrll     case CRX_R_REGTYPE:
   1154      1.1     skrll       if (! is_procreg)
   1155  1.1.1.2  christos 	return rreg->image;
   1156      1.1     skrll       else
   1157      1.1     skrll 	IMAGE_ERR;
   1158      1.1     skrll 
   1159      1.1     skrll     case CRX_C_REGTYPE:
   1160      1.1     skrll     case CRX_CS_REGTYPE:
   1161  1.1.1.2  christos       return rreg->image;
   1162      1.1     skrll       break;
   1163      1.1     skrll 
   1164      1.1     skrll     default:
   1165      1.1     skrll       IMAGE_ERR;
   1166      1.1     skrll   }
   1167      1.1     skrll 
   1168      1.1     skrll   return 0;
   1169      1.1     skrll }
   1170      1.1     skrll 
   1171      1.1     skrll /* Routine used to represent integer X using NBITS bits.  */
   1172      1.1     skrll 
   1173      1.1     skrll static long
   1174      1.1     skrll getconstant (long x, int nbits)
   1175      1.1     skrll {
   1176  1.1.1.3  christos   return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
   1177      1.1     skrll }
   1178      1.1     skrll 
   1179      1.1     skrll /* Print a constant value to 'output_opcode':
   1180      1.1     skrll    ARG holds the operand's type and value.
   1181      1.1     skrll    SHIFT represents the location of the operand to be print into.
   1182      1.1     skrll    NBITS determines the size (in bits) of the constant.  */
   1183      1.1     skrll 
   1184      1.1     skrll static void
   1185      1.1     skrll print_constant (int nbits, int shift, argument *arg)
   1186      1.1     skrll {
   1187      1.1     skrll   unsigned long mask = 0;
   1188      1.1     skrll 
   1189      1.1     skrll   long constant = getconstant (arg->constant, nbits);
   1190      1.1     skrll 
   1191      1.1     skrll   switch (nbits)
   1192      1.1     skrll   {
   1193      1.1     skrll     case 32:
   1194      1.1     skrll     case 28:
   1195      1.1     skrll     case 24:
   1196      1.1     skrll     case 22:
   1197      1.1     skrll       /* mask the upper part of the constant, that is, the bits
   1198      1.1     skrll 	 going to the lowest byte of output_opcode[0].
   1199      1.1     skrll 	 The upper part of output_opcode[1] is always filled,
   1200      1.1     skrll 	 therefore it is always masked with 0xFFFF.  */
   1201      1.1     skrll       mask = (1 << (nbits - 16)) - 1;
   1202      1.1     skrll       /* Divide the constant between two consecutive words :
   1203      1.1     skrll 		 0	   1	     2	       3
   1204      1.1     skrll 	    +---------+---------+---------+---------+
   1205      1.1     skrll 	    |	      | X X X X | X X X X |	    |
   1206      1.1     skrll 	    +---------+---------+---------+---------+
   1207      1.1     skrll 	      output_opcode[0]    output_opcode[1]     */
   1208      1.1     skrll 
   1209      1.1     skrll       CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
   1210      1.1     skrll       CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
   1211      1.1     skrll       break;
   1212      1.1     skrll 
   1213      1.1     skrll     case 16:
   1214      1.1     skrll     case 12:
   1215      1.1     skrll       /* Special case - in arg_cr, the SHIFT represents the location
   1216      1.1     skrll 	 of the REGISTER, not the constant, which is itself not shifted.  */
   1217      1.1     skrll       if (arg->type == arg_cr)
   1218      1.1     skrll 	{
   1219      1.1     skrll 	  CRX_PRINT (0, constant,  0);
   1220      1.1     skrll 	  break;
   1221      1.1     skrll 	}
   1222      1.1     skrll 
   1223  1.1.1.4  christos       /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
   1224  1.1.1.4  christos 	 always filling the upper part of output_opcode[1]. If we mistakenly
   1225      1.1     skrll 	 write it to output_opcode[0], the constant prefix (that is, 'match')
   1226      1.1     skrll 	 will be overridden.
   1227      1.1     skrll 		 0	   1	     2	       3
   1228      1.1     skrll 	    +---------+---------+---------+---------+
   1229      1.1     skrll 	    | 'match' |         | X X X X |	    |
   1230      1.1     skrll 	    +---------+---------+---------+---------+
   1231      1.1     skrll 	      output_opcode[0]    output_opcode[1]     */
   1232      1.1     skrll 
   1233      1.1     skrll       if ((instruction->size > 2) && (shift == WORD_SHIFT))
   1234      1.1     skrll 	CRX_PRINT (1, constant, WORD_SHIFT);
   1235      1.1     skrll       else
   1236      1.1     skrll 	CRX_PRINT (0, constant, shift);
   1237      1.1     skrll       break;
   1238      1.1     skrll 
   1239      1.1     skrll     default:
   1240      1.1     skrll       CRX_PRINT (0, constant,  shift);
   1241      1.1     skrll       break;
   1242      1.1     skrll   }
   1243      1.1     skrll }
   1244      1.1     skrll 
   1245      1.1     skrll /* Print an operand to 'output_opcode', which later on will be
   1246      1.1     skrll    printed to the object file:
   1247      1.1     skrll    ARG holds the operand's type, size and value.
   1248      1.1     skrll    SHIFT represents the printing location of operand.
   1249      1.1     skrll    NBITS determines the size (in bits) of a constant operand.  */
   1250      1.1     skrll 
   1251      1.1     skrll static void
   1252      1.1     skrll print_operand (int nbits, int shift, argument *arg)
   1253      1.1     skrll {
   1254      1.1     skrll   switch (arg->type)
   1255      1.1     skrll     {
   1256      1.1     skrll     case arg_r:
   1257      1.1     skrll       CRX_PRINT (0, getreg_image (arg->r), shift);
   1258      1.1     skrll       break;
   1259      1.1     skrll 
   1260      1.1     skrll     case arg_copr:
   1261      1.1     skrll       if (arg->cr < c0 || arg->cr > c15)
   1262      1.1     skrll 	as_bad (_("Illegal Co-processor register in Instruction `%s' "),
   1263      1.1     skrll 		ins_parse);
   1264      1.1     skrll       CRX_PRINT (0, getreg_image (arg->cr), shift);
   1265      1.1     skrll       break;
   1266      1.1     skrll 
   1267      1.1     skrll     case arg_copsr:
   1268      1.1     skrll       if (arg->cr < cs0 || arg->cr > cs15)
   1269      1.1     skrll 	as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
   1270      1.1     skrll 		ins_parse);
   1271      1.1     skrll       CRX_PRINT (0, getreg_image (arg->cr), shift);
   1272      1.1     skrll       break;
   1273      1.1     skrll 
   1274      1.1     skrll     case arg_idxr:
   1275      1.1     skrll       /*    16      12	      8    6         0
   1276      1.1     skrll 	    +--------------------------------+
   1277      1.1     skrll 	    | r_base | r_idx  | scl|  disp   |
   1278      1.1     skrll 	    +--------------------------------+	  */
   1279      1.1     skrll       CRX_PRINT (0, getreg_image (arg->r), 12);
   1280      1.1     skrll       CRX_PRINT (0, getreg_image (arg->i_r), 8);
   1281      1.1     skrll       CRX_PRINT (0, arg->scale, 6);
   1282      1.1     skrll     case arg_ic:
   1283      1.1     skrll     case arg_c:
   1284      1.1     skrll       print_constant (nbits, shift, arg);
   1285      1.1     skrll       break;
   1286      1.1     skrll 
   1287      1.1     skrll     case arg_rbase:
   1288      1.1     skrll       CRX_PRINT (0, getreg_image (arg->r), shift);
   1289      1.1     skrll       break;
   1290      1.1     skrll 
   1291      1.1     skrll     case arg_cr:
   1292      1.1     skrll       /* case base_cst4.  */
   1293      1.1     skrll       if (instruction->flags & DISPU4MAP)
   1294      1.1     skrll 	print_constant (nbits, shift + REG_SIZE, arg);
   1295      1.1     skrll       else
   1296      1.1     skrll 	/* rbase_disps<NN> and other such cases.  */
   1297      1.1     skrll 	print_constant (nbits, shift, arg);
   1298      1.1     skrll       /* Add the register argument to the output_opcode.  */
   1299      1.1     skrll       CRX_PRINT (0, getreg_image (arg->r), shift);
   1300      1.1     skrll       break;
   1301      1.1     skrll 
   1302      1.1     skrll     default:
   1303      1.1     skrll       break;
   1304      1.1     skrll     }
   1305      1.1     skrll }
   1306      1.1     skrll 
   1307      1.1     skrll /* Retrieve the number of operands for the current assembled instruction.  */
   1308      1.1     skrll 
   1309      1.1     skrll static int
   1310      1.1     skrll get_number_of_operands (void)
   1311      1.1     skrll {
   1312      1.1     skrll   int i;
   1313      1.1     skrll 
   1314      1.1     skrll   for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
   1315      1.1     skrll     ;
   1316      1.1     skrll   return i;
   1317      1.1     skrll }
   1318      1.1     skrll 
   1319  1.1.1.4  christos /* Verify that the number NUM can be represented in BITS bits (that is,
   1320  1.1.1.4  christos    within its permitted range), based on the instruction's FLAGS.
   1321      1.1     skrll    If UPDATE is nonzero, update the value of NUM if necessary.
   1322      1.1     skrll    Return OP_LEGAL upon success, actual error type upon failure.  */
   1323      1.1     skrll 
   1324      1.1     skrll static op_err
   1325      1.1     skrll check_range (long *num, int bits, int unsigned flags, int update)
   1326      1.1     skrll {
   1327  1.1.1.3  christos   uint32_t max;
   1328  1.1.1.5  christos   op_err retval = OP_LEGAL;
   1329      1.1     skrll   int bin;
   1330  1.1.1.3  christos   uint32_t upper_64kb = 0xffff0000;
   1331  1.1.1.3  christos   uint32_t value = *num;
   1332      1.1     skrll 
   1333      1.1     skrll   /* Verify operand value is even.  */
   1334      1.1     skrll   if (flags & OP_EVEN)
   1335      1.1     skrll     {
   1336      1.1     skrll       if (value % 2)
   1337      1.1     skrll 	return OP_NOT_EVEN;
   1338      1.1     skrll     }
   1339      1.1     skrll 
   1340      1.1     skrll   if (flags & OP_UPPER_64KB)
   1341      1.1     skrll     {
   1342      1.1     skrll       /* Check if value is to be mapped to upper 64 KB memory area.  */
   1343      1.1     skrll       if ((value & upper_64kb) == upper_64kb)
   1344      1.1     skrll 	{
   1345      1.1     skrll 	  value -= upper_64kb;
   1346      1.1     skrll 	  if (update)
   1347      1.1     skrll 	    *num = value;
   1348      1.1     skrll 	}
   1349      1.1     skrll       else
   1350      1.1     skrll 	return OP_NOT_UPPER_64KB;
   1351      1.1     skrll     }
   1352      1.1     skrll 
   1353      1.1     skrll   if (flags & OP_SHIFT)
   1354      1.1     skrll     {
   1355  1.1.1.3  christos       /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
   1356  1.1.1.3  christos 	 sign.  However, right shift of a signed type with a negative
   1357  1.1.1.3  christos 	 value is implementation defined.  See ISO C 6.5.7.  So we use
   1358  1.1.1.3  christos 	 an unsigned type and sign extend afterwards.  */
   1359      1.1     skrll       value >>= 1;
   1360  1.1.1.3  christos       value = (value ^ 0x40000000) - 0x40000000;
   1361      1.1     skrll       if (update)
   1362      1.1     skrll 	*num = value;
   1363      1.1     skrll     }
   1364      1.1     skrll   else if (flags & OP_SHIFT_DEC)
   1365      1.1     skrll     {
   1366      1.1     skrll       value = (value >> 1) - 1;
   1367      1.1     skrll       if (update)
   1368      1.1     skrll 	*num = value;
   1369      1.1     skrll     }
   1370      1.1     skrll 
   1371      1.1     skrll   if (flags & OP_ESC)
   1372      1.1     skrll     {
   1373      1.1     skrll       /* 0x7e and 0x7f are reserved escape sequences of dispe9.  */
   1374      1.1     skrll       if (value == 0x7e || value == 0x7f)
   1375      1.1     skrll 	return OP_OUT_OF_RANGE;
   1376      1.1     skrll     }
   1377      1.1     skrll 
   1378      1.1     skrll   if (flags & OP_DISPU4)
   1379      1.1     skrll     {
   1380      1.1     skrll       int is_dispu4 = 0;
   1381      1.1     skrll 
   1382  1.1.1.4  christos       uint32_t mul = (instruction->flags & DISPUB4 ? 1
   1383  1.1.1.3  christos 		      : instruction->flags & DISPUW4 ? 2
   1384  1.1.1.3  christos 		      : instruction->flags & DISPUD4 ? 4
   1385  1.1.1.3  christos 		      : 0);
   1386  1.1.1.4  christos 
   1387      1.1     skrll       for (bin = 0; bin < cst4_maps; bin++)
   1388      1.1     skrll 	{
   1389  1.1.1.3  christos 	  if (value == mul * bin)
   1390      1.1     skrll 	    {
   1391      1.1     skrll 	      is_dispu4 = 1;
   1392      1.1     skrll 	      if (update)
   1393      1.1     skrll 		*num = bin;
   1394      1.1     skrll 	      break;
   1395      1.1     skrll 	    }
   1396      1.1     skrll 	}
   1397      1.1     skrll       if (!is_dispu4)
   1398      1.1     skrll 	retval = OP_ILLEGAL_DISPU4;
   1399      1.1     skrll     }
   1400      1.1     skrll   else if (flags & OP_CST4)
   1401      1.1     skrll     {
   1402      1.1     skrll       int is_cst4 = 0;
   1403      1.1     skrll 
   1404      1.1     skrll       for (bin = 0; bin < cst4_maps; bin++)
   1405      1.1     skrll 	{
   1406  1.1.1.3  christos 	  if (value == (uint32_t) cst4_map[bin])
   1407      1.1     skrll 	    {
   1408      1.1     skrll 	      is_cst4 = 1;
   1409      1.1     skrll 	      if (update)
   1410      1.1     skrll 		*num = bin;
   1411      1.1     skrll 	      break;
   1412      1.1     skrll 	    }
   1413      1.1     skrll 	}
   1414      1.1     skrll       if (!is_cst4)
   1415      1.1     skrll 	retval = OP_ILLEGAL_CST4;
   1416      1.1     skrll     }
   1417      1.1     skrll   else if (flags & OP_SIGNED)
   1418      1.1     skrll     {
   1419  1.1.1.3  christos       max = 1;
   1420  1.1.1.3  christos       max = max << (bits - 1);
   1421  1.1.1.3  christos       value += max;
   1422  1.1.1.3  christos       max = ((max - 1) << 1) | 1;
   1423  1.1.1.3  christos       if (value > max)
   1424      1.1     skrll 	retval = OP_OUT_OF_RANGE;
   1425      1.1     skrll     }
   1426      1.1     skrll   else if (flags & OP_UNSIGNED)
   1427      1.1     skrll     {
   1428  1.1.1.3  christos       max = 1;
   1429  1.1.1.3  christos       max = max << (bits - 1);
   1430  1.1.1.3  christos       max = ((max - 1) << 1) | 1;
   1431  1.1.1.3  christos       if (value > max)
   1432      1.1     skrll 	retval = OP_OUT_OF_RANGE;
   1433      1.1     skrll     }
   1434      1.1     skrll   return retval;
   1435      1.1     skrll }
   1436      1.1     skrll 
   1437      1.1     skrll /* Assemble a single instruction:
   1438      1.1     skrll    INSN is already parsed (that is, all operand values and types are set).
   1439  1.1.1.4  christos    For instruction to be assembled, we need to find an appropriate template in
   1440      1.1     skrll    the instruction table, meeting the following conditions:
   1441      1.1     skrll     1: Has the same number of operands.
   1442      1.1     skrll     2: Has the same operand types.
   1443      1.1     skrll     3: Each operand size is sufficient to represent the instruction's values.
   1444      1.1     skrll    Returns 1 upon success, 0 upon failure.  */
   1445      1.1     skrll 
   1446      1.1     skrll static int
   1447      1.1     skrll assemble_insn (char *mnemonic, ins *insn)
   1448      1.1     skrll {
   1449      1.1     skrll   /* Type of each operand in the current template.  */
   1450      1.1     skrll   argtype cur_type[MAX_OPERANDS];
   1451      1.1     skrll   /* Size (in bits) of each operand in the current template.  */
   1452      1.1     skrll   unsigned int cur_size[MAX_OPERANDS];
   1453      1.1     skrll   /* Flags of each operand in the current template.  */
   1454      1.1     skrll   unsigned int cur_flags[MAX_OPERANDS];
   1455      1.1     skrll   /* Instruction type to match.  */
   1456      1.1     skrll   unsigned int ins_type;
   1457      1.1     skrll   /* Boolean flag to mark whether a match was found.  */
   1458      1.1     skrll   int match = 0;
   1459      1.1     skrll   int i;
   1460      1.1     skrll   /* Nonzero if an instruction with same number of operands was found.  */
   1461      1.1     skrll   int found_same_number_of_operands = 0;
   1462      1.1     skrll   /* Nonzero if an instruction with same argument types was found.  */
   1463      1.1     skrll   int found_same_argument_types = 0;
   1464      1.1     skrll   /* Nonzero if a constant was found within the required range.  */
   1465      1.1     skrll   int found_const_within_range  = 0;
   1466      1.1     skrll   /* Argument number of an operand with invalid type.  */
   1467      1.1     skrll   int invalid_optype = -1;
   1468      1.1     skrll   /* Argument number of an operand with invalid constant value.  */
   1469      1.1     skrll   int invalid_const  = -1;
   1470      1.1     skrll   /* Operand error (used for issuing various constant error messages).  */
   1471      1.1     skrll   op_err op_error, const_err = OP_LEGAL;
   1472      1.1     skrll 
   1473      1.1     skrll /* Retrieve data (based on FUNC) for each operand of a given instruction.  */
   1474      1.1     skrll #define GET_CURRENT_DATA(FUNC, ARRAY)				  \
   1475      1.1     skrll   for (i = 0; i < insn->nargs; i++)				  \
   1476      1.1     skrll     ARRAY[i] = FUNC (instruction->operands[i].op_type)
   1477      1.1     skrll 
   1478      1.1     skrll #define GET_CURRENT_TYPE    GET_CURRENT_DATA(get_optype, cur_type)
   1479      1.1     skrll #define GET_CURRENT_SIZE    GET_CURRENT_DATA(get_opbits, cur_size)
   1480      1.1     skrll #define GET_CURRENT_FLAGS   GET_CURRENT_DATA(get_opflags, cur_flags)
   1481      1.1     skrll 
   1482      1.1     skrll   /* Instruction has no operands -> only copy the constant opcode.   */
   1483      1.1     skrll   if (insn->nargs == 0)
   1484      1.1     skrll     {
   1485      1.1     skrll       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
   1486      1.1     skrll       return 1;
   1487      1.1     skrll     }
   1488      1.1     skrll 
   1489      1.1     skrll   /* In some case, same mnemonic can appear with different instruction types.
   1490      1.1     skrll      For example, 'storb' is supported with 3 different types :
   1491      1.1     skrll      LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
   1492  1.1.1.4  christos      We assume that when reaching this point, the instruction type was
   1493      1.1     skrll      pre-determined. We need to make sure that the type stays the same
   1494      1.1     skrll      during a search for matching instruction.  */
   1495      1.1     skrll   ins_type = CRX_INS_TYPE(instruction->flags);
   1496      1.1     skrll 
   1497      1.1     skrll   while (/* Check that match is still not found.  */
   1498      1.1     skrll 	 match != 1
   1499      1.1     skrll 	 /* Check we didn't get to end of table.  */
   1500      1.1     skrll 	 && instruction->mnemonic != NULL
   1501      1.1     skrll 	 /* Check that the actual mnemonic is still available.  */
   1502      1.1     skrll 	 && IS_INSN_MNEMONIC (mnemonic)
   1503      1.1     skrll 	 /* Check that the instruction type wasn't changed.  */
   1504      1.1     skrll 	 && IS_INSN_TYPE(ins_type))
   1505      1.1     skrll     {
   1506      1.1     skrll       /* Check whether number of arguments is legal.  */
   1507      1.1     skrll       if (get_number_of_operands () != insn->nargs)
   1508      1.1     skrll 	goto next_insn;
   1509      1.1     skrll       found_same_number_of_operands = 1;
   1510      1.1     skrll 
   1511      1.1     skrll       /* Initialize arrays with data of each operand in current template.  */
   1512      1.1     skrll       GET_CURRENT_TYPE;
   1513      1.1     skrll       GET_CURRENT_SIZE;
   1514      1.1     skrll       GET_CURRENT_FLAGS;
   1515      1.1     skrll 
   1516      1.1     skrll       /* Check for type compatibility.  */
   1517      1.1     skrll       for (i = 0; i < insn->nargs; i++)
   1518      1.1     skrll         {
   1519      1.1     skrll 	  if (cur_type[i] != insn->arg[i].type)
   1520      1.1     skrll 	    {
   1521      1.1     skrll 	      if (invalid_optype == -1)
   1522      1.1     skrll 		invalid_optype = i + 1;
   1523      1.1     skrll 	      goto next_insn;
   1524      1.1     skrll 	    }
   1525      1.1     skrll 	}
   1526      1.1     skrll       found_same_argument_types = 1;
   1527      1.1     skrll 
   1528      1.1     skrll       for (i = 0; i < insn->nargs; i++)
   1529      1.1     skrll 	{
   1530      1.1     skrll 	  /* Reverse the operand indices for certain opcodes:
   1531      1.1     skrll 	     Index 0	  -->> 1
   1532  1.1.1.4  christos 	     Index 1	  -->> 0
   1533      1.1     skrll 	     Other index  -->> stays the same.  */
   1534  1.1.1.4  christos 	  int j = instruction->flags & REVERSE_MATCH ?
   1535  1.1.1.4  christos 		  i == 0 ? 1 :
   1536  1.1.1.4  christos 		  i == 1 ? 0 : i :
   1537      1.1     skrll 		  i;
   1538      1.1     skrll 
   1539  1.1.1.4  christos 	  /* Only check range - don't update the constant's value, since the
   1540  1.1.1.4  christos 	     current instruction may not be the last we try to match.
   1541  1.1.1.4  christos 	     The constant's value will be updated later, right before printing
   1542      1.1     skrll 	     it to the object file.  */
   1543  1.1.1.4  christos   	  if ((insn->arg[j].X_op == O_constant)
   1544  1.1.1.4  christos 	       && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
   1545      1.1     skrll 					   cur_flags[j], 0)))
   1546      1.1     skrll   	    {
   1547      1.1     skrll 	      if (invalid_const == -1)
   1548      1.1     skrll 	      {
   1549      1.1     skrll 		invalid_const = j + 1;
   1550      1.1     skrll 		const_err = op_error;
   1551      1.1     skrll 	      }
   1552      1.1     skrll 	      goto next_insn;
   1553      1.1     skrll 	    }
   1554  1.1.1.4  christos 	  /* For symbols, we make sure the relocation size (which was already
   1555      1.1     skrll 	     determined) is sufficient.  */
   1556      1.1     skrll 	  else if ((insn->arg[j].X_op == O_symbol)
   1557  1.1.1.4  christos 		    && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
   1558      1.1     skrll 			 > cur_size[j]))
   1559      1.1     skrll 		  goto next_insn;
   1560      1.1     skrll 	}
   1561      1.1     skrll       found_const_within_range = 1;
   1562      1.1     skrll 
   1563      1.1     skrll       /* If we got till here -> Full match is found.  */
   1564      1.1     skrll       match = 1;
   1565      1.1     skrll       break;
   1566      1.1     skrll 
   1567      1.1     skrll /* Try again with next instruction.  */
   1568      1.1     skrll next_insn:
   1569      1.1     skrll       instruction++;
   1570      1.1     skrll     }
   1571      1.1     skrll 
   1572      1.1     skrll   if (!match)
   1573      1.1     skrll     {
   1574      1.1     skrll       /* We haven't found a match - instruction can't be assembled.  */
   1575      1.1     skrll       if (!found_same_number_of_operands)
   1576      1.1     skrll 	as_bad (_("Incorrect number of operands"));
   1577      1.1     skrll       else if (!found_same_argument_types)
   1578      1.1     skrll 	as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
   1579      1.1     skrll       else if (!found_const_within_range)
   1580      1.1     skrll       {
   1581      1.1     skrll 	switch (const_err)
   1582      1.1     skrll 	{
   1583      1.1     skrll 	case OP_OUT_OF_RANGE:
   1584      1.1     skrll 	  as_bad (_("Operand out of range (arg %d)"), invalid_const);
   1585      1.1     skrll 	  break;
   1586      1.1     skrll 	case OP_NOT_EVEN:
   1587      1.1     skrll 	  as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
   1588      1.1     skrll 	  break;
   1589      1.1     skrll 	case OP_ILLEGAL_DISPU4:
   1590      1.1     skrll 	  as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
   1591      1.1     skrll 	  break;
   1592      1.1     skrll 	case OP_ILLEGAL_CST4:
   1593      1.1     skrll 	  as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
   1594      1.1     skrll 	  break;
   1595      1.1     skrll 	case OP_NOT_UPPER_64KB:
   1596  1.1.1.4  christos 	  as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
   1597      1.1     skrll 		    invalid_const);
   1598      1.1     skrll 	  break;
   1599      1.1     skrll 	default:
   1600      1.1     skrll 	  as_bad (_("Illegal operand (arg %d)"), invalid_const);
   1601      1.1     skrll 	  break;
   1602      1.1     skrll 	}
   1603      1.1     skrll       }
   1604  1.1.1.4  christos 
   1605      1.1     skrll       return 0;
   1606      1.1     skrll     }
   1607      1.1     skrll   else
   1608      1.1     skrll     /* Full match - print the encoding to output file.  */
   1609      1.1     skrll     {
   1610      1.1     skrll       /* Make further checkings (such that couldn't be made earlier).
   1611      1.1     skrll 	 Warn the user if necessary.  */
   1612      1.1     skrll       warn_if_needed (insn);
   1613  1.1.1.4  christos 
   1614      1.1     skrll       /* Check whether we need to adjust the instruction pointer.  */
   1615      1.1     skrll       if (adjust_if_needed (insn))
   1616  1.1.1.4  christos 	/* If instruction pointer was adjusted, we need to update
   1617      1.1     skrll 	   the size of the current template operands.  */
   1618      1.1     skrll 	GET_CURRENT_SIZE;
   1619      1.1     skrll 
   1620      1.1     skrll       for (i = 0; i < insn->nargs; i++)
   1621      1.1     skrll         {
   1622  1.1.1.4  christos 	  int j = instruction->flags & REVERSE_MATCH ?
   1623  1.1.1.4  christos 		  i == 0 ? 1 :
   1624  1.1.1.4  christos 		  i == 1 ? 0 : i :
   1625      1.1     skrll 		  i;
   1626      1.1     skrll 
   1627      1.1     skrll 	  /* This time, update constant value before printing it.  */
   1628  1.1.1.4  christos   	  if ((insn->arg[j].X_op == O_constant)
   1629  1.1.1.4  christos 	       && (check_range (&insn->arg[j].constant, cur_size[j],
   1630      1.1     skrll 				cur_flags[j], 1) != OP_LEGAL))
   1631      1.1     skrll 	      as_fatal (_("Illegal operand (arg %d)"), j+1);
   1632      1.1     skrll 	}
   1633      1.1     skrll 
   1634      1.1     skrll       /* First, copy the instruction's opcode.  */
   1635      1.1     skrll       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
   1636      1.1     skrll 
   1637      1.1     skrll       for (i = 0; i < insn->nargs; i++)
   1638      1.1     skrll         {
   1639      1.1     skrll 	  cur_arg_num = i;
   1640  1.1.1.4  christos           print_operand (cur_size[i], instruction->operands[i].shift,
   1641      1.1     skrll 			 &insn->arg[i]);
   1642      1.1     skrll         }
   1643      1.1     skrll     }
   1644      1.1     skrll 
   1645      1.1     skrll   return 1;
   1646      1.1     skrll }
   1647      1.1     skrll 
   1648      1.1     skrll /* Bunch of error checkings.
   1649      1.1     skrll    The checks are made after a matching instruction was found.  */
   1650      1.1     skrll 
   1651      1.1     skrll void
   1652      1.1     skrll warn_if_needed (ins *insn)
   1653      1.1     skrll {
   1654  1.1.1.4  christos   /* If the post-increment address mode is used and the load/store
   1655  1.1.1.4  christos      source register is the same as rbase, the result of the
   1656      1.1     skrll      instruction is undefined.  */
   1657      1.1     skrll   if (IS_INSN_TYPE (LD_STOR_INS_INC))
   1658      1.1     skrll     {
   1659      1.1     skrll       /* Enough to verify that one of the arguments is a simple reg.  */
   1660      1.1     skrll       if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
   1661      1.1     skrll 	if (insn->arg[0].r == insn->arg[1].r)
   1662  1.1.1.4  christos 	  as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
   1663      1.1     skrll 		   insn->arg[0].r);
   1664      1.1     skrll     }
   1665      1.1     skrll 
   1666      1.1     skrll   /* Some instruction assume the stack pointer as rptr operand.
   1667      1.1     skrll      Issue an error when the register to be loaded is also SP.  */
   1668      1.1     skrll   if (instruction->flags & NO_SP)
   1669      1.1     skrll     {
   1670      1.1     skrll       if (getreg_image (insn->arg[0].r) == getreg_image (sp))
   1671      1.1     skrll 	as_bad (_("`%s' has undefined result"), ins_parse);
   1672      1.1     skrll     }
   1673      1.1     skrll 
   1674  1.1.1.4  christos   /* If the rptr register is specified as one of the registers to be loaded,
   1675      1.1     skrll      the final contents of rptr are undefined. Thus, we issue an error.  */
   1676      1.1     skrll   if (instruction->flags & NO_RPTR)
   1677      1.1     skrll     {
   1678      1.1     skrll       if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
   1679  1.1.1.4  christos 	as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
   1680      1.1     skrll 	 getreg_image (insn->arg[0].r));
   1681      1.1     skrll     }
   1682      1.1     skrll }
   1683      1.1     skrll 
   1684  1.1.1.4  christos /* In some cases, we need to adjust the instruction pointer although a
   1685      1.1     skrll    match was already found. Here, we gather all these cases.
   1686      1.1     skrll    Returns 1 if instruction pointer was adjusted, otherwise 0.  */
   1687      1.1     skrll 
   1688      1.1     skrll int
   1689      1.1     skrll adjust_if_needed (ins *insn)
   1690      1.1     skrll {
   1691      1.1     skrll   int ret_value = 0;
   1692      1.1     skrll 
   1693      1.1     skrll   /* Special check for 'addub $0, r0' instruction -
   1694      1.1     skrll      The opcode '0000 0000 0000 0000' is not allowed.  */
   1695      1.1     skrll   if (IS_INSN_MNEMONIC ("addub"))
   1696      1.1     skrll     {
   1697      1.1     skrll       if ((instruction->operands[0].op_type == cst4)
   1698      1.1     skrll 	  && instruction->operands[1].op_type == regr)
   1699      1.1     skrll         {
   1700      1.1     skrll           if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
   1701      1.1     skrll 	    {
   1702      1.1     skrll 	      instruction++;
   1703      1.1     skrll 	      ret_value = 1;
   1704      1.1     skrll 	    }
   1705      1.1     skrll         }
   1706      1.1     skrll     }
   1707      1.1     skrll 
   1708  1.1.1.4  christos   /* Optimization: Omit a zero displacement in bit operations,
   1709      1.1     skrll      saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)').  */
   1710      1.1     skrll   if (IS_INSN_TYPE (CSTBIT_INS))
   1711      1.1     skrll     {
   1712      1.1     skrll       if ((instruction->operands[1].op_type == rbase_disps12)
   1713      1.1     skrll 	   && (insn->arg[1].X_op == O_constant)
   1714      1.1     skrll 	   && (insn->arg[1].constant == 0))
   1715      1.1     skrll             {
   1716      1.1     skrll               instruction--;
   1717      1.1     skrll 	      ret_value = 1;
   1718      1.1     skrll             }
   1719      1.1     skrll     }
   1720      1.1     skrll 
   1721      1.1     skrll   return ret_value;
   1722      1.1     skrll }
   1723      1.1     skrll 
   1724      1.1     skrll /* Set the appropriate bit for register 'r' in 'mask'.
   1725      1.1     skrll    This indicates that this register is loaded or stored by
   1726      1.1     skrll    the instruction.  */
   1727      1.1     skrll 
   1728      1.1     skrll static void
   1729      1.1     skrll mask_reg (int r, unsigned short int *mask)
   1730      1.1     skrll {
   1731      1.1     skrll   if ((reg)r > (reg)sp)
   1732      1.1     skrll     {
   1733      1.1     skrll       as_bad (_("Invalid Register in Register List"));
   1734      1.1     skrll       return;
   1735      1.1     skrll     }
   1736      1.1     skrll 
   1737      1.1     skrll   *mask |= (1 << r);
   1738      1.1     skrll }
   1739      1.1     skrll 
   1740      1.1     skrll /* Preprocess register list - create a 16-bit mask with one bit for each
   1741      1.1     skrll    of the 16 general purpose registers. If a bit is set, it indicates
   1742      1.1     skrll    that this register is loaded or stored by the instruction.  */
   1743      1.1     skrll 
   1744      1.1     skrll static char *
   1745      1.1     skrll preprocess_reglist (char *param, int *allocated)
   1746      1.1     skrll {
   1747      1.1     skrll   char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name.  */
   1748      1.1     skrll   char *regP;			  /* Pointer to 'reg_name' string.  */
   1749      1.1     skrll   int reg_counter = 0;		  /* Count number of parsed registers.  */
   1750      1.1     skrll   unsigned short int mask = 0;	  /* Mask for 16 general purpose registers.  */
   1751      1.1     skrll   char *new_param;		  /* New created operands string.  */
   1752      1.1     skrll   char *paramP = param;		  /* Pointer to original opearands string.  */
   1753      1.1     skrll   char maskstring[10];		  /* Array to print the mask as a string.  */
   1754      1.1     skrll   int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers.  */
   1755      1.1     skrll   reg r;
   1756      1.1     skrll   copreg cr;
   1757      1.1     skrll 
   1758      1.1     skrll   /* If 'param' is already in form of a number, no need to preprocess.  */
   1759      1.1     skrll   if (strchr (paramP, '{') == NULL)
   1760      1.1     skrll     return param;
   1761      1.1     skrll 
   1762      1.1     skrll   /* Verifying correct syntax of operand.  */
   1763      1.1     skrll   if (strchr (paramP, '}') == NULL)
   1764      1.1     skrll     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
   1765      1.1     skrll 
   1766      1.1     skrll   while (*paramP++ != '{');
   1767      1.1     skrll 
   1768  1.1.1.5  christos   new_param = XCNEWVEC (char, MAX_INST_LEN);
   1769      1.1     skrll   *allocated = 1;
   1770      1.1     skrll   strncpy (new_param, param, paramP - param - 1);
   1771      1.1     skrll 
   1772      1.1     skrll   while (*paramP != '}')
   1773      1.1     skrll     {
   1774      1.1     skrll       regP = paramP;
   1775      1.1     skrll       memset (&reg_name, '\0', sizeof (reg_name));
   1776      1.1     skrll 
   1777      1.1     skrll       while (ISALNUM (*paramP))
   1778      1.1     skrll 	paramP++;
   1779      1.1     skrll 
   1780      1.1     skrll       strncpy (reg_name, regP, paramP - regP);
   1781      1.1     skrll 
   1782      1.1     skrll       /* Coprocessor register c<N>.  */
   1783      1.1     skrll       if (IS_INSN_TYPE (COP_REG_INS))
   1784      1.1     skrll         {
   1785      1.1     skrll           if (((cr = get_copregister (reg_name)) == nullcopregister)
   1786      1.1     skrll 	      || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
   1787      1.1     skrll 	    as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
   1788      1.1     skrll 	  mask_reg (getreg_image (cr - c0), &mask);
   1789      1.1     skrll         }
   1790      1.1     skrll       /* Coprocessor Special register cs<N>.  */
   1791      1.1     skrll       else if (IS_INSN_TYPE (COPS_REG_INS))
   1792      1.1     skrll         {
   1793      1.1     skrll           if (((cr = get_copregister (reg_name)) == nullcopregister)
   1794      1.1     skrll 	      || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
   1795  1.1.1.4  christos 	    as_fatal (_("Illegal register `%s' in cop-special-register list"),
   1796      1.1     skrll 		      reg_name);
   1797      1.1     skrll 	  mask_reg (getreg_image (cr - cs0), &mask);
   1798      1.1     skrll         }
   1799      1.1     skrll       /* User register u<N>.  */
   1800      1.1     skrll       else if (instruction->flags & USER_REG)
   1801      1.1     skrll 	{
   1802      1.1     skrll 	  if (streq(reg_name, "uhi"))
   1803      1.1     skrll 	    {
   1804      1.1     skrll 	      hi_found = 1;
   1805      1.1     skrll 	      goto next_inst;
   1806      1.1     skrll 	    }
   1807      1.1     skrll 	  else if (streq(reg_name, "ulo"))
   1808      1.1     skrll 	    {
   1809      1.1     skrll 	      lo_found = 1;
   1810      1.1     skrll 	      goto next_inst;
   1811      1.1     skrll 	    }
   1812      1.1     skrll           else if (((r = get_register (reg_name)) == nullregister)
   1813      1.1     skrll 	      || (crx_regtab[r].type != CRX_U_REGTYPE))
   1814      1.1     skrll 	    as_fatal (_("Illegal register `%s' in user register list"), reg_name);
   1815  1.1.1.4  christos 
   1816  1.1.1.4  christos 	  mask_reg (getreg_image (r - u0), &mask);
   1817      1.1     skrll 	}
   1818      1.1     skrll       /* General purpose register r<N>.  */
   1819      1.1     skrll       else
   1820      1.1     skrll         {
   1821      1.1     skrll 	  if (streq(reg_name, "hi"))
   1822      1.1     skrll 	    {
   1823      1.1     skrll 	      hi_found = 1;
   1824      1.1     skrll 	      goto next_inst;
   1825      1.1     skrll 	    }
   1826      1.1     skrll 	  else if (streq(reg_name, "lo"))
   1827      1.1     skrll 	    {
   1828      1.1     skrll 	      lo_found = 1;
   1829      1.1     skrll 	      goto next_inst;
   1830      1.1     skrll 	    }
   1831      1.1     skrll           else if (((r = get_register (reg_name)) == nullregister)
   1832      1.1     skrll 	      || (crx_regtab[r].type != CRX_R_REGTYPE))
   1833      1.1     skrll 	    as_fatal (_("Illegal register `%s' in register list"), reg_name);
   1834      1.1     skrll 
   1835      1.1     skrll 	  mask_reg (getreg_image (r - r0), &mask);
   1836      1.1     skrll         }
   1837      1.1     skrll 
   1838      1.1     skrll       if (++reg_counter > MAX_REGS_IN_MASK16)
   1839      1.1     skrll 	as_bad (_("Maximum %d bits may be set in `mask16' operand"),
   1840      1.1     skrll 		MAX_REGS_IN_MASK16);
   1841      1.1     skrll 
   1842      1.1     skrll next_inst:
   1843      1.1     skrll       while (!ISALNUM (*paramP) && *paramP != '}')
   1844      1.1     skrll 	  paramP++;
   1845      1.1     skrll     }
   1846      1.1     skrll 
   1847      1.1     skrll   if (*++paramP != '\0')
   1848      1.1     skrll     as_warn (_("rest of line ignored; first ignored character is `%c'"),
   1849      1.1     skrll 	     *paramP);
   1850      1.1     skrll 
   1851      1.1     skrll   switch (hi_found + lo_found)
   1852      1.1     skrll     {
   1853      1.1     skrll     case 0:
   1854      1.1     skrll       /* At least one register should be specified.  */
   1855      1.1     skrll       if (mask == 0)
   1856      1.1     skrll 	as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
   1857      1.1     skrll 		ins_parse);
   1858      1.1     skrll       break;
   1859      1.1     skrll 
   1860      1.1     skrll     case 1:
   1861      1.1     skrll       /* HI can't be specified without LO (and vise-versa).  */
   1862      1.1     skrll       as_bad (_("HI/LO registers should be specified together"));
   1863      1.1     skrll       break;
   1864      1.1     skrll 
   1865      1.1     skrll     case 2:
   1866      1.1     skrll       /* HI/LO registers mustn't be masked with additional registers.  */
   1867      1.1     skrll       if (mask != 0)
   1868      1.1     skrll 	as_bad (_("HI/LO registers should be specified without additional registers"));
   1869      1.1     skrll 
   1870      1.1     skrll     default:
   1871      1.1     skrll       break;
   1872      1.1     skrll     }
   1873      1.1     skrll 
   1874      1.1     skrll   sprintf (maskstring, "$0x%x", mask);
   1875      1.1     skrll   strcat (new_param, maskstring);
   1876      1.1     skrll   return new_param;
   1877      1.1     skrll }
   1878      1.1     skrll 
   1879      1.1     skrll /* Print the instruction.
   1880      1.1     skrll    Handle also cases where the instruction is relaxable/relocatable.  */
   1881      1.1     skrll 
   1882      1.1     skrll void
   1883      1.1     skrll print_insn (ins *insn)
   1884      1.1     skrll {
   1885      1.1     skrll   unsigned int i, j, insn_size;
   1886      1.1     skrll   char *this_frag;
   1887      1.1     skrll   unsigned short words[4];
   1888      1.1     skrll   int addr_mod;
   1889      1.1     skrll 
   1890      1.1     skrll   /* Arrange the insn encodings in a WORD size array.  */
   1891      1.1     skrll   for (i = 0, j = 0; i < 2; i++)
   1892      1.1     skrll     {
   1893      1.1     skrll       words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
   1894      1.1     skrll       words[j++] = output_opcode[i] & 0xFFFF;
   1895      1.1     skrll     }
   1896      1.1     skrll 
   1897      1.1     skrll   /* Handle relaxtion.  */
   1898      1.1     skrll   if ((instruction->flags & RELAXABLE) && relocatable)
   1899      1.1     skrll     {
   1900      1.1     skrll       int relax_subtype;
   1901      1.1     skrll 
   1902      1.1     skrll       /* Write the maximal instruction size supported.  */
   1903      1.1     skrll       insn_size = INSN_MAX_SIZE;
   1904      1.1     skrll 
   1905      1.1     skrll       /* bCC  */
   1906      1.1     skrll       if (IS_INSN_TYPE (BRANCH_INS))
   1907      1.1     skrll 	relax_subtype = 0;
   1908      1.1     skrll       /* bal  */
   1909      1.1     skrll       else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
   1910      1.1     skrll 	relax_subtype = 3;
   1911      1.1     skrll       /* cmpbr/bcop  */
   1912      1.1     skrll       else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
   1913      1.1     skrll 	relax_subtype = 5;
   1914      1.1     skrll       else
   1915      1.1     skrll 	abort ();
   1916      1.1     skrll 
   1917      1.1     skrll       this_frag = frag_var (rs_machine_dependent, insn_size * 2,
   1918      1.1     skrll 			    4, relax_subtype,
   1919      1.1     skrll 			    insn->exp.X_add_symbol,
   1920      1.1     skrll 			    insn->exp.X_add_number,
   1921      1.1     skrll 			    0);
   1922      1.1     skrll     }
   1923      1.1     skrll   else
   1924      1.1     skrll     {
   1925      1.1     skrll       insn_size = instruction->size;
   1926      1.1     skrll       this_frag = frag_more (insn_size * 2);
   1927      1.1     skrll 
   1928      1.1     skrll       /* Handle relocation.  */
   1929      1.1     skrll       if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
   1930      1.1     skrll 	{
   1931      1.1     skrll 	  reloc_howto_type *reloc_howto;
   1932      1.1     skrll 	  int size;
   1933      1.1     skrll 
   1934      1.1     skrll 	  reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
   1935      1.1     skrll 
   1936      1.1     skrll 	  if (!reloc_howto)
   1937      1.1     skrll 	    abort ();
   1938      1.1     skrll 
   1939      1.1     skrll 	  size = bfd_get_reloc_size (reloc_howto);
   1940      1.1     skrll 
   1941      1.1     skrll 	  if (size < 1 || size > 4)
   1942      1.1     skrll 	    abort ();
   1943      1.1     skrll 
   1944      1.1     skrll 	  fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
   1945      1.1     skrll 		       size, &insn->exp, reloc_howto->pc_relative,
   1946      1.1     skrll 		       insn->rtype);
   1947      1.1     skrll 	}
   1948      1.1     skrll     }
   1949      1.1     skrll 
   1950      1.1     skrll   /* Verify a 2-byte code alignment.  */
   1951      1.1     skrll   addr_mod = frag_now_fix () & 1;
   1952      1.1     skrll   if (frag_now->has_code && frag_now->insn_addr != addr_mod)
   1953      1.1     skrll     as_bad (_("instruction address is not a multiple of 2"));
   1954      1.1     skrll   frag_now->insn_addr = addr_mod;
   1955      1.1     skrll   frag_now->has_code = 1;
   1956      1.1     skrll 
   1957      1.1     skrll   /* Write the instruction encoding to frag.  */
   1958      1.1     skrll   for (i = 0; i < insn_size; i++)
   1959      1.1     skrll     {
   1960      1.1     skrll       md_number_to_chars (this_frag, (valueT) words[i], 2);
   1961      1.1     skrll       this_frag += 2;
   1962      1.1     skrll     }
   1963      1.1     skrll }
   1964      1.1     skrll 
   1965      1.1     skrll /* This is the guts of the machine-dependent assembler.  OP points to a
   1966      1.1     skrll    machine dependent instruction.  This function is supposed to emit
   1967      1.1     skrll    the frags/bytes it assembles to.  */
   1968      1.1     skrll 
   1969      1.1     skrll void
   1970      1.1     skrll md_assemble (char *op)
   1971      1.1     skrll {
   1972      1.1     skrll   ins crx_ins;
   1973      1.1     skrll   char *param;
   1974      1.1     skrll   char c;
   1975      1.1     skrll 
   1976      1.1     skrll   /* Reset global variables for a new instruction.  */
   1977      1.1     skrll   reset_vars (op);
   1978      1.1     skrll 
   1979      1.1     skrll   /* Strip the mnemonic.  */
   1980      1.1     skrll   for (param = op; *param != 0 && !ISSPACE (*param); param++)
   1981      1.1     skrll     ;
   1982      1.1     skrll   c = *param;
   1983      1.1     skrll   *param++ = '\0';
   1984      1.1     skrll 
   1985      1.1     skrll   /* Find the instruction.  */
   1986      1.1     skrll   instruction = (const inst *) hash_find (crx_inst_hash, op);
   1987      1.1     skrll   if (instruction == NULL)
   1988      1.1     skrll     {
   1989      1.1     skrll       as_bad (_("Unknown opcode: `%s'"), op);
   1990  1.1.1.2  christos       param[-1] = c;
   1991      1.1     skrll       return;
   1992      1.1     skrll     }
   1993      1.1     skrll 
   1994      1.1     skrll   /* Tie dwarf2 debug info to the address at the start of the insn.  */
   1995      1.1     skrll   dwarf2_emit_insn (0);
   1996      1.1     skrll 
   1997      1.1     skrll   /* Parse the instruction's operands.  */
   1998      1.1     skrll   parse_insn (&crx_ins, param);
   1999      1.1     skrll 
   2000      1.1     skrll   /* Assemble the instruction - return upon failure.  */
   2001      1.1     skrll   if (assemble_insn (op, &crx_ins) == 0)
   2002  1.1.1.2  christos     {
   2003  1.1.1.2  christos       param[-1] = c;
   2004  1.1.1.2  christos       return;
   2005  1.1.1.2  christos     }
   2006      1.1     skrll 
   2007      1.1     skrll   /* Print the instruction.  */
   2008  1.1.1.2  christos   param[-1] = c;
   2009      1.1     skrll   print_insn (&crx_ins);
   2010      1.1     skrll }
   2011