Home | History | Annotate | Line # | Download | only in config
tc-arc.c revision 1.1.1.1
      1  1.1  skrll /* tc-arc.c -- Assembler for the ARC
      2  1.1  skrll    Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
      3  1.1  skrll    2006, 2007  Free Software Foundation, Inc.
      4  1.1  skrll    Contributed by Doug Evans (dje (at) cygnus.com).
      5  1.1  skrll 
      6  1.1  skrll    This file is part of GAS, the GNU Assembler.
      7  1.1  skrll 
      8  1.1  skrll    GAS is free software; you can redistribute it and/or modify
      9  1.1  skrll    it under the terms of the GNU General Public License as published by
     10  1.1  skrll    the Free Software Foundation; either version 3, or (at your option)
     11  1.1  skrll    any later version.
     12  1.1  skrll 
     13  1.1  skrll    GAS is distributed in the hope that it will be useful,
     14  1.1  skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  skrll    GNU General Public License for more details.
     17  1.1  skrll 
     18  1.1  skrll    You should have received a copy of the GNU General Public License
     19  1.1  skrll    along with GAS; see the file COPYING.  If not, write to the Free
     20  1.1  skrll    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     21  1.1  skrll    02110-1301, USA.  */
     22  1.1  skrll 
     23  1.1  skrll #include "as.h"
     24  1.1  skrll #include "struc-symbol.h"
     25  1.1  skrll #include "safe-ctype.h"
     26  1.1  skrll #include "subsegs.h"
     27  1.1  skrll #include "opcode/arc.h"
     28  1.1  skrll #include "../opcodes/arc-ext.h"
     29  1.1  skrll #include "elf/arc.h"
     30  1.1  skrll #include "dwarf2dbg.h"
     31  1.1  skrll 
     32  1.1  skrll const struct suffix_classes
     33  1.1  skrll {
     34  1.1  skrll   char *name;
     35  1.1  skrll   int  len;
     36  1.1  skrll } suffixclass[] =
     37  1.1  skrll {
     38  1.1  skrll   { "SUFFIX_COND|SUFFIX_FLAG",23 },
     39  1.1  skrll   { "SUFFIX_FLAG", 11 },
     40  1.1  skrll   { "SUFFIX_COND", 11 },
     41  1.1  skrll   { "SUFFIX_NONE", 11 }
     42  1.1  skrll };
     43  1.1  skrll 
     44  1.1  skrll #define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
     45  1.1  skrll 
     46  1.1  skrll const struct syntax_classes
     47  1.1  skrll {
     48  1.1  skrll   char *name;
     49  1.1  skrll   int  len;
     50  1.1  skrll   int  class;
     51  1.1  skrll } syntaxclass[] =
     52  1.1  skrll {
     53  1.1  skrll   { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
     54  1.1  skrll   { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
     55  1.1  skrll   { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
     56  1.1  skrll   { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
     57  1.1  skrll   { "SYNTAX_3OP",                 10, SYNTAX_3OP|SYNTAX_VALID },
     58  1.1  skrll   { "SYNTAX_2OP",                 10, SYNTAX_2OP|SYNTAX_VALID }
     59  1.1  skrll };
     60  1.1  skrll 
     61  1.1  skrll #define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
     62  1.1  skrll 
     63  1.1  skrll /* This array holds the chars that always start a comment.  If the
     64  1.1  skrll    pre-processor is disabled, these aren't very useful.  */
     65  1.1  skrll const char comment_chars[] = "#;";
     66  1.1  skrll 
     67  1.1  skrll /* This array holds the chars that only start a comment at the beginning of
     68  1.1  skrll    a line.  If the line seems to have the form '# 123 filename'
     69  1.1  skrll    .line and .file directives will appear in the pre-processed output */
     70  1.1  skrll /* Note that input_file.c hand checks for '#' at the beginning of the
     71  1.1  skrll    first line of the input file.  This is because the compiler outputs
     72  1.1  skrll    #NO_APP at the beginning of its output.  */
     73  1.1  skrll /* Also note that comments started like this one will always
     74  1.1  skrll    work if '/' isn't otherwise defined.  */
     75  1.1  skrll const char line_comment_chars[] = "#";
     76  1.1  skrll 
     77  1.1  skrll const char line_separator_chars[] = "";
     78  1.1  skrll 
     79  1.1  skrll /* Chars that can be used to separate mant from exp in floating point nums.  */
     80  1.1  skrll const char EXP_CHARS[] = "eE";
     81  1.1  skrll 
     82  1.1  skrll /* Chars that mean this number is a floating point constant
     83  1.1  skrll    As in 0f12.456 or 0d1.2345e12.  */
     84  1.1  skrll const char FLT_CHARS[] = "rRsSfFdD";
     85  1.1  skrll 
     86  1.1  skrll /* Byte order.  */
     87  1.1  skrll extern int target_big_endian;
     88  1.1  skrll const char *arc_target_format = DEFAULT_TARGET_FORMAT;
     89  1.1  skrll static int byte_order = DEFAULT_BYTE_ORDER;
     90  1.1  skrll 
     91  1.1  skrll static segT arcext_section;
     92  1.1  skrll 
     93  1.1  skrll /* One of bfd_mach_arc_n.  */
     94  1.1  skrll static int arc_mach_type = bfd_mach_arc_6;
     95  1.1  skrll 
     96  1.1  skrll /* Non-zero if the cpu type has been explicitly specified.  */
     97  1.1  skrll static int mach_type_specified_p = 0;
     98  1.1  skrll 
     99  1.1  skrll /* Non-zero if opcode tables have been initialized.
    100  1.1  skrll    A .option command must appear before any instructions.  */
    101  1.1  skrll static int cpu_tables_init_p = 0;
    102  1.1  skrll 
    103  1.1  skrll static struct hash_control *arc_suffix_hash = NULL;
    104  1.1  skrll 
    105  1.1  skrll const char *md_shortopts = "";
    107  1.1  skrll 
    108  1.1  skrll enum options
    109  1.1  skrll {
    110  1.1  skrll   OPTION_EB = OPTION_MD_BASE,
    111  1.1  skrll   OPTION_EL,
    112  1.1  skrll   OPTION_ARC5,
    113  1.1  skrll   OPTION_ARC6,
    114  1.1  skrll   OPTION_ARC7,
    115  1.1  skrll   OPTION_ARC8,
    116  1.1  skrll   OPTION_ARC
    117  1.1  skrll };
    118  1.1  skrll 
    119  1.1  skrll struct option md_longopts[] =
    120  1.1  skrll {
    121  1.1  skrll   { "EB", no_argument, NULL, OPTION_EB },
    122  1.1  skrll   { "EL", no_argument, NULL, OPTION_EL },
    123  1.1  skrll   { "marc5", no_argument, NULL, OPTION_ARC5 },
    124  1.1  skrll   { "pre-v6", no_argument, NULL, OPTION_ARC5 },
    125  1.1  skrll   { "marc6", no_argument, NULL, OPTION_ARC6 },
    126  1.1  skrll   { "marc7", no_argument, NULL, OPTION_ARC7 },
    127  1.1  skrll   { "marc8", no_argument, NULL, OPTION_ARC8 },
    128  1.1  skrll   { "marc", no_argument, NULL, OPTION_ARC },
    129  1.1  skrll   { NULL, no_argument, NULL, 0 }
    130  1.1  skrll };
    131  1.1  skrll size_t md_longopts_size = sizeof (md_longopts);
    132  1.1  skrll 
    133  1.1  skrll #define IS_SYMBOL_OPERAND(o) \
    134  1.1  skrll  ((o) == 'b' || (o) == 'c' || (o) == 's' || (o) == 'o' || (o) == 'O')
    135  1.1  skrll 
    136  1.1  skrll struct arc_operand_value *get_ext_suffix (char *s);
    137  1.1  skrll 
    138  1.1  skrll /* Invocation line includes a switch not recognized by the base assembler.
    139  1.1  skrll    See if it's a processor-specific option.  */
    140  1.1  skrll 
    141  1.1  skrll int
    142  1.1  skrll md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
    143  1.1  skrll {
    144  1.1  skrll   switch (c)
    145  1.1  skrll     {
    146  1.1  skrll     case OPTION_ARC5:
    147  1.1  skrll       arc_mach_type = bfd_mach_arc_5;
    148  1.1  skrll       break;
    149  1.1  skrll     case OPTION_ARC:
    150  1.1  skrll     case OPTION_ARC6:
    151  1.1  skrll       arc_mach_type = bfd_mach_arc_6;
    152  1.1  skrll       break;
    153  1.1  skrll     case OPTION_ARC7:
    154  1.1  skrll       arc_mach_type = bfd_mach_arc_7;
    155  1.1  skrll       break;
    156  1.1  skrll     case OPTION_ARC8:
    157  1.1  skrll       arc_mach_type = bfd_mach_arc_8;
    158  1.1  skrll       break;
    159  1.1  skrll     case OPTION_EB:
    160  1.1  skrll       byte_order = BIG_ENDIAN;
    161  1.1  skrll       arc_target_format = "elf32-bigarc";
    162  1.1  skrll       break;
    163  1.1  skrll     case OPTION_EL:
    164  1.1  skrll       byte_order = LITTLE_ENDIAN;
    165  1.1  skrll       arc_target_format = "elf32-littlearc";
    166  1.1  skrll       break;
    167  1.1  skrll     default:
    168  1.1  skrll       return 0;
    169  1.1  skrll     }
    170  1.1  skrll   return 1;
    171  1.1  skrll }
    172  1.1  skrll 
    173  1.1  skrll void
    174  1.1  skrll md_show_usage (FILE *stream)
    175  1.1  skrll {
    176  1.1  skrll   fprintf (stream, "\
    177  1.1  skrll ARC Options:\n\
    178  1.1  skrll   -marc[5|6|7|8]          select processor variant (default arc%d)\n\
    179  1.1  skrll   -EB                     assemble code for a big endian cpu\n\
    180  1.1  skrll   -EL                     assemble code for a little endian cpu\n", arc_mach_type + 5);
    181  1.1  skrll }
    182  1.1  skrll 
    183  1.1  skrll /* This function is called once, at assembler startup time.  It should
    184  1.1  skrll    set up all the tables, etc. that the MD part of the assembler will need.
    185  1.1  skrll    Opcode selection is deferred until later because we might see a .option
    186  1.1  skrll    command.  */
    187  1.1  skrll 
    188  1.1  skrll void
    189  1.1  skrll md_begin (void)
    190  1.1  skrll {
    191  1.1  skrll   /* The endianness can be chosen "at the factory".  */
    192  1.1  skrll   target_big_endian = byte_order == BIG_ENDIAN;
    193  1.1  skrll 
    194  1.1  skrll   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
    195  1.1  skrll     as_warn (_("could not set architecture and machine"));
    196  1.1  skrll 
    197  1.1  skrll   /* This call is necessary because we need to initialize `arc_operand_map'
    198  1.1  skrll      which may be needed before we see the first insn.  */
    199  1.1  skrll   arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
    200  1.1  skrll 					       target_big_endian));
    201  1.1  skrll }
    202  1.1  skrll 
    203  1.1  skrll /* Initialize the various opcode and operand tables.
    204  1.1  skrll    MACH is one of bfd_mach_arc_xxx.  */
    205  1.1  skrll 
    206  1.1  skrll static void
    207  1.1  skrll init_opcode_tables (int mach)
    208  1.1  skrll {
    209  1.1  skrll   int i;
    210  1.1  skrll   char *last;
    211  1.1  skrll 
    212  1.1  skrll   if ((arc_suffix_hash = hash_new ()) == NULL)
    213  1.1  skrll     as_fatal (_("virtual memory exhausted"));
    214  1.1  skrll 
    215  1.1  skrll   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
    216  1.1  skrll     as_warn (_("could not set architecture and machine"));
    217  1.1  skrll 
    218  1.1  skrll   /* This initializes a few things in arc-opc.c that we need.
    219  1.1  skrll      This must be called before the various arc_xxx_supported fns.  */
    220  1.1  skrll   arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
    221  1.1  skrll 
    222  1.1  skrll   /* Only put the first entry of each equivalently named suffix in the
    223  1.1  skrll      table.  */
    224  1.1  skrll   last = "";
    225  1.1  skrll   for (i = 0; i < arc_suffixes_count; i++)
    226  1.1  skrll     {
    227  1.1  skrll       if (strcmp (arc_suffixes[i].name, last) != 0)
    228  1.1  skrll 	hash_insert (arc_suffix_hash, arc_suffixes[i].name, (void *) (arc_suffixes + i));
    229  1.1  skrll       last = arc_suffixes[i].name;
    230  1.1  skrll     }
    231  1.1  skrll 
    232  1.1  skrll   /* Since registers don't have a prefix, we put them in the symbol table so
    233  1.1  skrll      they can't be used as symbols.  This also simplifies argument parsing as
    234  1.1  skrll      we can let gas parse registers for us.  The recorded register number is
    235  1.1  skrll      the address of the register's entry in arc_reg_names.
    236  1.1  skrll 
    237  1.1  skrll      If the register name is already in the table, then the existing
    238  1.1  skrll      definition is assumed to be from an .ExtCoreRegister pseudo-op.  */
    239  1.1  skrll 
    240  1.1  skrll   for (i = 0; i < arc_reg_names_count; i++)
    241  1.1  skrll     {
    242  1.1  skrll       if (symbol_find (arc_reg_names[i].name))
    243  1.1  skrll 	continue;
    244  1.1  skrll       /* Use symbol_create here instead of symbol_new so we don't try to
    245  1.1  skrll 	 output registers into the object file's symbol table.  */
    246  1.1  skrll       symbol_table_insert (symbol_create (arc_reg_names[i].name,
    247  1.1  skrll 					  reg_section,
    248  1.1  skrll 					  (valueT) &arc_reg_names[i],
    249  1.1  skrll 					  &zero_address_frag));
    250  1.1  skrll     }
    251  1.1  skrll 
    252  1.1  skrll   /* Tell `.option' it's too late.  */
    253  1.1  skrll   cpu_tables_init_p = 1;
    254  1.1  skrll }
    255  1.1  skrll 
    256  1.1  skrll /* Insert an operand value into an instruction.
    258  1.1  skrll    If REG is non-NULL, it is a register number and ignore VAL.  */
    259  1.1  skrll 
    260  1.1  skrll static arc_insn
    261  1.1  skrll arc_insert_operand (arc_insn insn,
    262  1.1  skrll 		    const struct arc_operand *operand,
    263  1.1  skrll 		    int mods,
    264  1.1  skrll 		    const struct arc_operand_value *reg,
    265  1.1  skrll 		    offsetT val,
    266  1.1  skrll 		    char *file,
    267  1.1  skrll 		    unsigned int line)
    268  1.1  skrll {
    269  1.1  skrll   if (operand->bits != 32)
    270  1.1  skrll     {
    271  1.1  skrll       long min, max;
    272  1.1  skrll       offsetT test;
    273  1.1  skrll 
    274  1.1  skrll       if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
    275  1.1  skrll 	{
    276  1.1  skrll 	  if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
    277  1.1  skrll 	    max = (1 << operand->bits) - 1;
    278  1.1  skrll 	  else
    279  1.1  skrll 	    max = (1 << (operand->bits - 1)) - 1;
    280  1.1  skrll 	  min = - (1 << (operand->bits - 1));
    281  1.1  skrll 	}
    282  1.1  skrll       else
    283  1.1  skrll 	{
    284  1.1  skrll 	  max = (1 << operand->bits) - 1;
    285  1.1  skrll 	  min = 0;
    286  1.1  skrll 	}
    287  1.1  skrll 
    288  1.1  skrll       if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
    289  1.1  skrll 	test = - val;
    290  1.1  skrll       else
    291  1.1  skrll 	test = val;
    292  1.1  skrll 
    293  1.1  skrll       if (test < (offsetT) min || test > (offsetT) max)
    294  1.1  skrll 	as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
    295  1.1  skrll     }
    296  1.1  skrll 
    297  1.1  skrll   if (operand->insert)
    298  1.1  skrll     {
    299  1.1  skrll       const char *errmsg;
    300  1.1  skrll 
    301  1.1  skrll       errmsg = NULL;
    302  1.1  skrll       insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
    303  1.1  skrll       if (errmsg != (const char *) NULL)
    304  1.1  skrll 	as_warn (errmsg);
    305  1.1  skrll     }
    306  1.1  skrll   else
    307  1.1  skrll     insn |= (((long) val & ((1 << operand->bits) - 1))
    308  1.1  skrll 	     << operand->shift);
    309  1.1  skrll 
    310  1.1  skrll   return insn;
    311  1.1  skrll }
    312  1.1  skrll 
    313  1.1  skrll /* We need to keep a list of fixups.  We can't simply generate them as
    314  1.1  skrll    we go, because that would require us to first create the frag, and
    315  1.1  skrll    that would screw up references to ``.''.  */
    316  1.1  skrll 
    317  1.1  skrll struct arc_fixup
    318  1.1  skrll {
    319  1.1  skrll   /* index into `arc_operands'  */
    320  1.1  skrll   int opindex;
    321  1.1  skrll   expressionS exp;
    322  1.1  skrll };
    323  1.1  skrll 
    324  1.1  skrll #define MAX_FIXUPS 5
    325  1.1  skrll 
    326  1.1  skrll #define MAX_SUFFIXES 5
    327  1.1  skrll 
    328  1.1  skrll /* Compute the reloc type of an expression.
    329  1.1  skrll    The possibly modified expression is stored in EXPNEW.
    330  1.1  skrll 
    331  1.1  skrll    This is used to convert the expressions generated by the %-op's into
    332  1.1  skrll    the appropriate operand type.  It is called for both data in instructions
    333  1.1  skrll    (operands) and data outside instructions (variables, debugging info, etc.).
    334  1.1  skrll 
    335  1.1  skrll    Currently supported %-ops:
    336  1.1  skrll 
    337  1.1  skrll    %st(symbol): represented as "symbol >> 2"
    338  1.1  skrll                 "st" is short for STatus as in the status register (pc)
    339  1.1  skrll 
    340  1.1  skrll    DEFAULT_TYPE is the type to use if no special processing is required.
    341  1.1  skrll 
    342  1.1  skrll    DATA_P is non-zero for data or limm values, zero for insn operands.
    343  1.1  skrll    Remember that the opcode "insertion fns" cannot be used on data, they're
    344  1.1  skrll    only for inserting operands into insns.  They also can't be used for limm
    345  1.1  skrll    values as the insertion routines don't handle limm values.  When called for
    346  1.1  skrll    insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED).  When
    347  1.1  skrll    called for data or limm values we use real reloc types.  */
    348  1.1  skrll 
    349  1.1  skrll static int
    350  1.1  skrll get_arc_exp_reloc_type (int data_p,
    351  1.1  skrll 			int default_type,
    352  1.1  skrll 			expressionS *exp,
    353  1.1  skrll 			expressionS *expnew)
    354  1.1  skrll {
    355  1.1  skrll   /* If the expression is "symbol >> 2" we must change it to just "symbol",
    356  1.1  skrll      as fix_new_exp can't handle it.  Similarly for (symbol - symbol) >> 2.
    357  1.1  skrll      That's ok though.  What's really going on here is that we're using
    358  1.1  skrll      ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26.  */
    359  1.1  skrll 
    360  1.1  skrll   if (exp->X_op == O_right_shift
    361  1.1  skrll       && exp->X_op_symbol != NULL
    362  1.1  skrll       && exp->X_op_symbol->sy_value.X_op == O_constant
    363  1.1  skrll       && exp->X_op_symbol->sy_value.X_add_number == 2
    364  1.1  skrll       && exp->X_add_number == 0)
    365  1.1  skrll     {
    366  1.1  skrll       if (exp->X_add_symbol != NULL
    367  1.1  skrll 	  && (exp->X_add_symbol->sy_value.X_op == O_constant
    368  1.1  skrll 	      || exp->X_add_symbol->sy_value.X_op == O_symbol))
    369  1.1  skrll 	{
    370  1.1  skrll 	  *expnew = *exp;
    371  1.1  skrll 	  expnew->X_op = O_symbol;
    372  1.1  skrll 	  expnew->X_op_symbol = NULL;
    373  1.1  skrll 	  return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
    374  1.1  skrll 	}
    375  1.1  skrll       else if (exp->X_add_symbol != NULL
    376  1.1  skrll 	       && exp->X_add_symbol->sy_value.X_op == O_subtract)
    377  1.1  skrll 	{
    378  1.1  skrll 	  *expnew = exp->X_add_symbol->sy_value;
    379  1.1  skrll 	  return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
    380  1.1  skrll 	}
    381  1.1  skrll     }
    382  1.1  skrll 
    383  1.1  skrll   *expnew = *exp;
    384  1.1  skrll   return default_type;
    385  1.1  skrll }
    386  1.1  skrll 
    387  1.1  skrll static int
    389  1.1  skrll arc_set_ext_seg (void)
    390  1.1  skrll {
    391  1.1  skrll   if (!arcext_section)
    392  1.1  skrll     {
    393  1.1  skrll       arcext_section = subseg_new (".arcextmap", 0);
    394  1.1  skrll       bfd_set_section_flags (stdoutput, arcext_section,
    395  1.1  skrll 			     SEC_READONLY | SEC_HAS_CONTENTS);
    396  1.1  skrll     }
    397  1.1  skrll   else
    398  1.1  skrll     subseg_set (arcext_section, 0);
    399  1.1  skrll   return 1;
    400  1.1  skrll }
    401  1.1  skrll 
    402  1.1  skrll static void
    403  1.1  skrll arc_extoper (int opertype)
    404  1.1  skrll {
    405  1.1  skrll   char *name;
    406  1.1  skrll   char *mode;
    407  1.1  skrll   char c;
    408  1.1  skrll   char *p;
    409  1.1  skrll   int imode = 0;
    410  1.1  skrll   int number;
    411  1.1  skrll   struct arc_ext_operand_value *ext_oper;
    412  1.1  skrll   symbolS *symbolP;
    413  1.1  skrll 
    414  1.1  skrll   segT old_sec;
    415  1.1  skrll   int old_subsec;
    416  1.1  skrll 
    417  1.1  skrll   name = input_line_pointer;
    418  1.1  skrll   c = get_symbol_end ();
    419  1.1  skrll   name = xstrdup (name);
    420  1.1  skrll 
    421  1.1  skrll   p = name;
    422  1.1  skrll   while (*p)
    423  1.1  skrll     {
    424  1.1  skrll       *p = TOLOWER (*p);
    425  1.1  skrll       p++;
    426  1.1  skrll     }
    427  1.1  skrll 
    428  1.1  skrll   /* just after name is now '\0'  */
    429  1.1  skrll   p = input_line_pointer;
    430  1.1  skrll   *p = c;
    431  1.1  skrll   SKIP_WHITESPACE ();
    432  1.1  skrll 
    433  1.1  skrll   if (*input_line_pointer != ',')
    434  1.1  skrll     {
    435  1.1  skrll       as_bad (_("expected comma after operand name"));
    436  1.1  skrll       ignore_rest_of_line ();
    437  1.1  skrll       free (name);
    438  1.1  skrll       return;
    439  1.1  skrll     }
    440  1.1  skrll 
    441  1.1  skrll   input_line_pointer++;		/* skip ','  */
    442  1.1  skrll   number = get_absolute_expression ();
    443  1.1  skrll 
    444  1.1  skrll   if (number < 0)
    445  1.1  skrll     {
    446  1.1  skrll       as_bad (_("negative operand number %d"), number);
    447  1.1  skrll       ignore_rest_of_line ();
    448  1.1  skrll       free (name);
    449  1.1  skrll       return;
    450  1.1  skrll     }
    451  1.1  skrll 
    452  1.1  skrll   if (opertype)
    453  1.1  skrll     {
    454  1.1  skrll       SKIP_WHITESPACE ();
    455  1.1  skrll 
    456  1.1  skrll       if (*input_line_pointer != ',')
    457  1.1  skrll 	{
    458  1.1  skrll 	  as_bad (_("expected comma after register-number"));
    459  1.1  skrll 	  ignore_rest_of_line ();
    460  1.1  skrll 	  free (name);
    461  1.1  skrll 	  return;
    462  1.1  skrll 	}
    463  1.1  skrll 
    464  1.1  skrll       input_line_pointer++;		/* skip ','  */
    465  1.1  skrll       mode = input_line_pointer;
    466  1.1  skrll 
    467  1.1  skrll       if (!strncmp (mode, "r|w", 3))
    468  1.1  skrll 	{
    469  1.1  skrll 	  imode = 0;
    470  1.1  skrll 	  input_line_pointer += 3;
    471  1.1  skrll 	}
    472  1.1  skrll       else
    473  1.1  skrll 	{
    474  1.1  skrll 	  if (!strncmp (mode, "r", 1))
    475  1.1  skrll 	    {
    476  1.1  skrll 	      imode = ARC_REGISTER_READONLY;
    477  1.1  skrll 	      input_line_pointer += 1;
    478  1.1  skrll 	    }
    479  1.1  skrll 	  else
    480  1.1  skrll 	    {
    481  1.1  skrll 	      if (strncmp (mode, "w", 1))
    482  1.1  skrll 		{
    483  1.1  skrll 		  as_bad (_("invalid mode"));
    484  1.1  skrll 		  ignore_rest_of_line ();
    485  1.1  skrll 		  free (name);
    486  1.1  skrll 		  return;
    487  1.1  skrll 		}
    488  1.1  skrll 	      else
    489  1.1  skrll 		{
    490  1.1  skrll 		  imode = ARC_REGISTER_WRITEONLY;
    491  1.1  skrll 		  input_line_pointer += 1;
    492  1.1  skrll 		}
    493  1.1  skrll 	    }
    494  1.1  skrll 	}
    495  1.1  skrll       SKIP_WHITESPACE ();
    496  1.1  skrll       if (1 == opertype)
    497  1.1  skrll 	{
    498  1.1  skrll 	  if (*input_line_pointer != ',')
    499  1.1  skrll 	    {
    500  1.1  skrll 	      as_bad (_("expected comma after register-mode"));
    501  1.1  skrll 	      ignore_rest_of_line ();
    502  1.1  skrll 	      free (name);
    503  1.1  skrll 	      return;
    504  1.1  skrll 	    }
    505  1.1  skrll 
    506  1.1  skrll 	  input_line_pointer++;		/* skip ','  */
    507  1.1  skrll 
    508  1.1  skrll 	  if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
    509  1.1  skrll 	    {
    510  1.1  skrll 	      imode |= arc_get_noshortcut_flag ();
    511  1.1  skrll 	      input_line_pointer += 15;
    512  1.1  skrll 	    }
    513  1.1  skrll 	  else
    514  1.1  skrll 	    {
    515  1.1  skrll 	      if (strncmp (input_line_pointer, "can_shortcut", 12))
    516  1.1  skrll 		{
    517  1.1  skrll 		  as_bad (_("shortcut designator invalid"));
    518  1.1  skrll 		  ignore_rest_of_line ();
    519  1.1  skrll 		  free (name);
    520  1.1  skrll 		  return;
    521  1.1  skrll 		}
    522  1.1  skrll 	      else
    523  1.1  skrll 		{
    524  1.1  skrll 		  input_line_pointer += 12;
    525  1.1  skrll 		}
    526  1.1  skrll 	    }
    527  1.1  skrll 	}
    528  1.1  skrll     }
    529  1.1  skrll 
    530  1.1  skrll   if ((opertype == 1) && number > 60)
    531  1.1  skrll     {
    532  1.1  skrll       as_bad (_("core register value (%d) too large"), number);
    533  1.1  skrll       ignore_rest_of_line ();
    534  1.1  skrll       free (name);
    535  1.1  skrll       return;
    536  1.1  skrll     }
    537  1.1  skrll 
    538  1.1  skrll   if ((opertype == 0) && number > 31)
    539  1.1  skrll     {
    540  1.1  skrll       as_bad (_("condition code value (%d) too large"), number);
    541  1.1  skrll       ignore_rest_of_line ();
    542  1.1  skrll       free (name);
    543  1.1  skrll       return;
    544  1.1  skrll     }
    545  1.1  skrll 
    546  1.1  skrll   ext_oper = xmalloc (sizeof (struct arc_ext_operand_value));
    547  1.1  skrll 
    548  1.1  skrll   if (opertype)
    549  1.1  skrll     {
    550  1.1  skrll       /* If the symbol already exists, point it at the new definition.  */
    551  1.1  skrll       if ((symbolP = symbol_find (name)))
    552  1.1  skrll 	{
    553  1.1  skrll 	  if (S_GET_SEGMENT (symbolP) == reg_section)
    554  1.1  skrll 	    S_SET_VALUE (symbolP, (valueT) &ext_oper->operand);
    555  1.1  skrll 	  else
    556  1.1  skrll 	    {
    557  1.1  skrll 	      as_bad (_("attempt to override symbol: %s"), name);
    558  1.1  skrll 	      ignore_rest_of_line ();
    559  1.1  skrll 	      free (name);
    560  1.1  skrll 	      free (ext_oper);
    561  1.1  skrll 	      return;
    562  1.1  skrll 	    }
    563  1.1  skrll 	}
    564  1.1  skrll       else
    565  1.1  skrll 	{
    566  1.1  skrll 	  /* If its not there, add it.  */
    567  1.1  skrll 	  symbol_table_insert (symbol_create (name, reg_section,
    568  1.1  skrll 					      (valueT) &ext_oper->operand,
    569  1.1  skrll 					      &zero_address_frag));
    570  1.1  skrll 	}
    571  1.1  skrll     }
    572  1.1  skrll 
    573  1.1  skrll   ext_oper->operand.name  = name;
    574  1.1  skrll   ext_oper->operand.value = number;
    575  1.1  skrll   ext_oper->operand.type  = arc_operand_type (opertype);
    576  1.1  skrll   ext_oper->operand.flags = imode;
    577  1.1  skrll 
    578  1.1  skrll   ext_oper->next = arc_ext_operands;
    579  1.1  skrll   arc_ext_operands = ext_oper;
    580  1.1  skrll 
    581  1.1  skrll   /* OK, now that we know what this operand is, put a description in
    582  1.1  skrll      the arc extension section of the output file.  */
    583  1.1  skrll 
    584  1.1  skrll   old_sec    = now_seg;
    585  1.1  skrll   old_subsec = now_subseg;
    586  1.1  skrll 
    587  1.1  skrll   arc_set_ext_seg ();
    588  1.1  skrll 
    589  1.1  skrll   switch (opertype)
    590  1.1  skrll     {
    591  1.1  skrll     case 0:
    592  1.1  skrll       p = frag_more (1);
    593  1.1  skrll       *p = 3 + strlen (name) + 1;
    594  1.1  skrll       p = frag_more (1);
    595  1.1  skrll       *p = EXT_COND_CODE;
    596  1.1  skrll       p = frag_more (1);
    597  1.1  skrll       *p = number;
    598  1.1  skrll       p = frag_more (strlen (name) + 1);
    599  1.1  skrll       strcpy (p, name);
    600  1.1  skrll       break;
    601  1.1  skrll     case 1:
    602  1.1  skrll       p = frag_more (1);
    603  1.1  skrll       *p = 3 + strlen (name) + 1;
    604  1.1  skrll       p = frag_more (1);
    605  1.1  skrll       *p = EXT_CORE_REGISTER;
    606  1.1  skrll       p = frag_more (1);
    607  1.1  skrll       *p = number;
    608  1.1  skrll       p = frag_more (strlen (name) + 1);
    609  1.1  skrll       strcpy (p, name);
    610  1.1  skrll       break;
    611  1.1  skrll     case 2:
    612  1.1  skrll       p = frag_more (1);
    613  1.1  skrll       *p = 6 + strlen (name) + 1;
    614  1.1  skrll       p = frag_more (1);
    615  1.1  skrll       *p = EXT_AUX_REGISTER;
    616  1.1  skrll       p = frag_more (1);
    617  1.1  skrll       *p = number >> 24 & 0xff;
    618  1.1  skrll       p = frag_more (1);
    619  1.1  skrll       *p = number >> 16 & 0xff;
    620  1.1  skrll       p = frag_more (1);
    621  1.1  skrll       *p = number >>  8 & 0xff;
    622  1.1  skrll       p = frag_more (1);
    623  1.1  skrll       *p = number       & 0xff;
    624  1.1  skrll       p = frag_more (strlen (name) + 1);
    625  1.1  skrll       strcpy (p, name);
    626  1.1  skrll       break;
    627  1.1  skrll     default:
    628  1.1  skrll       as_bad (_("invalid opertype"));
    629  1.1  skrll       ignore_rest_of_line ();
    630  1.1  skrll       free (name);
    631  1.1  skrll       return;
    632  1.1  skrll       break;
    633  1.1  skrll     }
    634  1.1  skrll 
    635  1.1  skrll   subseg_set (old_sec, old_subsec);
    636  1.1  skrll 
    637  1.1  skrll   /* Enter all registers into the symbol table.  */
    638  1.1  skrll 
    639  1.1  skrll   demand_empty_rest_of_line ();
    640  1.1  skrll }
    641  1.1  skrll 
    642  1.1  skrll static void
    643  1.1  skrll arc_extinst (int ignore ATTRIBUTE_UNUSED)
    644  1.1  skrll {
    645  1.1  skrll   char syntax[129];
    646  1.1  skrll   char *name;
    647  1.1  skrll   char *p;
    648  1.1  skrll   char c;
    649  1.1  skrll   int suffixcode = -1;
    650  1.1  skrll   int opcode, subopcode;
    651  1.1  skrll   int i;
    652  1.1  skrll   int class = 0;
    653  1.1  skrll   int name_len;
    654  1.1  skrll   struct arc_opcode *ext_op;
    655  1.1  skrll 
    656  1.1  skrll   segT old_sec;
    657  1.1  skrll   int old_subsec;
    658  1.1  skrll 
    659  1.1  skrll   name = input_line_pointer;
    660  1.1  skrll   c = get_symbol_end ();
    661  1.1  skrll   name = xstrdup (name);
    662  1.1  skrll   strcpy (syntax, name);
    663  1.1  skrll   name_len = strlen (name);
    664  1.1  skrll 
    665  1.1  skrll   /* just after name is now '\0'  */
    666  1.1  skrll   p = input_line_pointer;
    667  1.1  skrll   *p = c;
    668  1.1  skrll 
    669  1.1  skrll   SKIP_WHITESPACE ();
    670  1.1  skrll 
    671  1.1  skrll   if (*input_line_pointer != ',')
    672  1.1  skrll     {
    673  1.1  skrll       as_bad (_("expected comma after operand name"));
    674  1.1  skrll       ignore_rest_of_line ();
    675  1.1  skrll       return;
    676  1.1  skrll     }
    677  1.1  skrll 
    678  1.1  skrll   input_line_pointer++;		/* skip ','  */
    679  1.1  skrll   opcode = get_absolute_expression ();
    680  1.1  skrll 
    681  1.1  skrll   SKIP_WHITESPACE ();
    682  1.1  skrll 
    683  1.1  skrll   if (*input_line_pointer != ',')
    684  1.1  skrll     {
    685  1.1  skrll       as_bad (_("expected comma after opcode"));
    686  1.1  skrll       ignore_rest_of_line ();
    687  1.1  skrll       return;
    688  1.1  skrll     }
    689  1.1  skrll 
    690  1.1  skrll   input_line_pointer++;		/* skip ','  */
    691  1.1  skrll   subopcode = get_absolute_expression ();
    692  1.1  skrll 
    693  1.1  skrll   if (subopcode < 0)
    694  1.1  skrll     {
    695  1.1  skrll       as_bad (_("negative subopcode %d"), subopcode);
    696  1.1  skrll       ignore_rest_of_line ();
    697  1.1  skrll       return;
    698  1.1  skrll     }
    699  1.1  skrll 
    700  1.1  skrll   if (subopcode)
    701  1.1  skrll     {
    702  1.1  skrll       if (3 != opcode)
    703  1.1  skrll 	{
    704  1.1  skrll 	  as_bad (_("subcode value found when opcode not equal 0x03"));
    705  1.1  skrll 	  ignore_rest_of_line ();
    706  1.1  skrll 	  return;
    707  1.1  skrll 	}
    708  1.1  skrll       else
    709  1.1  skrll 	{
    710  1.1  skrll 	  if (subopcode < 0x09 || subopcode == 0x3f)
    711  1.1  skrll 	    {
    712  1.1  skrll 	      as_bad (_("invalid subopcode %d"), subopcode);
    713  1.1  skrll 	      ignore_rest_of_line ();
    714  1.1  skrll 	      return;
    715  1.1  skrll 	    }
    716  1.1  skrll 	}
    717  1.1  skrll     }
    718  1.1  skrll 
    719  1.1  skrll   SKIP_WHITESPACE ();
    720  1.1  skrll 
    721  1.1  skrll   if (*input_line_pointer != ',')
    722  1.1  skrll     {
    723  1.1  skrll       as_bad (_("expected comma after subopcode"));
    724  1.1  skrll       ignore_rest_of_line ();
    725  1.1  skrll       return;
    726  1.1  skrll     }
    727  1.1  skrll 
    728  1.1  skrll   input_line_pointer++;		/* skip ','  */
    729  1.1  skrll 
    730  1.1  skrll   for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
    731  1.1  skrll     {
    732  1.1  skrll       if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
    733  1.1  skrll 	{
    734  1.1  skrll 	  suffixcode = i;
    735  1.1  skrll 	  input_line_pointer += suffixclass[i].len;
    736  1.1  skrll 	  break;
    737  1.1  skrll 	}
    738  1.1  skrll     }
    739  1.1  skrll 
    740  1.1  skrll   if (-1 == suffixcode)
    741  1.1  skrll     {
    742  1.1  skrll       as_bad (_("invalid suffix class"));
    743  1.1  skrll       ignore_rest_of_line ();
    744  1.1  skrll       return;
    745  1.1  skrll     }
    746  1.1  skrll 
    747  1.1  skrll   SKIP_WHITESPACE ();
    748  1.1  skrll 
    749  1.1  skrll   if (*input_line_pointer != ',')
    750  1.1  skrll     {
    751  1.1  skrll       as_bad (_("expected comma after suffix class"));
    752  1.1  skrll       ignore_rest_of_line ();
    753  1.1  skrll       return;
    754  1.1  skrll     }
    755  1.1  skrll 
    756  1.1  skrll   input_line_pointer++;		/* skip ','  */
    757  1.1  skrll 
    758  1.1  skrll   for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
    759  1.1  skrll     {
    760  1.1  skrll       if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
    761  1.1  skrll 	{
    762  1.1  skrll 	  class = syntaxclass[i].class;
    763  1.1  skrll 	  input_line_pointer += syntaxclass[i].len;
    764  1.1  skrll 	  break;
    765  1.1  skrll 	}
    766  1.1  skrll     }
    767  1.1  skrll 
    768  1.1  skrll   if (0 == (SYNTAX_VALID & class))
    769  1.1  skrll     {
    770  1.1  skrll       as_bad (_("invalid syntax class"));
    771  1.1  skrll       ignore_rest_of_line ();
    772  1.1  skrll       return;
    773  1.1  skrll     }
    774  1.1  skrll 
    775  1.1  skrll   if ((0x3 == opcode) & (class & SYNTAX_3OP))
    776  1.1  skrll     {
    777  1.1  skrll       as_bad (_("opcode 0x3 and SYNTAX_3OP invalid"));
    778  1.1  skrll       ignore_rest_of_line ();
    779  1.1  skrll       return;
    780  1.1  skrll     }
    781  1.1  skrll 
    782  1.1  skrll   switch (suffixcode)
    783  1.1  skrll     {
    784  1.1  skrll     case 0:
    785  1.1  skrll       strcat (syntax, "%.q%.f ");
    786  1.1  skrll       break;
    787  1.1  skrll     case 1:
    788  1.1  skrll       strcat (syntax, "%.f ");
    789  1.1  skrll       break;
    790  1.1  skrll     case 2:
    791  1.1  skrll       strcat (syntax, "%.q ");
    792  1.1  skrll       break;
    793  1.1  skrll     case 3:
    794  1.1  skrll       strcat (syntax, " ");
    795  1.1  skrll       break;
    796  1.1  skrll     default:
    797  1.1  skrll       as_bad (_("unknown suffix class"));
    798  1.1  skrll       ignore_rest_of_line ();
    799  1.1  skrll       return;
    800  1.1  skrll       break;
    801  1.1  skrll     };
    802  1.1  skrll 
    803  1.1  skrll   strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
    804  1.1  skrll   if (suffixcode < 2)
    805  1.1  skrll     strcat (syntax, "%F");
    806  1.1  skrll   strcat (syntax, "%S%L");
    807  1.1  skrll 
    808  1.1  skrll   ext_op = xmalloc (sizeof (struct arc_opcode));
    809  1.1  skrll   ext_op->syntax = xstrdup (syntax);
    810  1.1  skrll 
    811  1.1  skrll   ext_op->mask  = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
    812  1.1  skrll   ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
    813  1.1  skrll   ext_op->flags = class;
    814  1.1  skrll   ext_op->next_asm = arc_ext_opcodes;
    815  1.1  skrll   ext_op->next_dis = arc_ext_opcodes;
    816  1.1  skrll   arc_ext_opcodes = ext_op;
    817  1.1  skrll 
    818  1.1  skrll   /* OK, now that we know what this inst is, put a description in the
    819  1.1  skrll      arc extension section of the output file.  */
    820  1.1  skrll 
    821  1.1  skrll   old_sec    = now_seg;
    822  1.1  skrll   old_subsec = now_subseg;
    823  1.1  skrll 
    824  1.1  skrll   arc_set_ext_seg ();
    825  1.1  skrll 
    826  1.1  skrll   p = frag_more (1);
    827  1.1  skrll   *p = 5 + name_len + 1;
    828  1.1  skrll   p = frag_more (1);
    829  1.1  skrll   *p = EXT_INSTRUCTION;
    830  1.1  skrll   p = frag_more (1);
    831  1.1  skrll   *p = opcode;
    832  1.1  skrll   p = frag_more (1);
    833  1.1  skrll   *p = subopcode;
    834  1.1  skrll   p = frag_more (1);
    835  1.1  skrll   *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
    836  1.1  skrll   p = frag_more (name_len);
    837  1.1  skrll   strncpy (p, syntax, name_len);
    838  1.1  skrll   p = frag_more (1);
    839  1.1  skrll   *p = '\0';
    840  1.1  skrll 
    841  1.1  skrll   subseg_set (old_sec, old_subsec);
    842  1.1  skrll 
    843  1.1  skrll   demand_empty_rest_of_line ();
    844  1.1  skrll }
    845  1.1  skrll 
    846  1.1  skrll static void
    847  1.1  skrll arc_common (int localScope)
    848  1.1  skrll {
    849  1.1  skrll   char *name;
    850  1.1  skrll   char c;
    851  1.1  skrll   char *p;
    852  1.1  skrll   int align, size;
    853  1.1  skrll   symbolS *symbolP;
    854  1.1  skrll 
    855  1.1  skrll   name = input_line_pointer;
    856  1.1  skrll   c = get_symbol_end ();
    857  1.1  skrll   /* just after name is now '\0'  */
    858  1.1  skrll   p = input_line_pointer;
    859  1.1  skrll   *p = c;
    860  1.1  skrll   SKIP_WHITESPACE ();
    861  1.1  skrll 
    862  1.1  skrll   if (*input_line_pointer != ',')
    863  1.1  skrll     {
    864  1.1  skrll       as_bad (_("expected comma after symbol name"));
    865  1.1  skrll       ignore_rest_of_line ();
    866  1.1  skrll       return;
    867  1.1  skrll     }
    868  1.1  skrll 
    869  1.1  skrll   input_line_pointer++;		/* skip ','  */
    870  1.1  skrll   size = get_absolute_expression ();
    871  1.1  skrll 
    872  1.1  skrll   if (size < 0)
    873  1.1  skrll     {
    874  1.1  skrll       as_bad (_("negative symbol length"));
    875  1.1  skrll       ignore_rest_of_line ();
    876  1.1  skrll       return;
    877  1.1  skrll     }
    878  1.1  skrll 
    879  1.1  skrll   *p = 0;
    880  1.1  skrll   symbolP = symbol_find_or_make (name);
    881  1.1  skrll   *p = c;
    882  1.1  skrll 
    883  1.1  skrll   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
    884  1.1  skrll     {
    885  1.1  skrll       as_bad (_("ignoring attempt to re-define symbol"));
    886  1.1  skrll       ignore_rest_of_line ();
    887  1.1  skrll       return;
    888  1.1  skrll     }
    889  1.1  skrll   if (((int) S_GET_VALUE (symbolP) != 0) \
    890  1.1  skrll       && ((int) S_GET_VALUE (symbolP) != size))
    891  1.1  skrll     {
    892  1.1  skrll       as_warn (_("length of symbol \"%s\" already %ld, ignoring %d"),
    893  1.1  skrll 	       S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
    894  1.1  skrll     }
    895  1.1  skrll   assert (symbolP->sy_frag == &zero_address_frag);
    896  1.1  skrll 
    897  1.1  skrll   /* Now parse the alignment field.  This field is optional for
    898  1.1  skrll      local and global symbols. Default alignment is zero.  */
    899  1.1  skrll   if (*input_line_pointer == ',')
    900  1.1  skrll     {
    901  1.1  skrll       input_line_pointer++;
    902  1.1  skrll       align = get_absolute_expression ();
    903  1.1  skrll       if (align < 0)
    904  1.1  skrll 	{
    905  1.1  skrll 	  align = 0;
    906  1.1  skrll 	  as_warn (_("assuming symbol alignment of zero"));
    907  1.1  skrll 	}
    908  1.1  skrll     }
    909  1.1  skrll   else
    910  1.1  skrll     align = 0;
    911  1.1  skrll 
    912  1.1  skrll   if (localScope != 0)
    913  1.1  skrll     {
    914  1.1  skrll       segT old_sec;
    915  1.1  skrll       int old_subsec;
    916  1.1  skrll       char *pfrag;
    917  1.1  skrll 
    918  1.1  skrll       old_sec    = now_seg;
    919  1.1  skrll       old_subsec = now_subseg;
    920  1.1  skrll       record_alignment (bss_section, align);
    921  1.1  skrll       subseg_set (bss_section, 0);  /* ??? subseg_set (bss_section, 1); ???  */
    922  1.1  skrll 
    923  1.1  skrll       if (align)
    924  1.1  skrll 	/* Do alignment.  */
    925  1.1  skrll 	frag_align (align, 0, 0);
    926  1.1  skrll 
    927  1.1  skrll       /* Detach from old frag.  */
    928  1.1  skrll       if (S_GET_SEGMENT (symbolP) == bss_section)
    929  1.1  skrll 	symbolP->sy_frag->fr_symbol = NULL;
    930  1.1  skrll 
    931  1.1  skrll       symbolP->sy_frag = frag_now;
    932  1.1  skrll       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
    933  1.1  skrll 			(offsetT) size, (char *) 0);
    934  1.1  skrll       *pfrag = 0;
    935  1.1  skrll 
    936  1.1  skrll       S_SET_SIZE       (symbolP, size);
    937  1.1  skrll       S_SET_SEGMENT    (symbolP, bss_section);
    938  1.1  skrll       S_CLEAR_EXTERNAL (symbolP);
    939  1.1  skrll       symbolP->local = 1;
    940  1.1  skrll       subseg_set (old_sec, old_subsec);
    941  1.1  skrll     }
    942  1.1  skrll   else
    943  1.1  skrll     {
    944  1.1  skrll       S_SET_VALUE    (symbolP, (valueT) size);
    945  1.1  skrll       S_SET_ALIGN    (symbolP, align);
    946  1.1  skrll       S_SET_EXTERNAL (symbolP);
    947  1.1  skrll       S_SET_SEGMENT  (symbolP, bfd_com_section_ptr);
    948  1.1  skrll     }
    949  1.1  skrll 
    950  1.1  skrll   symbolP->bsym->flags |= BSF_OBJECT;
    951  1.1  skrll 
    952  1.1  skrll   demand_empty_rest_of_line ();
    953  1.1  skrll }
    954  1.1  skrll 
    955  1.1  skrll /* Select the cpu we're assembling for.  */
    957  1.1  skrll 
    958  1.1  skrll static void
    959  1.1  skrll arc_option (int ignore ATTRIBUTE_UNUSED)
    960  1.1  skrll {
    961  1.1  skrll   extern int arc_get_mach (char *);
    962  1.1  skrll   int mach;
    963  1.1  skrll   char c;
    964  1.1  skrll   char *cpu;
    965  1.1  skrll 
    966  1.1  skrll   cpu = input_line_pointer;
    967  1.1  skrll   c = get_symbol_end ();
    968  1.1  skrll   mach = arc_get_mach (cpu);
    969  1.1  skrll   *input_line_pointer = c;
    970  1.1  skrll 
    971  1.1  skrll   /* If an instruction has already been seen, it's too late.  */
    972  1.1  skrll   if (cpu_tables_init_p)
    973  1.1  skrll     {
    974  1.1  skrll       as_bad (_("\".option\" directive must appear before any instructions"));
    975  1.1  skrll       ignore_rest_of_line ();
    976  1.1  skrll       return;
    977  1.1  skrll     }
    978  1.1  skrll 
    979  1.1  skrll   if (mach == -1)
    980  1.1  skrll     goto bad_cpu;
    981  1.1  skrll 
    982  1.1  skrll   if (mach_type_specified_p && mach != arc_mach_type)
    983  1.1  skrll     {
    984  1.1  skrll       as_bad (_("\".option\" directive conflicts with initial definition"));
    985  1.1  skrll       ignore_rest_of_line ();
    986  1.1  skrll       return;
    987  1.1  skrll     }
    988  1.1  skrll   else
    989  1.1  skrll     {
    990  1.1  skrll       /* The cpu may have been selected on the command line.  */
    991  1.1  skrll       if (mach != arc_mach_type)
    992  1.1  skrll 	as_warn (_("\".option\" directive overrides command-line (default) value"));
    993  1.1  skrll       arc_mach_type = mach;
    994  1.1  skrll       if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
    995  1.1  skrll 	as_fatal (_("could not set architecture and machine"));
    996  1.1  skrll       mach_type_specified_p = 1;
    997  1.1  skrll     }
    998  1.1  skrll   demand_empty_rest_of_line ();
    999  1.1  skrll   return;
   1000  1.1  skrll 
   1001  1.1  skrll  bad_cpu:
   1002  1.1  skrll   as_bad (_("invalid identifier for \".option\""));
   1003  1.1  skrll   ignore_rest_of_line ();
   1004  1.1  skrll }
   1005  1.1  skrll 
   1006  1.1  skrll char *
   1008  1.1  skrll md_atof (int type, char *litP, int *sizeP)
   1009  1.1  skrll {
   1010  1.1  skrll   return ieee_md_atof (type, litP, sizeP, TRUE);
   1011  1.1  skrll }
   1012  1.1  skrll 
   1013  1.1  skrll /* Write a value out to the object file, using the appropriate
   1014  1.1  skrll    endianness.  */
   1015  1.1  skrll 
   1016  1.1  skrll void
   1017  1.1  skrll md_number_to_chars (char *buf, valueT val, int n)
   1018  1.1  skrll {
   1019  1.1  skrll   if (target_big_endian)
   1020  1.1  skrll     number_to_chars_bigendian (buf, val, n);
   1021  1.1  skrll   else
   1022  1.1  skrll     number_to_chars_littleendian (buf, val, n);
   1023  1.1  skrll }
   1024  1.1  skrll 
   1025  1.1  skrll /* Round up a section size to the appropriate boundary.  */
   1026  1.1  skrll 
   1027  1.1  skrll valueT
   1028  1.1  skrll md_section_align (segT segment, valueT size)
   1029  1.1  skrll {
   1030  1.1  skrll   int align = bfd_get_section_alignment (stdoutput, segment);
   1031  1.1  skrll 
   1032  1.1  skrll   return ((size + (1 << align) - 1) & (-1 << align));
   1033  1.1  skrll }
   1034  1.1  skrll 
   1035  1.1  skrll /* We don't have any form of relaxing.  */
   1036  1.1  skrll 
   1037  1.1  skrll int
   1038  1.1  skrll md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
   1039  1.1  skrll 			       asection *seg ATTRIBUTE_UNUSED)
   1040  1.1  skrll {
   1041  1.1  skrll   as_fatal (_("relaxation not supported\n"));
   1042  1.1  skrll   return 1;
   1043  1.1  skrll }
   1044  1.1  skrll 
   1045  1.1  skrll /* Convert a machine dependent frag.  We never generate these.  */
   1046  1.1  skrll 
   1047  1.1  skrll void
   1048  1.1  skrll md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   1049  1.1  skrll 		 asection *sec ATTRIBUTE_UNUSED,
   1050  1.1  skrll 		 fragS *fragp ATTRIBUTE_UNUSED)
   1051  1.1  skrll {
   1052  1.1  skrll   abort ();
   1053  1.1  skrll }
   1054  1.1  skrll 
   1055  1.1  skrll static void
   1056  1.1  skrll arc_code_symbol (expressionS *expressionP)
   1057  1.1  skrll {
   1058  1.1  skrll   if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
   1059  1.1  skrll     {
   1060  1.1  skrll       expressionS two;
   1061  1.1  skrll 
   1062  1.1  skrll       expressionP->X_op = O_right_shift;
   1063  1.1  skrll       expressionP->X_add_symbol->sy_value.X_op = O_constant;
   1064  1.1  skrll       two.X_op = O_constant;
   1065  1.1  skrll       two.X_add_symbol = two.X_op_symbol = NULL;
   1066  1.1  skrll       two.X_add_number = 2;
   1067  1.1  skrll       expressionP->X_op_symbol = make_expr_symbol (&two);
   1068  1.1  skrll     }
   1069  1.1  skrll   /* Allow %st(sym1-sym2)  */
   1070  1.1  skrll   else if (expressionP->X_op == O_subtract
   1071  1.1  skrll 	   && expressionP->X_add_symbol != NULL
   1072  1.1  skrll 	   && expressionP->X_op_symbol != NULL
   1073  1.1  skrll 	   && expressionP->X_add_number == 0)
   1074  1.1  skrll     {
   1075  1.1  skrll       expressionS two;
   1076  1.1  skrll 
   1077  1.1  skrll       expressionP->X_add_symbol = make_expr_symbol (expressionP);
   1078  1.1  skrll       expressionP->X_op = O_right_shift;
   1079  1.1  skrll       two.X_op = O_constant;
   1080  1.1  skrll       two.X_add_symbol = two.X_op_symbol = NULL;
   1081  1.1  skrll       two.X_add_number = 2;
   1082  1.1  skrll       expressionP->X_op_symbol = make_expr_symbol (&two);
   1083  1.1  skrll     }
   1084  1.1  skrll   else
   1085  1.1  skrll     as_bad (_("expression too complex code symbol"));
   1086  1.1  skrll }
   1087  1.1  skrll 
   1088  1.1  skrll /* Parse an operand that is machine-specific.
   1089  1.1  skrll 
   1090  1.1  skrll    The ARC has a special %-op to adjust addresses so they're usable in
   1091  1.1  skrll    branches.  The "st" is short for the STatus register.
   1092  1.1  skrll    ??? Later expand this to take a flags value too.
   1093  1.1  skrll 
   1094  1.1  skrll    ??? We can't create new expression types so we map the %-op's onto the
   1095  1.1  skrll    existing syntax.  This means that the user could use the chosen syntax
   1096  1.1  skrll    to achieve the same effect.  */
   1097  1.1  skrll 
   1098  1.1  skrll void
   1099  1.1  skrll md_operand (expressionS *expressionP)
   1100  1.1  skrll {
   1101  1.1  skrll   char *p = input_line_pointer;
   1102  1.1  skrll 
   1103  1.1  skrll   if (*p != '%')
   1104  1.1  skrll     return;
   1105  1.1  skrll 
   1106  1.1  skrll   if (strncmp (p, "%st(", 4) == 0)
   1107  1.1  skrll     {
   1108  1.1  skrll       input_line_pointer += 4;
   1109  1.1  skrll       expression (expressionP);
   1110  1.1  skrll       if (*input_line_pointer != ')')
   1111  1.1  skrll 	{
   1112  1.1  skrll 	  as_bad (_("missing ')' in %%-op"));
   1113  1.1  skrll 	  return;
   1114  1.1  skrll 	}
   1115  1.1  skrll       ++input_line_pointer;
   1116  1.1  skrll       arc_code_symbol (expressionP);
   1117  1.1  skrll     }
   1118  1.1  skrll   else
   1119  1.1  skrll     {
   1120  1.1  skrll       /* It could be a register.  */
   1121  1.1  skrll       int i, l;
   1122  1.1  skrll       struct arc_ext_operand_value *ext_oper = arc_ext_operands;
   1123  1.1  skrll       p++;
   1124  1.1  skrll 
   1125  1.1  skrll       while (ext_oper)
   1126  1.1  skrll 	{
   1127  1.1  skrll 	  l = strlen (ext_oper->operand.name);
   1128  1.1  skrll 	  if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
   1129  1.1  skrll 	    {
   1130  1.1  skrll 	      input_line_pointer += l + 1;
   1131  1.1  skrll 	      expressionP->X_op = O_register;
   1132  1.1  skrll 	      expressionP->X_add_number = (offsetT) &ext_oper->operand;
   1133  1.1  skrll 	      return;
   1134  1.1  skrll 	    }
   1135  1.1  skrll 	  ext_oper = ext_oper->next;
   1136  1.1  skrll 	}
   1137  1.1  skrll       for (i = 0; i < arc_reg_names_count; i++)
   1138  1.1  skrll 	{
   1139  1.1  skrll 	  l = strlen (arc_reg_names[i].name);
   1140  1.1  skrll 	  if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
   1141  1.1  skrll 	    {
   1142  1.1  skrll 	      input_line_pointer += l + 1;
   1143  1.1  skrll 	      expressionP->X_op = O_register;
   1144  1.1  skrll 	      expressionP->X_add_number = (offsetT) &arc_reg_names[i];
   1145  1.1  skrll 	      break;
   1146  1.1  skrll 	    }
   1147  1.1  skrll 	}
   1148  1.1  skrll     }
   1149  1.1  skrll }
   1150  1.1  skrll 
   1151  1.1  skrll /* We have no need to default values of symbols.
   1152  1.1  skrll    We could catch register names here, but that is handled by inserting
   1153  1.1  skrll    them all in the symbol table to begin with.  */
   1154  1.1  skrll 
   1155  1.1  skrll symbolS *
   1156  1.1  skrll md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   1157  1.1  skrll {
   1158  1.1  skrll   return 0;
   1159  1.1  skrll }
   1160  1.1  skrll 
   1161  1.1  skrll /* Functions concerning expressions.  */
   1163  1.1  skrll 
   1164  1.1  skrll /* Parse a .byte, .word, etc. expression.
   1165  1.1  skrll 
   1166  1.1  skrll    Values for the status register are specified with %st(label).
   1167  1.1  skrll    `label' will be right shifted by 2.  */
   1168  1.1  skrll 
   1169  1.1  skrll void
   1170  1.1  skrll arc_parse_cons_expression (expressionS *exp,
   1171  1.1  skrll 			   unsigned int nbytes ATTRIBUTE_UNUSED)
   1172  1.1  skrll {
   1173  1.1  skrll   char *p = input_line_pointer;
   1174  1.1  skrll   int code_symbol_fix = 0;
   1175  1.1  skrll 
   1176  1.1  skrll   for (; ! is_end_of_line[(unsigned char) *p]; p++)
   1177  1.1  skrll     if (*p == '@' && !strncmp (p, "@h30", 4))
   1178  1.1  skrll       {
   1179  1.1  skrll 	code_symbol_fix = 1;
   1180  1.1  skrll 	strcpy (p, ";   ");
   1181  1.1  skrll       }
   1182  1.1  skrll   expression_and_evaluate (exp);
   1183  1.1  skrll   if (code_symbol_fix)
   1184  1.1  skrll     {
   1185  1.1  skrll       arc_code_symbol (exp);
   1186  1.1  skrll       input_line_pointer = p;
   1187  1.1  skrll     }
   1188  1.1  skrll }
   1189  1.1  skrll 
   1190  1.1  skrll /* Record a fixup for a cons expression.  */
   1191  1.1  skrll 
   1192  1.1  skrll void
   1193  1.1  skrll arc_cons_fix_new (fragS *frag,
   1194  1.1  skrll 		  int where,
   1195  1.1  skrll 		  int nbytes,
   1196  1.1  skrll 		  expressionS *exp)
   1197  1.1  skrll {
   1198  1.1  skrll   if (nbytes == 4)
   1199  1.1  skrll     {
   1200  1.1  skrll       int reloc_type;
   1201  1.1  skrll       expressionS exptmp;
   1202  1.1  skrll 
   1203  1.1  skrll       /* This may be a special ARC reloc (eg: %st()).  */
   1204  1.1  skrll       reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
   1205  1.1  skrll       fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
   1206  1.1  skrll     }
   1207  1.1  skrll   else
   1208  1.1  skrll     {
   1209  1.1  skrll       fix_new_exp (frag, where, nbytes, exp, 0,
   1210  1.1  skrll 		   nbytes == 2 ? BFD_RELOC_16
   1211  1.1  skrll 		   : nbytes == 8 ? BFD_RELOC_64
   1212  1.1  skrll 		   : BFD_RELOC_32);
   1213  1.1  skrll     }
   1214  1.1  skrll }
   1215  1.1  skrll 
   1216  1.1  skrll /* Functions concerning relocs.  */
   1218  1.1  skrll 
   1219  1.1  skrll /* The location from which a PC relative jump should be calculated,
   1220  1.1  skrll    given a PC relative reloc.  */
   1221  1.1  skrll 
   1222  1.1  skrll long
   1223  1.1  skrll md_pcrel_from (fixS *fixP)
   1224  1.1  skrll {
   1225  1.1  skrll   /* Return the address of the delay slot.  */
   1226  1.1  skrll   return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
   1227  1.1  skrll }
   1228  1.1  skrll 
   1229  1.1  skrll /* Apply a fixup to the object code.  This is called for all the
   1230  1.1  skrll    fixups we generated by the call to fix_new_exp, above.  In the call
   1231  1.1  skrll    above we used a reloc code which was the largest legal reloc code
   1232  1.1  skrll    plus the operand index.  Here we undo that to recover the operand
   1233  1.1  skrll    index.  At this point all symbol values should be fully resolved,
   1234  1.1  skrll    and we attempt to completely resolve the reloc.  If we can not do
   1235  1.1  skrll    that, we determine the correct reloc code and put it back in the fixup.  */
   1236  1.1  skrll 
   1237  1.1  skrll void
   1238  1.1  skrll md_apply_fix (fixS *fixP, valueT * valP, segT seg)
   1239  1.1  skrll {
   1240  1.1  skrll   valueT value = * valP;
   1241  1.1  skrll 
   1242  1.1  skrll   if (fixP->fx_addsy == (symbolS *) NULL)
   1243  1.1  skrll     fixP->fx_done = 1;
   1244  1.1  skrll 
   1245  1.1  skrll   else if (fixP->fx_pcrel)
   1246  1.1  skrll     {
   1247  1.1  skrll       /* Hack around bfd_install_relocation brain damage.  */
   1248  1.1  skrll       if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
   1249  1.1  skrll 	value += md_pcrel_from (fixP);
   1250  1.1  skrll     }
   1251  1.1  skrll 
   1252  1.1  skrll   /* We can't actually support subtracting a symbol.  */
   1253  1.1  skrll   if (fixP->fx_subsy != NULL)
   1254  1.1  skrll     as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
   1255  1.1  skrll 
   1256  1.1  skrll   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
   1257  1.1  skrll     {
   1258  1.1  skrll       int opindex;
   1259  1.1  skrll       const struct arc_operand *operand;
   1260  1.1  skrll       char *where;
   1261  1.1  skrll       arc_insn insn;
   1262  1.1  skrll 
   1263  1.1  skrll       opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
   1264  1.1  skrll 
   1265  1.1  skrll       operand = &arc_operands[opindex];
   1266  1.1  skrll 
   1267  1.1  skrll       /* Fetch the instruction, insert the fully resolved operand
   1268  1.1  skrll 	 value, and stuff the instruction back again.  */
   1269  1.1  skrll       where = fixP->fx_frag->fr_literal + fixP->fx_where;
   1270  1.1  skrll       if (target_big_endian)
   1271  1.1  skrll 	insn = bfd_getb32 ((unsigned char *) where);
   1272  1.1  skrll       else
   1273  1.1  skrll 	insn = bfd_getl32 ((unsigned char *) where);
   1274  1.1  skrll       insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
   1275  1.1  skrll 				 fixP->fx_file, fixP->fx_line);
   1276  1.1  skrll       if (target_big_endian)
   1277  1.1  skrll 	bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
   1278  1.1  skrll       else
   1279  1.1  skrll 	bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
   1280  1.1  skrll 
   1281  1.1  skrll       if (fixP->fx_done)
   1282  1.1  skrll 	/* Nothing else to do here.  */
   1283  1.1  skrll 	return;
   1284  1.1  skrll 
   1285  1.1  skrll       /* Determine a BFD reloc value based on the operand information.
   1286  1.1  skrll 	 We are only prepared to turn a few of the operands into relocs.
   1287  1.1  skrll 	 !!! Note that we can't handle limm values here.  Since we're using
   1288  1.1  skrll 	 implicit addends the addend must be inserted into the instruction,
   1289  1.1  skrll 	 however, the opcode insertion routines currently do nothing with
   1290  1.1  skrll 	 limm values.  */
   1291  1.1  skrll       if (operand->fmt == 'B')
   1292  1.1  skrll 	{
   1293  1.1  skrll 	  assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
   1294  1.1  skrll 		  && operand->bits == 20
   1295  1.1  skrll 		  && operand->shift == 7);
   1296  1.1  skrll 	  fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
   1297  1.1  skrll 	}
   1298  1.1  skrll       else if (operand->fmt == 'J')
   1299  1.1  skrll 	{
   1300  1.1  skrll 	  assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
   1301  1.1  skrll 		  && operand->bits == 24
   1302  1.1  skrll 		  && operand->shift == 32);
   1303  1.1  skrll 	  fixP->fx_r_type = BFD_RELOC_ARC_B26;
   1304  1.1  skrll 	}
   1305  1.1  skrll       else if (operand->fmt == 'L')
   1306  1.1  skrll 	{
   1307  1.1  skrll 	  assert ((operand->flags & ARC_OPERAND_LIMM) != 0
   1308  1.1  skrll 		  && operand->bits == 32
   1309  1.1  skrll 		  && operand->shift == 32);
   1310  1.1  skrll 	  fixP->fx_r_type = BFD_RELOC_32;
   1311  1.1  skrll 	}
   1312  1.1  skrll       else
   1313  1.1  skrll 	{
   1314  1.1  skrll 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   1315  1.1  skrll 			_("unresolved expression that must be resolved"));
   1316  1.1  skrll 	  fixP->fx_done = 1;
   1317  1.1  skrll 	  return;
   1318  1.1  skrll 	}
   1319  1.1  skrll     }
   1320  1.1  skrll   else
   1321  1.1  skrll     {
   1322  1.1  skrll       switch (fixP->fx_r_type)
   1323  1.1  skrll 	{
   1324  1.1  skrll 	case BFD_RELOC_8:
   1325  1.1  skrll 	  md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
   1326  1.1  skrll 			      value, 1);
   1327  1.1  skrll 	  break;
   1328  1.1  skrll 	case BFD_RELOC_16:
   1329  1.1  skrll 	  md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
   1330  1.1  skrll 			      value, 2);
   1331  1.1  skrll 	  break;
   1332  1.1  skrll 	case BFD_RELOC_32:
   1333  1.1  skrll 	  md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
   1334  1.1  skrll 			      value, 4);
   1335  1.1  skrll 	  break;
   1336  1.1  skrll 	case BFD_RELOC_ARC_B26:
   1337  1.1  skrll 	  /* If !fixP->fx_done then `value' is an implicit addend.
   1338  1.1  skrll 	     We must shift it right by 2 in this case as well because the
   1339  1.1  skrll 	     linker performs the relocation and then adds this in (as opposed
   1340  1.1  skrll 	     to adding this in and then shifting right by 2).  */
   1341  1.1  skrll 	  value >>= 2;
   1342  1.1  skrll 	  md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
   1343  1.1  skrll 			      value, 4);
   1344  1.1  skrll 	  break;
   1345  1.1  skrll 	default:
   1346  1.1  skrll 	  abort ();
   1347  1.1  skrll 	}
   1348  1.1  skrll     }
   1349  1.1  skrll }
   1350  1.1  skrll 
   1351  1.1  skrll /* Translate internal representation of relocation info to BFD target
   1352  1.1  skrll    format.  */
   1353  1.1  skrll 
   1354  1.1  skrll arelent *
   1355  1.1  skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
   1356  1.1  skrll 	      fixS *fixP)
   1357  1.1  skrll {
   1358  1.1  skrll   arelent *reloc;
   1359  1.1  skrll 
   1360  1.1  skrll   reloc = xmalloc (sizeof (arelent));
   1361  1.1  skrll   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   1362  1.1  skrll 
   1363  1.1  skrll   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   1364  1.1  skrll   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   1365  1.1  skrll   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
   1366  1.1  skrll   if (reloc->howto == (reloc_howto_type *) NULL)
   1367  1.1  skrll     {
   1368  1.1  skrll       as_bad_where (fixP->fx_file, fixP->fx_line,
   1369  1.1  skrll 		    _("internal error: can't export reloc type %d (`%s')"),
   1370  1.1  skrll 		    fixP->fx_r_type,
   1371  1.1  skrll 		    bfd_get_reloc_code_name (fixP->fx_r_type));
   1372  1.1  skrll       return NULL;
   1373  1.1  skrll     }
   1374  1.1  skrll 
   1375  1.1  skrll   assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
   1376  1.1  skrll 
   1377  1.1  skrll   /* Set addend to account for PC being advanced one insn before the
   1378  1.1  skrll      target address is computed.  */
   1379  1.1  skrll 
   1380  1.1  skrll   reloc->addend = (fixP->fx_pcrel ? -4 : 0);
   1381  1.1  skrll 
   1382  1.1  skrll   return reloc;
   1383  1.1  skrll }
   1384  1.1  skrll 
   1385  1.1  skrll const pseudo_typeS md_pseudo_table[] =
   1386  1.1  skrll {
   1387  1.1  skrll   { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0).  */
   1388  1.1  skrll   { "comm", arc_common, 0 },
   1389  1.1  skrll   { "common", arc_common, 0 },
   1390  1.1  skrll   { "lcomm", arc_common, 1 },
   1391  1.1  skrll   { "lcommon", arc_common, 1 },
   1392  1.1  skrll   { "2byte", cons, 2 },
   1393  1.1  skrll   { "half", cons, 2 },
   1394  1.1  skrll   { "short", cons, 2 },
   1395  1.1  skrll   { "3byte", cons, 3 },
   1396  1.1  skrll   { "4byte", cons, 4 },
   1397  1.1  skrll   { "word", cons, 4 },
   1398  1.1  skrll   { "option", arc_option, 0 },
   1399  1.1  skrll   { "cpu", arc_option, 0 },
   1400  1.1  skrll   { "block", s_space, 0 },
   1401  1.1  skrll   { "extcondcode", arc_extoper, 0 },
   1402  1.1  skrll   { "extcoreregister", arc_extoper, 1 },
   1403  1.1  skrll   { "extauxregister", arc_extoper, 2 },
   1404  1.1  skrll   { "extinstruction", arc_extinst, 0 },
   1405  1.1  skrll   { NULL, 0, 0 },
   1406  1.1  skrll };
   1407  1.1  skrll 
   1408  1.1  skrll /* This routine is called for each instruction to be assembled.  */
   1409  1.1  skrll 
   1410  1.1  skrll void
   1411  1.1  skrll md_assemble (char *str)
   1412  1.1  skrll {
   1413  1.1  skrll   const struct arc_opcode *opcode;
   1414  1.1  skrll   const struct arc_opcode *std_opcode;
   1415  1.1  skrll   struct arc_opcode *ext_opcode;
   1416  1.1  skrll   char *start;
   1417  1.1  skrll   const char *last_errmsg = 0;
   1418  1.1  skrll   arc_insn insn;
   1419  1.1  skrll   static int init_tables_p = 0;
   1420  1.1  skrll 
   1421  1.1  skrll   /* Opcode table initialization is deferred until here because we have to
   1422  1.1  skrll      wait for a possible .option command.  */
   1423  1.1  skrll   if (!init_tables_p)
   1424  1.1  skrll     {
   1425  1.1  skrll       init_opcode_tables (arc_mach_type);
   1426  1.1  skrll       init_tables_p = 1;
   1427  1.1  skrll     }
   1428  1.1  skrll 
   1429  1.1  skrll   /* Skip leading white space.  */
   1430  1.1  skrll   while (ISSPACE (*str))
   1431  1.1  skrll     str++;
   1432  1.1  skrll 
   1433  1.1  skrll   /* The instructions are stored in lists hashed by the first letter (though
   1434  1.1  skrll      we needn't care how they're hashed).  Get the first in the list.  */
   1435  1.1  skrll 
   1436  1.1  skrll   ext_opcode = arc_ext_opcodes;
   1437  1.1  skrll   std_opcode = arc_opcode_lookup_asm (str);
   1438  1.1  skrll 
   1439  1.1  skrll   /* Keep looking until we find a match.  */
   1440  1.1  skrll   start = str;
   1441  1.1  skrll   for (opcode = (ext_opcode ? ext_opcode : std_opcode);
   1442  1.1  skrll        opcode != NULL;
   1443  1.1  skrll        opcode = (ARC_OPCODE_NEXT_ASM (opcode)
   1444  1.1  skrll 		 ? ARC_OPCODE_NEXT_ASM (opcode)
   1445  1.1  skrll 		 : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
   1446  1.1  skrll     {
   1447  1.1  skrll       int past_opcode_p, fc, num_suffixes;
   1448  1.1  skrll       int fix_up_at = 0;
   1449  1.1  skrll       char *syn;
   1450  1.1  skrll       struct arc_fixup fixups[MAX_FIXUPS];
   1451  1.1  skrll       /* Used as a sanity check.  If we need a limm reloc, make sure we ask
   1452  1.1  skrll 	 for an extra 4 bytes from frag_more.  */
   1453  1.1  skrll       int limm_reloc_p;
   1454  1.1  skrll       int ext_suffix_p;
   1455  1.1  skrll       const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
   1456  1.1  skrll 
   1457  1.1  skrll       /* Is this opcode supported by the selected cpu?  */
   1458  1.1  skrll       if (! arc_opcode_supported (opcode))
   1459  1.1  skrll 	continue;
   1460  1.1  skrll 
   1461  1.1  skrll       /* Scan the syntax string.  If it doesn't match, try the next one.  */
   1462  1.1  skrll       arc_opcode_init_insert ();
   1463  1.1  skrll       insn = opcode->value;
   1464  1.1  skrll       fc = 0;
   1465  1.1  skrll       past_opcode_p = 0;
   1466  1.1  skrll       num_suffixes = 0;
   1467  1.1  skrll       limm_reloc_p = 0;
   1468  1.1  skrll       ext_suffix_p = 0;
   1469  1.1  skrll 
   1470  1.1  skrll       /* We don't check for (*str != '\0') here because we want to parse
   1471  1.1  skrll 	 any trailing fake arguments in the syntax string.  */
   1472  1.1  skrll       for (str = start, syn = opcode->syntax; *syn != '\0';)
   1473  1.1  skrll 	{
   1474  1.1  skrll 	  int mods;
   1475  1.1  skrll 	  const struct arc_operand *operand;
   1476  1.1  skrll 
   1477  1.1  skrll 	  /* Non operand chars must match exactly.  */
   1478  1.1  skrll 	  if (*syn != '%' || *++syn == '%')
   1479  1.1  skrll 	    {
   1480  1.1  skrll 	     if (*str == *syn)
   1481  1.1  skrll 		{
   1482  1.1  skrll 		  if (*syn == ' ')
   1483  1.1  skrll 		    past_opcode_p = 1;
   1484  1.1  skrll 		  ++syn;
   1485  1.1  skrll 		  ++str;
   1486  1.1  skrll 		}
   1487  1.1  skrll 	      else
   1488  1.1  skrll 		break;
   1489  1.1  skrll 	      continue;
   1490  1.1  skrll 	    }
   1491  1.1  skrll 
   1492  1.1  skrll 	  /* We have an operand.  Pick out any modifiers.  */
   1493  1.1  skrll 	  mods = 0;
   1494  1.1  skrll 	  while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
   1495  1.1  skrll 	    {
   1496  1.1  skrll 	      mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
   1497  1.1  skrll 	      ++syn;
   1498  1.1  skrll 	    }
   1499  1.1  skrll 	  operand = arc_operands + arc_operand_map[(int) *syn];
   1500  1.1  skrll 	  if (operand->fmt == 0)
   1501  1.1  skrll 	    as_fatal (_("unknown syntax format character `%c'"), *syn);
   1502  1.1  skrll 
   1503  1.1  skrll 	  if (operand->flags & ARC_OPERAND_FAKE)
   1504  1.1  skrll 	    {
   1505  1.1  skrll 	      const char *errmsg = NULL;
   1506  1.1  skrll 	      if (operand->insert)
   1507  1.1  skrll 		{
   1508  1.1  skrll 		  insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
   1509  1.1  skrll 		  if (errmsg != (const char *) NULL)
   1510  1.1  skrll 		    {
   1511  1.1  skrll 		      last_errmsg = errmsg;
   1512  1.1  skrll 		      if (operand->flags & ARC_OPERAND_ERROR)
   1513  1.1  skrll 			{
   1514  1.1  skrll 			  as_bad (errmsg);
   1515  1.1  skrll 			  return;
   1516  1.1  skrll 			}
   1517  1.1  skrll 		      else if (operand->flags & ARC_OPERAND_WARN)
   1518  1.1  skrll 			as_warn (errmsg);
   1519  1.1  skrll 		      break;
   1520  1.1  skrll 		    }
   1521  1.1  skrll 		  if (limm_reloc_p
   1522  1.1  skrll 		      && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
   1523  1.1  skrll 		      && (operand->flags &
   1524  1.1  skrll 			  (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
   1525  1.1  skrll 		    {
   1526  1.1  skrll 		      fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
   1527  1.1  skrll 		    }
   1528  1.1  skrll 		}
   1529  1.1  skrll 	      ++syn;
   1530  1.1  skrll 	    }
   1531  1.1  skrll 	  /* Are we finished with suffixes?  */
   1532  1.1  skrll 	  else if (!past_opcode_p)
   1533  1.1  skrll 	    {
   1534  1.1  skrll 	      int found;
   1535  1.1  skrll 	      char c;
   1536  1.1  skrll 	      char *s, *t;
   1537  1.1  skrll 	      const struct arc_operand_value *suf, *suffix_end;
   1538  1.1  skrll 	      const struct arc_operand_value *suffix = NULL;
   1539  1.1  skrll 
   1540  1.1  skrll 	      if (!(operand->flags & ARC_OPERAND_SUFFIX))
   1541  1.1  skrll 		abort ();
   1542  1.1  skrll 
   1543  1.1  skrll 	      /* If we're at a space in the input string, we want to skip the
   1544  1.1  skrll 		 remaining suffixes.  There may be some fake ones though, so
   1545  1.1  skrll 		 just go on to try the next one.  */
   1546  1.1  skrll 	      if (*str == ' ')
   1547  1.1  skrll 		{
   1548  1.1  skrll 		  ++syn;
   1549  1.1  skrll 		  continue;
   1550  1.1  skrll 		}
   1551  1.1  skrll 
   1552  1.1  skrll 	      s = str;
   1553  1.1  skrll 	      if (mods & ARC_MOD_DOT)
   1554  1.1  skrll 		{
   1555  1.1  skrll 		  if (*s != '.')
   1556  1.1  skrll 		    break;
   1557  1.1  skrll 		  ++s;
   1558  1.1  skrll 		}
   1559  1.1  skrll 	      else
   1560  1.1  skrll 		{
   1561  1.1  skrll 		  /* This can happen in "b.nd foo" and we're currently looking
   1562  1.1  skrll 		     for "%q" (ie: a condition code suffix).  */
   1563  1.1  skrll 		  if (*s == '.')
   1564  1.1  skrll 		    {
   1565  1.1  skrll 		      ++syn;
   1566  1.1  skrll 		      continue;
   1567  1.1  skrll 		    }
   1568  1.1  skrll 		}
   1569  1.1  skrll 
   1570  1.1  skrll 	      /* Pick the suffix out and look it up via the hash table.  */
   1571  1.1  skrll 	      for (t = s; *t && ISALNUM (*t); ++t)
   1572  1.1  skrll 		continue;
   1573  1.1  skrll 	      c = *t;
   1574  1.1  skrll 	      *t = '\0';
   1575  1.1  skrll 	      if ((suf = get_ext_suffix (s)))
   1576  1.1  skrll 		ext_suffix_p = 1;
   1577  1.1  skrll 	      else
   1578  1.1  skrll 		suf = hash_find (arc_suffix_hash, s);
   1579  1.1  skrll 	      if (!suf)
   1580  1.1  skrll 		{
   1581  1.1  skrll 		  /* This can happen in "blle foo" and we're currently using
   1582  1.1  skrll 		     the template "b%q%.n %j".  The "bl" insn occurs later in
   1583  1.1  skrll 		     the table so "lle" isn't an illegal suffix.  */
   1584  1.1  skrll 		  *t = c;
   1585  1.1  skrll 		  break;
   1586  1.1  skrll 		}
   1587  1.1  skrll 
   1588  1.1  skrll 	      /* Is it the right type?  Note that the same character is used
   1589  1.1  skrll 		 several times, so we have to examine all of them.  This is
   1590  1.1  skrll 		 relatively efficient as equivalent entries are kept
   1591  1.1  skrll 		 together.  If it's not the right type, don't increment `str'
   1592  1.1  skrll 		 so we try the next one in the series.  */
   1593  1.1  skrll 	      found = 0;
   1594  1.1  skrll 	      if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
   1595  1.1  skrll 		{
   1596  1.1  skrll 		  /* Insert the suffix's value into the insn.  */
   1597  1.1  skrll 		  *t = c;
   1598  1.1  skrll 		  if (operand->insert)
   1599  1.1  skrll 		    insn = (*operand->insert) (insn, operand,
   1600  1.1  skrll 					       mods, NULL, suf->value,
   1601  1.1  skrll 					       NULL);
   1602  1.1  skrll 		  else
   1603  1.1  skrll 		    insn |= suf->value << operand->shift;
   1604  1.1  skrll 		  suffix = suf;
   1605  1.1  skrll 		  str = t;
   1606  1.1  skrll 		  found = 1;
   1607  1.1  skrll 		}
   1608  1.1  skrll 	      else
   1609  1.1  skrll 		{
   1610  1.1  skrll 		  *t = c;
   1611  1.1  skrll 		  suffix_end = arc_suffixes + arc_suffixes_count;
   1612  1.1  skrll 		  for (suffix = suf;
   1613  1.1  skrll 		       suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
   1614  1.1  skrll 		       ++suffix)
   1615  1.1  skrll 		    {
   1616  1.1  skrll 		      if (arc_operands[suffix->type].fmt == *syn)
   1617  1.1  skrll 			{
   1618  1.1  skrll 			  /* Insert the suffix's value into the insn.  */
   1619  1.1  skrll 			  if (operand->insert)
   1620  1.1  skrll 			    insn = (*operand->insert) (insn, operand,
   1621  1.1  skrll 						       mods, NULL, suffix->value,
   1622  1.1  skrll 						       NULL);
   1623  1.1  skrll 			  else
   1624  1.1  skrll 			    insn |= suffix->value << operand->shift;
   1625  1.1  skrll 
   1626  1.1  skrll 			  str = t;
   1627  1.1  skrll 			  found = 1;
   1628  1.1  skrll 			  break;
   1629  1.1  skrll 			}
   1630  1.1  skrll 		    }
   1631  1.1  skrll 		}
   1632  1.1  skrll 	      ++syn;
   1633  1.1  skrll 	      if (!found)
   1634  1.1  skrll 		/* Wrong type.  Just go on to try next insn entry.  */
   1635  1.1  skrll 		;
   1636  1.1  skrll 	      else
   1637  1.1  skrll 		{
   1638  1.1  skrll 		  if (num_suffixes == MAX_SUFFIXES)
   1639  1.1  skrll 		    as_bad (_("too many suffixes"));
   1640  1.1  skrll 		  else
   1641  1.1  skrll 		    insn_suffixes[num_suffixes++] = suffix;
   1642  1.1  skrll 		}
   1643  1.1  skrll 	    }
   1644  1.1  skrll 	  else
   1645  1.1  skrll 	    /* This is either a register or an expression of some kind.  */
   1646  1.1  skrll 	    {
   1647  1.1  skrll 	      char *hold;
   1648  1.1  skrll 	      const struct arc_operand_value *reg = NULL;
   1649  1.1  skrll 	      long value = 0;
   1650  1.1  skrll 	      expressionS exp;
   1651  1.1  skrll 
   1652  1.1  skrll 	      if (operand->flags & ARC_OPERAND_SUFFIX)
   1653  1.1  skrll 		abort ();
   1654  1.1  skrll 
   1655  1.1  skrll 	      /* Is there anything left to parse?
   1656  1.1  skrll 		 We don't check for this at the top because we want to parse
   1657  1.1  skrll 		 any trailing fake arguments in the syntax string.  */
   1658  1.1  skrll 	      if (is_end_of_line[(unsigned char) *str])
   1659  1.1  skrll 		break;
   1660  1.1  skrll 
   1661  1.1  skrll 	      /* Parse the operand.  */
   1662  1.1  skrll 	      hold = input_line_pointer;
   1663  1.1  skrll 	      input_line_pointer = str;
   1664  1.1  skrll 	      expression (&exp);
   1665  1.1  skrll 	      str = input_line_pointer;
   1666  1.1  skrll 	      input_line_pointer = hold;
   1667  1.1  skrll 
   1668  1.1  skrll 	      if (exp.X_op == O_illegal)
   1669  1.1  skrll 		as_bad (_("illegal operand"));
   1670  1.1  skrll 	      else if (exp.X_op == O_absent)
   1671  1.1  skrll 		as_bad (_("missing operand"));
   1672  1.1  skrll 	      else if (exp.X_op == O_constant)
   1673  1.1  skrll 		value = exp.X_add_number;
   1674  1.1  skrll 	      else if (exp.X_op == O_register)
   1675  1.1  skrll 		reg = (struct arc_operand_value *) exp.X_add_number;
   1676  1.1  skrll #define IS_REG_DEST_OPERAND(o) ((o) == 'a')
   1677  1.1  skrll 	      else if (IS_REG_DEST_OPERAND (*syn))
   1678  1.1  skrll 		as_bad (_("symbol as destination register"));
   1679  1.1  skrll 	      else
   1680  1.1  skrll 		{
   1681  1.1  skrll 		  if (!strncmp (str, "@h30", 4))
   1682  1.1  skrll 		    {
   1683  1.1  skrll 		      arc_code_symbol (&exp);
   1684  1.1  skrll 		      str += 4;
   1685  1.1  skrll 		    }
   1686  1.1  skrll 		  /* We need to generate a fixup for this expression.  */
   1687  1.1  skrll 		  if (fc >= MAX_FIXUPS)
   1688  1.1  skrll 		    as_fatal (_("too many fixups"));
   1689  1.1  skrll 		  fixups[fc].exp = exp;
   1690  1.1  skrll 		  /* We don't support shimm relocs. break here to force
   1691  1.1  skrll 		     the assembler to output a limm.  */
   1692  1.1  skrll #define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
   1693  1.1  skrll 		  if (IS_REG_SHIMM_OFFSET (*syn))
   1694  1.1  skrll 		    break;
   1695  1.1  skrll 		  /* If this is a register constant (IE: one whose
   1696  1.1  skrll 		     register value gets stored as 61-63) then this
   1697  1.1  skrll 		     must be a limm.  */
   1698  1.1  skrll 		  /* ??? This bit could use some cleaning up.
   1699  1.1  skrll 		     Referencing the format chars like this goes
   1700  1.1  skrll 		     against style.  */
   1701  1.1  skrll 		  if (IS_SYMBOL_OPERAND (*syn))
   1702  1.1  skrll 		    {
   1703  1.1  skrll 		      const char *junk;
   1704  1.1  skrll 		      limm_reloc_p = 1;
   1705  1.1  skrll 		      /* Save this, we don't yet know what reloc to use.  */
   1706  1.1  skrll 		      fix_up_at = fc;
   1707  1.1  skrll 		      /* Tell insert_reg we need a limm.  This is
   1708  1.1  skrll 			 needed because the value at this point is
   1709  1.1  skrll 			 zero, a shimm.  */
   1710  1.1  skrll 		      /* ??? We need a cleaner interface than this.  */
   1711  1.1  skrll 		      (*arc_operands[arc_operand_map['Q']].insert)
   1712  1.1  skrll 			(insn, operand, mods, reg, 0L, &junk);
   1713  1.1  skrll 		    }
   1714  1.1  skrll 		  else
   1715  1.1  skrll 		    fixups[fc].opindex = arc_operand_map[(int) *syn];
   1716  1.1  skrll 		  ++fc;
   1717  1.1  skrll 		  value = 0;
   1718  1.1  skrll 		}
   1719  1.1  skrll 
   1720  1.1  skrll 	      /* Insert the register or expression into the instruction.  */
   1721  1.1  skrll 	      if (operand->insert)
   1722  1.1  skrll 		{
   1723  1.1  skrll 		  const char *errmsg = NULL;
   1724  1.1  skrll 		  insn = (*operand->insert) (insn, operand, mods,
   1725  1.1  skrll 					     reg, (long) value, &errmsg);
   1726  1.1  skrll 		  if (errmsg != (const char *) NULL)
   1727  1.1  skrll 		    {
   1728  1.1  skrll 		      last_errmsg = errmsg;
   1729  1.1  skrll 		      if (operand->flags & ARC_OPERAND_ERROR)
   1730  1.1  skrll 			{
   1731  1.1  skrll 			  as_bad (errmsg);
   1732  1.1  skrll 			  return;
   1733  1.1  skrll 			}
   1734  1.1  skrll 		      else if (operand->flags & ARC_OPERAND_WARN)
   1735  1.1  skrll 			as_warn (errmsg);
   1736  1.1  skrll 		      break;
   1737  1.1  skrll 		    }
   1738  1.1  skrll 		}
   1739  1.1  skrll 	      else
   1740  1.1  skrll 		insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
   1741  1.1  skrll 
   1742  1.1  skrll 	      ++syn;
   1743  1.1  skrll 	    }
   1744  1.1  skrll 	}
   1745  1.1  skrll 
   1746  1.1  skrll       /* If we're at the end of the syntax string, we're done.  */
   1747  1.1  skrll       /* FIXME: try to move this to a separate function.  */
   1748  1.1  skrll       if (*syn == '\0')
   1749  1.1  skrll 	{
   1750  1.1  skrll 	  int i;
   1751  1.1  skrll 	  char *f;
   1752  1.1  skrll 	  long limm, limm_p;
   1753  1.1  skrll 
   1754  1.1  skrll 	  /* For the moment we assume a valid `str' can only contain blanks
   1755  1.1  skrll 	     now.  IE: We needn't try again with a longer version of the
   1756  1.1  skrll 	     insn and it is assumed that longer versions of insns appear
   1757  1.1  skrll 	     before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
   1758  1.1  skrll 
   1759  1.1  skrll 	  while (ISSPACE (*str))
   1760  1.1  skrll 	    ++str;
   1761  1.1  skrll 
   1762  1.1  skrll 	  if (!is_end_of_line[(unsigned char) *str])
   1763  1.1  skrll 	    as_bad (_("junk at end of line: `%s'"), str);
   1764  1.1  skrll 
   1765  1.1  skrll 	  /* Is there a limm value?  */
   1766  1.1  skrll 	  limm_p = arc_opcode_limm_p (&limm);
   1767  1.1  skrll 
   1768  1.1  skrll 	  /* Perform various error and warning tests.  */
   1769  1.1  skrll 
   1770  1.1  skrll 	  {
   1771  1.1  skrll 	    static int in_delay_slot_p = 0;
   1772  1.1  skrll 	    static int prev_insn_needs_cc_nop_p = 0;
   1773  1.1  skrll 	    /* delay slot type seen */
   1774  1.1  skrll 	    int delay_slot_type = ARC_DELAY_NONE;
   1775  1.1  skrll 	    /* conditional execution flag seen */
   1776  1.1  skrll 	    int conditional = 0;
   1777  1.1  skrll 	    /* 1 if condition codes are being set */
   1778  1.1  skrll 	    int cc_set_p = 0;
   1779  1.1  skrll 	    /* 1 if conditional branch, including `b' "branch always" */
   1780  1.1  skrll 	    int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
   1781  1.1  skrll 
   1782  1.1  skrll 	    for (i = 0; i < num_suffixes; ++i)
   1783  1.1  skrll 	      {
   1784  1.1  skrll 		switch (arc_operands[insn_suffixes[i]->type].fmt)
   1785  1.1  skrll 		  {
   1786  1.1  skrll 		  case 'n':
   1787  1.1  skrll 		    delay_slot_type = insn_suffixes[i]->value;
   1788  1.1  skrll 		    break;
   1789  1.1  skrll 		  case 'q':
   1790  1.1  skrll 		    conditional = insn_suffixes[i]->value;
   1791  1.1  skrll 		    break;
   1792  1.1  skrll 		  case 'f':
   1793  1.1  skrll 		    cc_set_p = 1;
   1794  1.1  skrll 		    break;
   1795  1.1  skrll 		  }
   1796  1.1  skrll 	      }
   1797  1.1  skrll 
   1798  1.1  skrll 	    /* Putting an insn with a limm value in a delay slot is supposed to
   1799  1.1  skrll 	       be legal, but let's warn the user anyway.  Ditto for 8 byte
   1800  1.1  skrll 	       jumps with delay slots.  */
   1801  1.1  skrll 	    if (in_delay_slot_p && limm_p)
   1802  1.1  skrll 	      as_warn (_("8 byte instruction in delay slot"));
   1803  1.1  skrll 	    if (delay_slot_type != ARC_DELAY_NONE
   1804  1.1  skrll 		&& limm_p && arc_insn_not_jl (insn)) /* except for jl  addr */
   1805  1.1  skrll 	      as_warn (_("8 byte jump instruction with delay slot"));
   1806  1.1  skrll 	    in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
   1807  1.1  skrll 
   1808  1.1  skrll 	    /* Warn when a conditional branch immediately follows a set of
   1809  1.1  skrll 	       the condition codes.  Note that this needn't be done if the
   1810  1.1  skrll 	       insn that sets the condition codes uses a limm.  */
   1811  1.1  skrll 	    if (cond_branch_p && conditional != 0 /* 0 = "always" */
   1812  1.1  skrll 		&& prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
   1813  1.1  skrll 	      as_warn (_("conditional branch follows set of flags"));
   1814  1.1  skrll 	    prev_insn_needs_cc_nop_p =
   1815  1.1  skrll 	      /* FIXME: ??? not required:
   1816  1.1  skrll 		 (delay_slot_type != ARC_DELAY_NONE) &&  */
   1817  1.1  skrll 	      cc_set_p && !limm_p;
   1818  1.1  skrll 	  }
   1819  1.1  skrll 
   1820  1.1  skrll 	  /* Write out the instruction.
   1821  1.1  skrll 	     It is important to fetch enough space in one call to `frag_more'.
   1822  1.1  skrll 	     We use (f - frag_now->fr_literal) to compute where we are and we
   1823  1.1  skrll 	     don't want frag_now to change between calls.  */
   1824  1.1  skrll 	  if (limm_p)
   1825  1.1  skrll 	    {
   1826  1.1  skrll 	      f = frag_more (8);
   1827  1.1  skrll 	      md_number_to_chars (f, insn, 4);
   1828  1.1  skrll 	      md_number_to_chars (f + 4, limm, 4);
   1829  1.1  skrll 	      dwarf2_emit_insn (8);
   1830  1.1  skrll 	    }
   1831  1.1  skrll 	  else if (limm_reloc_p)
   1832  1.1  skrll 	    /* We need a limm reloc, but the tables think we don't.  */
   1833  1.1  skrll 	    abort ();
   1834  1.1  skrll 	  else
   1835  1.1  skrll 	    {
   1836  1.1  skrll 	      f = frag_more (4);
   1837  1.1  skrll 	      md_number_to_chars (f, insn, 4);
   1838  1.1  skrll 	      dwarf2_emit_insn (4);
   1839  1.1  skrll 	    }
   1840  1.1  skrll 
   1841  1.1  skrll 	  /* Create any fixups.  */
   1842  1.1  skrll 	  for (i = 0; i < fc; ++i)
   1843  1.1  skrll 	    {
   1844  1.1  skrll 	      int op_type, reloc_type;
   1845  1.1  skrll 	      expressionS exptmp;
   1846  1.1  skrll 	      const struct arc_operand *operand;
   1847  1.1  skrll 
   1848  1.1  skrll 	      /* Create a fixup for this operand.
   1849  1.1  skrll 		 At this point we do not use a bfd_reloc_code_real_type for
   1850  1.1  skrll 		 operands residing in the insn, but instead just use the
   1851  1.1  skrll 		 operand index.  This lets us easily handle fixups for any
   1852  1.1  skrll 		 operand type, although that is admittedly not a very exciting
   1853  1.1  skrll 		 feature.  We pick a BFD reloc type in md_apply_fix.
   1854  1.1  skrll 
   1855  1.1  skrll 		 Limm values (4 byte immediate "constants") must be treated
   1856  1.1  skrll 		 normally because they're not part of the actual insn word
   1857  1.1  skrll 		 and thus the insertion routines don't handle them.  */
   1858  1.1  skrll 
   1859  1.1  skrll 	      if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
   1860  1.1  skrll 		{
   1861  1.1  skrll 		  /* Modify the fixup addend as required by the cpu.  */
   1862  1.1  skrll 		  fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
   1863  1.1  skrll 		  op_type = fixups[i].opindex;
   1864  1.1  skrll 		  /* FIXME: can we add this data to the operand table?  */
   1865  1.1  skrll 		  if (op_type == arc_operand_map['L']
   1866  1.1  skrll 		      || op_type == arc_operand_map['s']
   1867  1.1  skrll 		      || op_type == arc_operand_map['o']
   1868  1.1  skrll 		      || op_type == arc_operand_map['O'])
   1869  1.1  skrll 		    reloc_type = BFD_RELOC_32;
   1870  1.1  skrll 		  else if (op_type == arc_operand_map['J'])
   1871  1.1  skrll 		    reloc_type = BFD_RELOC_ARC_B26;
   1872  1.1  skrll 		  else
   1873  1.1  skrll 		    abort ();
   1874  1.1  skrll 		  reloc_type = get_arc_exp_reloc_type (1, reloc_type,
   1875  1.1  skrll 						       &fixups[i].exp,
   1876  1.1  skrll 						       &exptmp);
   1877  1.1  skrll 		}
   1878  1.1  skrll 	      else
   1879  1.1  skrll 		{
   1880  1.1  skrll 		  op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
   1881  1.1  skrll 						    &fixups[i].exp, &exptmp);
   1882  1.1  skrll 		  reloc_type = op_type + (int) BFD_RELOC_UNUSED;
   1883  1.1  skrll 		}
   1884  1.1  skrll 	      operand = &arc_operands[op_type];
   1885  1.1  skrll 	      fix_new_exp (frag_now,
   1886  1.1  skrll 			   ((f - frag_now->fr_literal)
   1887  1.1  skrll 			    + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
   1888  1.1  skrll 			   &exptmp,
   1889  1.1  skrll 			   (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
   1890  1.1  skrll 			   (bfd_reloc_code_real_type) reloc_type);
   1891  1.1  skrll 	    }
   1892  1.1  skrll 	  return;
   1893  1.1  skrll 	}
   1894                 }
   1895             
   1896               if (NULL == last_errmsg)
   1897                 as_bad (_("bad instruction `%s'"), start);
   1898               else
   1899                 as_bad (last_errmsg);
   1900             }
   1901