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