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