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