Back to index

cell-binutils  2.17cvs20070401
tc-arc.c
Go to the documentation of this file.
00001 /* tc-arc.c -- Assembler for the ARC
00002    Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00003    2006  Free Software Foundation, Inc.
00004    Contributed by Doug Evans (dje@cygnus.com).
00005 
00006    This file is part of GAS, the GNU Assembler.
00007 
00008    GAS is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    GAS is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with GAS; see the file COPYING.  If not, write to the Free
00020    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00021    02110-1301, USA.  */
00022 
00023 #include "as.h"
00024 #include "struc-symbol.h"
00025 #include "safe-ctype.h"
00026 #include "subsegs.h"
00027 #include "opcode/arc.h"
00028 #include "../opcodes/arc-ext.h"
00029 #include "elf/arc.h"
00030 #include "dwarf2dbg.h"
00031 
00032 const struct suffix_classes
00033 {
00034   char *name;
00035   int  len;
00036 } suffixclass[] =
00037 {
00038   { "SUFFIX_COND|SUFFIX_FLAG",23 },
00039   { "SUFFIX_FLAG", 11 },
00040   { "SUFFIX_COND", 11 },
00041   { "SUFFIX_NONE", 11 }
00042 };
00043 
00044 #define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
00045 
00046 const struct syntax_classes
00047 {
00048   char *name;
00049   int  len;
00050   int  class;
00051 } syntaxclass[] =
00052 {
00053   { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
00054   { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
00055   { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
00056   { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
00057   { "SYNTAX_3OP",                 10, SYNTAX_3OP|SYNTAX_VALID },
00058   { "SYNTAX_2OP",                 10, SYNTAX_2OP|SYNTAX_VALID }
00059 };
00060 
00061 #define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
00062 
00063 /* This array holds the chars that always start a comment.  If the
00064    pre-processor is disabled, these aren't very useful.  */
00065 const char comment_chars[] = "#;";
00066 
00067 /* This array holds the chars that only start a comment at the beginning of
00068    a line.  If the line seems to have the form '# 123 filename'
00069    .line and .file directives will appear in the pre-processed output */
00070 /* Note that input_file.c hand checks for '#' at the beginning of the
00071    first line of the input file.  This is because the compiler outputs
00072    #NO_APP at the beginning of its output.  */
00073 /* Also note that comments started like this one will always
00074    work if '/' isn't otherwise defined.  */
00075 const char line_comment_chars[] = "#";
00076 
00077 const char line_separator_chars[] = "";
00078 
00079 /* Chars that can be used to separate mant from exp in floating point nums.  */
00080 const char EXP_CHARS[] = "eE";
00081 
00082 /* Chars that mean this number is a floating point constant
00083    As in 0f12.456 or 0d1.2345e12.  */
00084 const char FLT_CHARS[] = "rRsSfFdD";
00085 
00086 /* Byte order.  */
00087 extern int target_big_endian;
00088 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
00089 static int byte_order = DEFAULT_BYTE_ORDER;
00090 
00091 static segT arcext_section;
00092 
00093 /* One of bfd_mach_arc_n.  */
00094 static int arc_mach_type = bfd_mach_arc_6;
00095 
00096 /* Non-zero if the cpu type has been explicitly specified.  */
00097 static int mach_type_specified_p = 0;
00098 
00099 /* Non-zero if opcode tables have been initialized.
00100    A .option command must appear before any instructions.  */
00101 static int cpu_tables_init_p = 0;
00102 
00103 static struct hash_control *arc_suffix_hash = NULL;
00104 
00105 const char *md_shortopts = "";
00106 
00107 enum options
00108 {
00109   OPTION_EB = OPTION_MD_BASE,
00110   OPTION_EL,
00111   OPTION_ARC5,
00112   OPTION_ARC6,
00113   OPTION_ARC7,
00114   OPTION_ARC8,
00115   OPTION_ARC
00116 };
00117 
00118 struct option md_longopts[] =
00119 {
00120   { "EB", no_argument, NULL, OPTION_EB },
00121   { "EL", no_argument, NULL, OPTION_EL },
00122   { "marc5", no_argument, NULL, OPTION_ARC5 },
00123   { "pre-v6", no_argument, NULL, OPTION_ARC5 },
00124   { "marc6", no_argument, NULL, OPTION_ARC6 },
00125   { "marc7", no_argument, NULL, OPTION_ARC7 },
00126   { "marc8", no_argument, NULL, OPTION_ARC8 },
00127   { "marc", no_argument, NULL, OPTION_ARC },
00128   { NULL, no_argument, NULL, 0 }
00129 };
00130 size_t md_longopts_size = sizeof (md_longopts);
00131 
00132 #define IS_SYMBOL_OPERAND(o) \
00133  ((o) == 'b' || (o) == 'c' || (o) == 's' || (o) == 'o' || (o) == 'O')
00134 
00135 struct arc_operand_value *get_ext_suffix (char *s);
00136 
00137 /* Invocation line includes a switch not recognized by the base assembler.
00138    See if it's a processor-specific option.  */
00139 
00140 int
00141 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
00142 {
00143   switch (c)
00144     {
00145     case OPTION_ARC5:
00146       arc_mach_type = bfd_mach_arc_5;
00147       break;
00148     case OPTION_ARC:
00149     case OPTION_ARC6:
00150       arc_mach_type = bfd_mach_arc_6;
00151       break;
00152     case OPTION_ARC7:
00153       arc_mach_type = bfd_mach_arc_7;
00154       break;
00155     case OPTION_ARC8:
00156       arc_mach_type = bfd_mach_arc_8;
00157       break;
00158     case OPTION_EB:
00159       byte_order = BIG_ENDIAN;
00160       arc_target_format = "elf32-bigarc";
00161       break;
00162     case OPTION_EL:
00163       byte_order = LITTLE_ENDIAN;
00164       arc_target_format = "elf32-littlearc";
00165       break;
00166     default:
00167       return 0;
00168     }
00169   return 1;
00170 }
00171 
00172 void
00173 md_show_usage (FILE *stream)
00174 {
00175   fprintf (stream, "\
00176 ARC Options:\n\
00177   -marc[5|6|7|8]          select processor variant (default arc%d)\n\
00178   -EB                     assemble code for a big endian cpu\n\
00179   -EL                     assemble code for a little endian cpu\n", arc_mach_type + 5);
00180 }
00181 
00182 /* This function is called once, at assembler startup time.  It should
00183    set up all the tables, etc. that the MD part of the assembler will need.
00184    Opcode selection is deferred until later because we might see a .option
00185    command.  */
00186 
00187 void
00188 md_begin (void)
00189 {
00190   /* The endianness can be chosen "at the factory".  */
00191   target_big_endian = byte_order == BIG_ENDIAN;
00192 
00193   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
00194     as_warn ("could not set architecture and machine");
00195 
00196   /* This call is necessary because we need to initialize `arc_operand_map'
00197      which may be needed before we see the first insn.  */
00198   arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
00199                                           target_big_endian));
00200 }
00201 
00202 /* Initialize the various opcode and operand tables.
00203    MACH is one of bfd_mach_arc_xxx.  */
00204 
00205 static void
00206 init_opcode_tables (int mach)
00207 {
00208   int i;
00209   char *last;
00210 
00211   if ((arc_suffix_hash = hash_new ()) == NULL)
00212     as_fatal ("virtual memory exhausted");
00213 
00214   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
00215     as_warn ("could not set architecture and machine");
00216 
00217   /* This initializes a few things in arc-opc.c that we need.
00218      This must be called before the various arc_xxx_supported fns.  */
00219   arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
00220 
00221   /* Only put the first entry of each equivalently named suffix in the
00222      table.  */
00223   last = "";
00224   for (i = 0; i < arc_suffixes_count; i++)
00225     {
00226       if (strcmp (arc_suffixes[i].name, last) != 0)
00227        hash_insert (arc_suffix_hash, arc_suffixes[i].name, (void *) (arc_suffixes + i));
00228       last = arc_suffixes[i].name;
00229     }
00230 
00231   /* Since registers don't have a prefix, we put them in the symbol table so
00232      they can't be used as symbols.  This also simplifies argument parsing as
00233      we can let gas parse registers for us.  The recorded register number is
00234      the address of the register's entry in arc_reg_names.
00235 
00236      If the register name is already in the table, then the existing
00237      definition is assumed to be from an .ExtCoreRegister pseudo-op.  */
00238 
00239   for (i = 0; i < arc_reg_names_count; i++)
00240     {
00241       if (symbol_find (arc_reg_names[i].name))
00242        continue;
00243       /* Use symbol_create here instead of symbol_new so we don't try to
00244         output registers into the object file's symbol table.  */
00245       symbol_table_insert (symbol_create (arc_reg_names[i].name,
00246                                      reg_section,
00247                                      (valueT) &arc_reg_names[i],
00248                                      &zero_address_frag));
00249     }
00250 
00251   /* Tell `.option' it's too late.  */
00252   cpu_tables_init_p = 1;
00253 }
00254 
00255 /* Insert an operand value into an instruction.
00256    If REG is non-NULL, it is a register number and ignore VAL.  */
00257 
00258 static arc_insn
00259 arc_insert_operand (arc_insn insn,
00260                   const struct arc_operand *operand,
00261                   int mods,
00262                   const struct arc_operand_value *reg,
00263                   offsetT val,
00264                   char *file,
00265                   unsigned int line)
00266 {
00267   if (operand->bits != 32)
00268     {
00269       long min, max;
00270       offsetT test;
00271 
00272       if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
00273        {
00274          if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
00275            max = (1 << operand->bits) - 1;
00276          else
00277            max = (1 << (operand->bits - 1)) - 1;
00278          min = - (1 << (operand->bits - 1));
00279        }
00280       else
00281        {
00282          max = (1 << operand->bits) - 1;
00283          min = 0;
00284        }
00285 
00286       if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
00287        test = - val;
00288       else
00289        test = val;
00290 
00291       if (test < (offsetT) min || test > (offsetT) max)
00292        as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
00293     }
00294 
00295   if (operand->insert)
00296     {
00297       const char *errmsg;
00298 
00299       errmsg = NULL;
00300       insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
00301       if (errmsg != (const char *) NULL)
00302        as_warn (errmsg);
00303     }
00304   else
00305     insn |= (((long) val & ((1 << operand->bits) - 1))
00306             << operand->shift);
00307 
00308   return insn;
00309 }
00310 
00311 /* We need to keep a list of fixups.  We can't simply generate them as
00312    we go, because that would require us to first create the frag, and
00313    that would screw up references to ``.''.  */
00314 
00315 struct arc_fixup
00316 {
00317   /* index into `arc_operands'  */
00318   int opindex;
00319   expressionS exp;
00320 };
00321 
00322 #define MAX_FIXUPS 5
00323 
00324 #define MAX_SUFFIXES 5
00325 
00326 /* Compute the reloc type of an expression.
00327    The possibly modified expression is stored in EXPNEW.
00328 
00329    This is used to convert the expressions generated by the %-op's into
00330    the appropriate operand type.  It is called for both data in instructions
00331    (operands) and data outside instructions (variables, debugging info, etc.).
00332 
00333    Currently supported %-ops:
00334 
00335    %st(symbol): represented as "symbol >> 2"
00336                 "st" is short for STatus as in the status register (pc)
00337 
00338    DEFAULT_TYPE is the type to use if no special processing is required.
00339 
00340    DATA_P is non-zero for data or limm values, zero for insn operands.
00341    Remember that the opcode "insertion fns" cannot be used on data, they're
00342    only for inserting operands into insns.  They also can't be used for limm
00343    values as the insertion routines don't handle limm values.  When called for
00344    insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED).  When
00345    called for data or limm values we use real reloc types.  */
00346 
00347 static int
00348 get_arc_exp_reloc_type (int data_p,
00349                      int default_type,
00350                      expressionS *exp,
00351                      expressionS *expnew)
00352 {
00353   /* If the expression is "symbol >> 2" we must change it to just "symbol",
00354      as fix_new_exp can't handle it.  Similarly for (symbol - symbol) >> 2.
00355      That's ok though.  What's really going on here is that we're using
00356      ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26.  */
00357 
00358   if (exp->X_op == O_right_shift
00359       && exp->X_op_symbol != NULL
00360       && exp->X_op_symbol->sy_value.X_op == O_constant
00361       && exp->X_op_symbol->sy_value.X_add_number == 2
00362       && exp->X_add_number == 0)
00363     {
00364       if (exp->X_add_symbol != NULL
00365          && (exp->X_add_symbol->sy_value.X_op == O_constant
00366              || exp->X_add_symbol->sy_value.X_op == O_symbol))
00367        {
00368          *expnew = *exp;
00369          expnew->X_op = O_symbol;
00370          expnew->X_op_symbol = NULL;
00371          return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
00372        }
00373       else if (exp->X_add_symbol != NULL
00374               && exp->X_add_symbol->sy_value.X_op == O_subtract)
00375        {
00376          *expnew = exp->X_add_symbol->sy_value;
00377          return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
00378        }
00379     }
00380 
00381   *expnew = *exp;
00382   return default_type;
00383 }
00384 
00385 static int
00386 arc_set_ext_seg (void)
00387 {
00388   if (!arcext_section)
00389     {
00390       arcext_section = subseg_new (".arcextmap", 0);
00391       bfd_set_section_flags (stdoutput, arcext_section,
00392                           SEC_READONLY | SEC_HAS_CONTENTS);
00393     }
00394   else
00395     subseg_set (arcext_section, 0);
00396   return 1;
00397 }
00398 
00399 static void
00400 arc_extoper (int opertype)
00401 {
00402   char *name;
00403   char *mode;
00404   char c;
00405   char *p;
00406   int imode = 0;
00407   int number;
00408   struct arc_ext_operand_value *ext_oper;
00409   symbolS *symbolP;
00410 
00411   segT old_sec;
00412   int old_subsec;
00413 
00414   name = input_line_pointer;
00415   c = get_symbol_end ();
00416   name = xstrdup (name);
00417 
00418   p = name;
00419   while (*p)
00420     {
00421       *p = TOLOWER (*p);
00422       p++;
00423     }
00424 
00425   /* just after name is now '\0'  */
00426   p = input_line_pointer;
00427   *p = c;
00428   SKIP_WHITESPACE ();
00429 
00430   if (*input_line_pointer != ',')
00431     {
00432       as_bad ("expected comma after operand name");
00433       ignore_rest_of_line ();
00434       free (name);
00435       return;
00436     }
00437 
00438   input_line_pointer++;            /* skip ','  */
00439   number = get_absolute_expression ();
00440 
00441   if (number < 0)
00442     {
00443       as_bad ("negative operand number %d", number);
00444       ignore_rest_of_line ();
00445       free (name);
00446       return;
00447     }
00448 
00449   if (opertype)
00450     {
00451       SKIP_WHITESPACE ();
00452 
00453       if (*input_line_pointer != ',')
00454        {
00455          as_bad ("expected comma after register-number");
00456          ignore_rest_of_line ();
00457          free (name);
00458          return;
00459        }
00460 
00461       input_line_pointer++;        /* skip ','  */
00462       mode = input_line_pointer;
00463 
00464       if (!strncmp (mode, "r|w", 3))
00465        {
00466          imode = 0;
00467          input_line_pointer += 3;
00468        }
00469       else
00470        {
00471          if (!strncmp (mode, "r", 1))
00472            {
00473              imode = ARC_REGISTER_READONLY;
00474              input_line_pointer += 1;
00475            }
00476          else
00477            {
00478              if (strncmp (mode, "w", 1))
00479               {
00480                 as_bad ("invalid mode");
00481                 ignore_rest_of_line ();
00482                 free (name);
00483                 return;
00484               }
00485              else
00486               {
00487                 imode = ARC_REGISTER_WRITEONLY;
00488                 input_line_pointer += 1;
00489               }
00490            }
00491        }
00492       SKIP_WHITESPACE ();
00493       if (1 == opertype)
00494        {
00495          if (*input_line_pointer != ',')
00496            {
00497              as_bad ("expected comma after register-mode");
00498              ignore_rest_of_line ();
00499              free (name);
00500              return;
00501            }
00502 
00503          input_line_pointer++;            /* skip ','  */
00504 
00505          if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
00506            {
00507              imode |= arc_get_noshortcut_flag ();
00508              input_line_pointer += 15;
00509            }
00510          else
00511            {
00512              if (strncmp (input_line_pointer, "can_shortcut", 12))
00513               {
00514                 as_bad ("shortcut designator invalid");
00515                 ignore_rest_of_line ();
00516                 free (name);
00517                 return;
00518               }
00519              else
00520               {
00521                 input_line_pointer += 12;
00522               }
00523            }
00524        }
00525     }
00526 
00527   if ((opertype == 1) && number > 60)
00528     {
00529       as_bad ("core register value (%d) too large", number);
00530       ignore_rest_of_line ();
00531       free (name);
00532       return;
00533     }
00534 
00535   if ((opertype == 0) && number > 31)
00536     {
00537       as_bad ("condition code value (%d) too large", number);
00538       ignore_rest_of_line ();
00539       free (name);
00540       return;
00541     }
00542 
00543   ext_oper = xmalloc (sizeof (struct arc_ext_operand_value));
00544 
00545   if (opertype)
00546     {
00547       /* If the symbol already exists, point it at the new definition.  */
00548       if ((symbolP = symbol_find (name)))
00549        {
00550          if (S_GET_SEGMENT (symbolP) == reg_section)
00551            S_SET_VALUE (symbolP, (valueT) &ext_oper->operand);
00552          else
00553            {
00554              as_bad ("attempt to override symbol: %s", name);
00555              ignore_rest_of_line ();
00556              free (name);
00557              free (ext_oper);
00558              return;
00559            }
00560        }
00561       else
00562        {
00563          /* If its not there, add it.  */
00564          symbol_table_insert (symbol_create (name, reg_section,
00565                                          (valueT) &ext_oper->operand,
00566                                          &zero_address_frag));
00567        }
00568     }
00569 
00570   ext_oper->operand.name  = name;
00571   ext_oper->operand.value = number;
00572   ext_oper->operand.type  = arc_operand_type (opertype);
00573   ext_oper->operand.flags = imode;
00574 
00575   ext_oper->next = arc_ext_operands;
00576   arc_ext_operands = ext_oper;
00577 
00578   /* OK, now that we know what this operand is, put a description in
00579      the arc extension section of the output file.  */
00580 
00581   old_sec    = now_seg;
00582   old_subsec = now_subseg;
00583 
00584   arc_set_ext_seg ();
00585 
00586   switch (opertype)
00587     {
00588     case 0:
00589       p = frag_more (1);
00590       *p = 3 + strlen (name) + 1;
00591       p = frag_more (1);
00592       *p = EXT_COND_CODE;
00593       p = frag_more (1);
00594       *p = number;
00595       p = frag_more (strlen (name) + 1);
00596       strcpy (p, name);
00597       break;
00598     case 1:
00599       p = frag_more (1);
00600       *p = 3 + strlen (name) + 1;
00601       p = frag_more (1);
00602       *p = EXT_CORE_REGISTER;
00603       p = frag_more (1);
00604       *p = number;
00605       p = frag_more (strlen (name) + 1);
00606       strcpy (p, name);
00607       break;
00608     case 2:
00609       p = frag_more (1);
00610       *p = 6 + strlen (name) + 1;
00611       p = frag_more (1);
00612       *p = EXT_AUX_REGISTER;
00613       p = frag_more (1);
00614       *p = number >> 24 & 0xff;
00615       p = frag_more (1);
00616       *p = number >> 16 & 0xff;
00617       p = frag_more (1);
00618       *p = number >>  8 & 0xff;
00619       p = frag_more (1);
00620       *p = number       & 0xff;
00621       p = frag_more (strlen (name) + 1);
00622       strcpy (p, name);
00623       break;
00624     default:
00625       as_bad ("invalid opertype");
00626       ignore_rest_of_line ();
00627       free (name);
00628       return;
00629       break;
00630     }
00631 
00632   subseg_set (old_sec, old_subsec);
00633 
00634   /* Enter all registers into the symbol table.  */
00635 
00636   demand_empty_rest_of_line ();
00637 }
00638 
00639 static void
00640 arc_extinst (int ignore ATTRIBUTE_UNUSED)
00641 {
00642   char syntax[129];
00643   char *name;
00644   char *p;
00645   char c;
00646   int suffixcode = -1;
00647   int opcode, subopcode;
00648   int i;
00649   int class = 0;
00650   int name_len;
00651   struct arc_opcode *ext_op;
00652 
00653   segT old_sec;
00654   int old_subsec;
00655 
00656   name = input_line_pointer;
00657   c = get_symbol_end ();
00658   name = xstrdup (name);
00659   strcpy (syntax, name);
00660   name_len = strlen (name);
00661 
00662   /* just after name is now '\0'  */
00663   p = input_line_pointer;
00664   *p = c;
00665 
00666   SKIP_WHITESPACE ();
00667 
00668   if (*input_line_pointer != ',')
00669     {
00670       as_bad ("expected comma after operand name");
00671       ignore_rest_of_line ();
00672       return;
00673     }
00674 
00675   input_line_pointer++;            /* skip ','  */
00676   opcode = get_absolute_expression ();
00677 
00678   SKIP_WHITESPACE ();
00679 
00680   if (*input_line_pointer != ',')
00681     {
00682       as_bad ("expected comma after opcode");
00683       ignore_rest_of_line ();
00684       return;
00685     }
00686 
00687   input_line_pointer++;            /* skip ','  */
00688   subopcode = get_absolute_expression ();
00689 
00690   if (subopcode < 0)
00691     {
00692       as_bad ("negative subopcode %d", subopcode);
00693       ignore_rest_of_line ();
00694       return;
00695     }
00696 
00697   if (subopcode)
00698     {
00699       if (3 != opcode)
00700        {
00701          as_bad ("subcode value found when opcode not equal 0x03");
00702          ignore_rest_of_line ();
00703          return;
00704        }
00705       else
00706        {
00707          if (subopcode < 0x09 || subopcode == 0x3f)
00708            {
00709              as_bad ("invalid subopcode %d", subopcode);
00710              ignore_rest_of_line ();
00711              return;
00712            }
00713        }
00714     }
00715 
00716   SKIP_WHITESPACE ();
00717 
00718   if (*input_line_pointer != ',')
00719     {
00720       as_bad ("expected comma after subopcode");
00721       ignore_rest_of_line ();
00722       return;
00723     }
00724 
00725   input_line_pointer++;            /* skip ','  */
00726 
00727   for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
00728     {
00729       if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
00730        {
00731          suffixcode = i;
00732          input_line_pointer += suffixclass[i].len;
00733          break;
00734        }
00735     }
00736 
00737   if (-1 == suffixcode)
00738     {
00739       as_bad ("invalid suffix class");
00740       ignore_rest_of_line ();
00741       return;
00742     }
00743 
00744   SKIP_WHITESPACE ();
00745 
00746   if (*input_line_pointer != ',')
00747     {
00748       as_bad ("expected comma after suffix class");
00749       ignore_rest_of_line ();
00750       return;
00751     }
00752 
00753   input_line_pointer++;            /* skip ','  */
00754 
00755   for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
00756     {
00757       if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
00758        {
00759          class = syntaxclass[i].class;
00760          input_line_pointer += syntaxclass[i].len;
00761          break;
00762        }
00763     }
00764 
00765   if (0 == (SYNTAX_VALID & class))
00766     {
00767       as_bad ("invalid syntax class");
00768       ignore_rest_of_line ();
00769       return;
00770     }
00771 
00772   if ((0x3 == opcode) & (class & SYNTAX_3OP))
00773     {
00774       as_bad ("opcode 0x3 and SYNTAX_3OP invalid");
00775       ignore_rest_of_line ();
00776       return;
00777     }
00778 
00779   switch (suffixcode)
00780     {
00781     case 0:
00782       strcat (syntax, "%.q%.f ");
00783       break;
00784     case 1:
00785       strcat (syntax, "%.f ");
00786       break;
00787     case 2:
00788       strcat (syntax, "%.q ");
00789       break;
00790     case 3:
00791       strcat (syntax, " ");
00792       break;
00793     default:
00794       as_bad ("unknown suffix class");
00795       ignore_rest_of_line ();
00796       return;
00797       break;
00798     };
00799 
00800   strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
00801   if (suffixcode < 2)
00802     strcat (syntax, "%F");
00803   strcat (syntax, "%S%L");
00804 
00805   ext_op = xmalloc (sizeof (struct arc_opcode));
00806   ext_op->syntax = xstrdup (syntax);
00807 
00808   ext_op->mask  = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
00809   ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
00810   ext_op->flags = class;
00811   ext_op->next_asm = arc_ext_opcodes;
00812   ext_op->next_dis = arc_ext_opcodes;
00813   arc_ext_opcodes = ext_op;
00814 
00815   /* OK, now that we know what this inst is, put a description in the
00816      arc extension section of the output file.  */
00817 
00818   old_sec    = now_seg;
00819   old_subsec = now_subseg;
00820 
00821   arc_set_ext_seg ();
00822 
00823   p = frag_more (1);
00824   *p = 5 + name_len + 1;
00825   p = frag_more (1);
00826   *p = EXT_INSTRUCTION;
00827   p = frag_more (1);
00828   *p = opcode;
00829   p = frag_more (1);
00830   *p = subopcode;
00831   p = frag_more (1);
00832   *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
00833   p = frag_more (name_len);
00834   strncpy (p, syntax, name_len);
00835   p = frag_more (1);
00836   *p = '\0';
00837 
00838   subseg_set (old_sec, old_subsec);
00839 
00840   demand_empty_rest_of_line ();
00841 }
00842 
00843 static void
00844 arc_common (int localScope)
00845 {
00846   char *name;
00847   char c;
00848   char *p;
00849   int align, size;
00850   symbolS *symbolP;
00851 
00852   name = input_line_pointer;
00853   c = get_symbol_end ();
00854   /* just after name is now '\0'  */
00855   p = input_line_pointer;
00856   *p = c;
00857   SKIP_WHITESPACE ();
00858 
00859   if (*input_line_pointer != ',')
00860     {
00861       as_bad ("expected comma after symbol name");
00862       ignore_rest_of_line ();
00863       return;
00864     }
00865 
00866   input_line_pointer++;            /* skip ','  */
00867   size = get_absolute_expression ();
00868 
00869   if (size < 0)
00870     {
00871       as_bad ("negative symbol length");
00872       ignore_rest_of_line ();
00873       return;
00874     }
00875 
00876   *p = 0;
00877   symbolP = symbol_find_or_make (name);
00878   *p = c;
00879 
00880   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
00881     {
00882       as_bad ("ignoring attempt to re-define symbol");
00883       ignore_rest_of_line ();
00884       return;
00885     }
00886   if (((int) S_GET_VALUE (symbolP) != 0) \
00887       && ((int) S_GET_VALUE (symbolP) != size))
00888     {
00889       as_warn ("length of symbol \"%s\" already %ld, ignoring %d",
00890               S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
00891     }
00892   assert (symbolP->sy_frag == &zero_address_frag);
00893 
00894   /* Now parse the alignment field.  This field is optional for
00895      local and global symbols. Default alignment is zero.  */
00896   if (*input_line_pointer == ',')
00897     {
00898       input_line_pointer++;
00899       align = get_absolute_expression ();
00900       if (align < 0)
00901        {
00902          align = 0;
00903          as_warn ("assuming symbol alignment of zero");
00904        }
00905     }
00906   else
00907     align = 0;
00908 
00909   if (localScope != 0)
00910     {
00911       segT old_sec;
00912       int old_subsec;
00913       char *pfrag;
00914 
00915       old_sec    = now_seg;
00916       old_subsec = now_subseg;
00917       record_alignment (bss_section, align);
00918       subseg_set (bss_section, 0);  /* ??? subseg_set (bss_section, 1); ???  */
00919 
00920       if (align)
00921        /* Do alignment.  */
00922        frag_align (align, 0, 0);
00923 
00924       /* Detach from old frag.  */
00925       if (S_GET_SEGMENT (symbolP) == bss_section)
00926        symbolP->sy_frag->fr_symbol = NULL;
00927 
00928       symbolP->sy_frag = frag_now;
00929       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
00930                      (offsetT) size, (char *) 0);
00931       *pfrag = 0;
00932 
00933       S_SET_SIZE       (symbolP, size);
00934       S_SET_SEGMENT    (symbolP, bss_section);
00935       S_CLEAR_EXTERNAL (symbolP);
00936       symbolP->local = 1;
00937       subseg_set (old_sec, old_subsec);
00938     }
00939   else
00940     {
00941       S_SET_VALUE    (symbolP, (valueT) size);
00942       S_SET_ALIGN    (symbolP, align);
00943       S_SET_EXTERNAL (symbolP);
00944       S_SET_SEGMENT  (symbolP, bfd_com_section_ptr);
00945     }
00946 
00947   symbolP->bsym->flags |= BSF_OBJECT;
00948 
00949   demand_empty_rest_of_line ();
00950 }
00951 
00952 /* Select the cpu we're assembling for.  */
00953 
00954 static void
00955 arc_option (int ignore ATTRIBUTE_UNUSED)
00956 {
00957   extern int arc_get_mach (char *);
00958   int mach;
00959   char c;
00960   char *cpu;
00961 
00962   cpu = input_line_pointer;
00963   c = get_symbol_end ();
00964   mach = arc_get_mach (cpu);
00965   *input_line_pointer = c;
00966 
00967   /* If an instruction has already been seen, it's too late.  */
00968   if (cpu_tables_init_p)
00969     {
00970       as_bad ("\".option\" directive must appear before any instructions");
00971       ignore_rest_of_line ();
00972       return;
00973     }
00974 
00975   if (mach == -1)
00976     goto bad_cpu;
00977 
00978   if (mach_type_specified_p && mach != arc_mach_type)
00979     {
00980       as_bad ("\".option\" directive conflicts with initial definition");
00981       ignore_rest_of_line ();
00982       return;
00983     }
00984   else
00985     {
00986       /* The cpu may have been selected on the command line.  */
00987       if (mach != arc_mach_type)
00988        as_warn ("\".option\" directive overrides command-line (default) value");
00989       arc_mach_type = mach;
00990       if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
00991        as_fatal ("could not set architecture and machine");
00992       mach_type_specified_p = 1;
00993     }
00994   demand_empty_rest_of_line ();
00995   return;
00996 
00997  bad_cpu:
00998   as_bad ("invalid identifier for \".option\"");
00999   ignore_rest_of_line ();
01000 }
01001 
01002 /* Turn a string in input_line_pointer into a floating point constant
01003    of type TYPE, and store the appropriate bytes in *LITP.  The number
01004    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
01005    returned, or NULL on OK.  */
01006 
01007 /* Equal to MAX_PRECISION in atof-ieee.c  */
01008 #define MAX_LITTLENUMS 6
01009 
01010 char *
01011 md_atof (int type, char *litP, int *sizeP)
01012 {
01013   int prec;
01014   LITTLENUM_TYPE words[MAX_LITTLENUMS];
01015   LITTLENUM_TYPE *wordP;
01016   char *t;
01017 
01018   switch (type)
01019     {
01020     case 'f':
01021     case 'F':
01022       prec = 2;
01023       break;
01024 
01025     case 'd':
01026     case 'D':
01027       prec = 4;
01028       break;
01029 
01030     default:
01031       *sizeP = 0;
01032       return "bad call to md_atof";
01033     }
01034 
01035   t = atof_ieee (input_line_pointer, type, words);
01036   if (t)
01037     input_line_pointer = t;
01038   *sizeP = prec * sizeof (LITTLENUM_TYPE);
01039   for (wordP = words; prec--;)
01040     {
01041       md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
01042       litP += sizeof (LITTLENUM_TYPE);
01043     }
01044 
01045   return NULL;
01046 }
01047 
01048 /* Write a value out to the object file, using the appropriate
01049    endianness.  */
01050 
01051 void
01052 md_number_to_chars (char *buf, valueT val, int n)
01053 {
01054   if (target_big_endian)
01055     number_to_chars_bigendian (buf, val, n);
01056   else
01057     number_to_chars_littleendian (buf, val, n);
01058 }
01059 
01060 /* Round up a section size to the appropriate boundary.  */
01061 
01062 valueT
01063 md_section_align (segT segment, valueT size)
01064 {
01065   int align = bfd_get_section_alignment (stdoutput, segment);
01066 
01067   return ((size + (1 << align) - 1) & (-1 << align));
01068 }
01069 
01070 /* We don't have any form of relaxing.  */
01071 
01072 int
01073 md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
01074                             asection *seg ATTRIBUTE_UNUSED)
01075 {
01076   as_fatal (_("md_estimate_size_before_relax\n"));
01077   return 1;
01078 }
01079 
01080 /* Convert a machine dependent frag.  We never generate these.  */
01081 
01082 void
01083 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
01084                asection *sec ATTRIBUTE_UNUSED,
01085                fragS *fragp ATTRIBUTE_UNUSED)
01086 {
01087   as_fatal (_("md_convert_frag\n"));
01088 }
01089 
01090 static void
01091 arc_code_symbol (expressionS *expressionP)
01092 {
01093   if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
01094     {
01095       expressionS two;
01096 
01097       expressionP->X_op = O_right_shift;
01098       expressionP->X_add_symbol->sy_value.X_op = O_constant;
01099       two.X_op = O_constant;
01100       two.X_add_symbol = two.X_op_symbol = NULL;
01101       two.X_add_number = 2;
01102       expressionP->X_op_symbol = make_expr_symbol (&two);
01103     }
01104   /* Allow %st(sym1-sym2)  */
01105   else if (expressionP->X_op == O_subtract
01106           && expressionP->X_add_symbol != NULL
01107           && expressionP->X_op_symbol != NULL
01108           && expressionP->X_add_number == 0)
01109     {
01110       expressionS two;
01111 
01112       expressionP->X_add_symbol = make_expr_symbol (expressionP);
01113       expressionP->X_op = O_right_shift;
01114       two.X_op = O_constant;
01115       two.X_add_symbol = two.X_op_symbol = NULL;
01116       two.X_add_number = 2;
01117       expressionP->X_op_symbol = make_expr_symbol (&two);
01118     }
01119   else
01120     as_bad ("expression too complex code symbol");
01121 }
01122 
01123 /* Parse an operand that is machine-specific.
01124 
01125    The ARC has a special %-op to adjust addresses so they're usable in
01126    branches.  The "st" is short for the STatus register.
01127    ??? Later expand this to take a flags value too.
01128 
01129    ??? We can't create new expression types so we map the %-op's onto the
01130    existing syntax.  This means that the user could use the chosen syntax
01131    to achieve the same effect.  */
01132 
01133 void
01134 md_operand (expressionS *expressionP)
01135 {
01136   char *p = input_line_pointer;
01137 
01138   if (*p != '%')
01139     return;
01140 
01141   if (strncmp (p, "%st(", 4) == 0)
01142     {
01143       input_line_pointer += 4;
01144       expression (expressionP);
01145       if (*input_line_pointer != ')')
01146        {
01147          as_bad ("missing ')' in %%-op");
01148          return;
01149        }
01150       ++input_line_pointer;
01151       arc_code_symbol (expressionP);
01152     }
01153   else
01154     {
01155       /* It could be a register.  */
01156       int i, l;
01157       struct arc_ext_operand_value *ext_oper = arc_ext_operands;
01158       p++;
01159 
01160       while (ext_oper)
01161        {
01162          l = strlen (ext_oper->operand.name);
01163          if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
01164            {
01165              input_line_pointer += l + 1;
01166              expressionP->X_op = O_register;
01167              expressionP->X_add_number = (offsetT) &ext_oper->operand;
01168              return;
01169            }
01170          ext_oper = ext_oper->next;
01171        }
01172       for (i = 0; i < arc_reg_names_count; i++)
01173        {
01174          l = strlen (arc_reg_names[i].name);
01175          if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
01176            {
01177              input_line_pointer += l + 1;
01178              expressionP->X_op = O_register;
01179              expressionP->X_add_number = (offsetT) &arc_reg_names[i];
01180              break;
01181            }
01182        }
01183     }
01184 }
01185 
01186 /* We have no need to default values of symbols.
01187    We could catch register names here, but that is handled by inserting
01188    them all in the symbol table to begin with.  */
01189 
01190 symbolS *
01191 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
01192 {
01193   return 0;
01194 }
01195 
01196 /* Functions concerning expressions.  */
01197 
01198 /* Parse a .byte, .word, etc. expression.
01199 
01200    Values for the status register are specified with %st(label).
01201    `label' will be right shifted by 2.  */
01202 
01203 void
01204 arc_parse_cons_expression (expressionS *exp,
01205                         unsigned int nbytes ATTRIBUTE_UNUSED)
01206 {
01207   char *p = input_line_pointer;
01208   int code_symbol_fix = 0;
01209 
01210   for (; ! is_end_of_line[(unsigned char) *p]; p++)
01211     if (*p == '@' && !strncmp (p, "@h30", 4))
01212       {
01213        code_symbol_fix = 1;
01214        strcpy (p, ";   ");
01215       }
01216   expression_and_evaluate (exp);
01217   if (code_symbol_fix)
01218     {
01219       arc_code_symbol (exp);
01220       input_line_pointer = p;
01221     }
01222 }
01223 
01224 /* Record a fixup for a cons expression.  */
01225 
01226 void
01227 arc_cons_fix_new (fragS *frag,
01228                 int where,
01229                 int nbytes,
01230                 expressionS *exp)
01231 {
01232   if (nbytes == 4)
01233     {
01234       int reloc_type;
01235       expressionS exptmp;
01236 
01237       /* This may be a special ARC reloc (eg: %st()).  */
01238       reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
01239       fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
01240     }
01241   else
01242     {
01243       fix_new_exp (frag, where, nbytes, exp, 0,
01244                  nbytes == 2 ? BFD_RELOC_16
01245                  : nbytes == 8 ? BFD_RELOC_64
01246                  : BFD_RELOC_32);
01247     }
01248 }
01249 
01250 /* Functions concerning relocs.  */
01251 
01252 /* The location from which a PC relative jump should be calculated,
01253    given a PC relative reloc.  */
01254 
01255 long
01256 md_pcrel_from (fixS *fixP)
01257 {
01258   /* Return the address of the delay slot.  */
01259   return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
01260 }
01261 
01262 /* Apply a fixup to the object code.  This is called for all the
01263    fixups we generated by the call to fix_new_exp, above.  In the call
01264    above we used a reloc code which was the largest legal reloc code
01265    plus the operand index.  Here we undo that to recover the operand
01266    index.  At this point all symbol values should be fully resolved,
01267    and we attempt to completely resolve the reloc.  If we can not do
01268    that, we determine the correct reloc code and put it back in the fixup.  */
01269 
01270 void
01271 md_apply_fix (fixS *fixP, valueT * valP, segT seg)
01272 {
01273   valueT value = * valP;
01274 
01275   if (fixP->fx_addsy == (symbolS *) NULL)
01276     fixP->fx_done = 1;
01277 
01278   else if (fixP->fx_pcrel)
01279     {
01280       /* Hack around bfd_install_relocation brain damage.  */
01281       if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
01282        value += md_pcrel_from (fixP);
01283     }
01284 
01285   /* We can't actually support subtracting a symbol.  */
01286   if (fixP->fx_subsy != NULL)
01287     as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
01288 
01289   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
01290     {
01291       int opindex;
01292       const struct arc_operand *operand;
01293       char *where;
01294       arc_insn insn;
01295 
01296       opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
01297 
01298       operand = &arc_operands[opindex];
01299 
01300       /* Fetch the instruction, insert the fully resolved operand
01301         value, and stuff the instruction back again.  */
01302       where = fixP->fx_frag->fr_literal + fixP->fx_where;
01303       if (target_big_endian)
01304        insn = bfd_getb32 ((unsigned char *) where);
01305       else
01306        insn = bfd_getl32 ((unsigned char *) where);
01307       insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
01308                              fixP->fx_file, fixP->fx_line);
01309       if (target_big_endian)
01310        bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
01311       else
01312        bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
01313 
01314       if (fixP->fx_done)
01315        /* Nothing else to do here.  */
01316        return;
01317 
01318       /* Determine a BFD reloc value based on the operand information.
01319         We are only prepared to turn a few of the operands into relocs.
01320         !!! Note that we can't handle limm values here.  Since we're using
01321         implicit addends the addend must be inserted into the instruction,
01322         however, the opcode insertion routines currently do nothing with
01323         limm values.  */
01324       if (operand->fmt == 'B')
01325        {
01326          assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
01327                 && operand->bits == 20
01328                 && operand->shift == 7);
01329          fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
01330        }
01331       else if (operand->fmt == 'J')
01332        {
01333          assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
01334                 && operand->bits == 24
01335                 && operand->shift == 32);
01336          fixP->fx_r_type = BFD_RELOC_ARC_B26;
01337        }
01338       else if (operand->fmt == 'L')
01339        {
01340          assert ((operand->flags & ARC_OPERAND_LIMM) != 0
01341                 && operand->bits == 32
01342                 && operand->shift == 32);
01343          fixP->fx_r_type = BFD_RELOC_32;
01344        }
01345       else
01346        {
01347          as_bad_where (fixP->fx_file, fixP->fx_line,
01348                      "unresolved expression that must be resolved");
01349          fixP->fx_done = 1;
01350          return;
01351        }
01352     }
01353   else
01354     {
01355       switch (fixP->fx_r_type)
01356        {
01357        case BFD_RELOC_8:
01358          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
01359                            value, 1);
01360          break;
01361        case BFD_RELOC_16:
01362          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
01363                            value, 2);
01364          break;
01365        case BFD_RELOC_32:
01366          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
01367                            value, 4);
01368          break;
01369        case BFD_RELOC_ARC_B26:
01370          /* If !fixP->fx_done then `value' is an implicit addend.
01371             We must shift it right by 2 in this case as well because the
01372             linker performs the relocation and then adds this in (as opposed
01373             to adding this in and then shifting right by 2).  */
01374          value >>= 2;
01375          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
01376                            value, 4);
01377          break;
01378        default:
01379          abort ();
01380        }
01381     }
01382 }
01383 
01384 /* Translate internal representation of relocation info to BFD target
01385    format.  */
01386 
01387 arelent *
01388 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
01389              fixS *fixP)
01390 {
01391   arelent *reloc;
01392 
01393   reloc = xmalloc (sizeof (arelent));
01394   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
01395 
01396   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
01397   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
01398   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
01399   if (reloc->howto == (reloc_howto_type *) NULL)
01400     {
01401       as_bad_where (fixP->fx_file, fixP->fx_line,
01402                   "internal error: can't export reloc type %d (`%s')",
01403                   fixP->fx_r_type,
01404                   bfd_get_reloc_code_name (fixP->fx_r_type));
01405       return NULL;
01406     }
01407 
01408   assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
01409 
01410   /* Set addend to account for PC being advanced one insn before the
01411      target address is computed.  */
01412 
01413   reloc->addend = (fixP->fx_pcrel ? -4 : 0);
01414 
01415   return reloc;
01416 }
01417 
01418 const pseudo_typeS md_pseudo_table[] =
01419 {
01420   { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0).  */
01421   { "comm", arc_common, 0 },
01422   { "common", arc_common, 0 },
01423   { "lcomm", arc_common, 1 },
01424   { "lcommon", arc_common, 1 },
01425   { "2byte", cons, 2 },
01426   { "half", cons, 2 },
01427   { "short", cons, 2 },
01428   { "3byte", cons, 3 },
01429   { "4byte", cons, 4 },
01430   { "word", cons, 4 },
01431   { "option", arc_option, 0 },
01432   { "cpu", arc_option, 0 },
01433   { "block", s_space, 0 },
01434   { "extcondcode", arc_extoper, 0 },
01435   { "extcoreregister", arc_extoper, 1 },
01436   { "extauxregister", arc_extoper, 2 },
01437   { "extinstruction", arc_extinst, 0 },
01438   { NULL, 0, 0 },
01439 };
01440 
01441 /* This routine is called for each instruction to be assembled.  */
01442 
01443 void
01444 md_assemble (char *str)
01445 {
01446   const struct arc_opcode *opcode;
01447   const struct arc_opcode *std_opcode;
01448   struct arc_opcode *ext_opcode;
01449   char *start;
01450   const char *last_errmsg = 0;
01451   arc_insn insn;
01452   static int init_tables_p = 0;
01453 
01454   /* Opcode table initialization is deferred until here because we have to
01455      wait for a possible .option command.  */
01456   if (!init_tables_p)
01457     {
01458       init_opcode_tables (arc_mach_type);
01459       init_tables_p = 1;
01460     }
01461 
01462   /* Skip leading white space.  */
01463   while (ISSPACE (*str))
01464     str++;
01465 
01466   /* The instructions are stored in lists hashed by the first letter (though
01467      we needn't care how they're hashed).  Get the first in the list.  */
01468 
01469   ext_opcode = arc_ext_opcodes;
01470   std_opcode = arc_opcode_lookup_asm (str);
01471 
01472   /* Keep looking until we find a match.  */
01473   start = str;
01474   for (opcode = (ext_opcode ? ext_opcode : std_opcode);
01475        opcode != NULL;
01476        opcode = (ARC_OPCODE_NEXT_ASM (opcode)
01477                ? ARC_OPCODE_NEXT_ASM (opcode)
01478                : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
01479     {
01480       int past_opcode_p, fc, num_suffixes;
01481       int fix_up_at = 0;
01482       char *syn;
01483       struct arc_fixup fixups[MAX_FIXUPS];
01484       /* Used as a sanity check.  If we need a limm reloc, make sure we ask
01485         for an extra 4 bytes from frag_more.  */
01486       int limm_reloc_p;
01487       int ext_suffix_p;
01488       const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
01489 
01490       /* Is this opcode supported by the selected cpu?  */
01491       if (! arc_opcode_supported (opcode))
01492        continue;
01493 
01494       /* Scan the syntax string.  If it doesn't match, try the next one.  */
01495       arc_opcode_init_insert ();
01496       insn = opcode->value;
01497       fc = 0;
01498       past_opcode_p = 0;
01499       num_suffixes = 0;
01500       limm_reloc_p = 0;
01501       ext_suffix_p = 0;
01502 
01503       /* We don't check for (*str != '\0') here because we want to parse
01504         any trailing fake arguments in the syntax string.  */
01505       for (str = start, syn = opcode->syntax; *syn != '\0';)
01506        {
01507          int mods;
01508          const struct arc_operand *operand;
01509 
01510          /* Non operand chars must match exactly.  */
01511          if (*syn != '%' || *++syn == '%')
01512            {
01513             if (*str == *syn)
01514               {
01515                 if (*syn == ' ')
01516                   past_opcode_p = 1;
01517                 ++syn;
01518                 ++str;
01519               }
01520              else
01521               break;
01522              continue;
01523            }
01524 
01525          /* We have an operand.  Pick out any modifiers.  */
01526          mods = 0;
01527          while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
01528            {
01529              mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
01530              ++syn;
01531            }
01532          operand = arc_operands + arc_operand_map[(int) *syn];
01533          if (operand->fmt == 0)
01534            as_fatal ("unknown syntax format character `%c'", *syn);
01535 
01536          if (operand->flags & ARC_OPERAND_FAKE)
01537            {
01538              const char *errmsg = NULL;
01539              if (operand->insert)
01540               {
01541                 insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
01542                 if (errmsg != (const char *) NULL)
01543                   {
01544                     last_errmsg = errmsg;
01545                     if (operand->flags & ARC_OPERAND_ERROR)
01546                      {
01547                        as_bad (errmsg);
01548                        return;
01549                      }
01550                     else if (operand->flags & ARC_OPERAND_WARN)
01551                      as_warn (errmsg);
01552                     break;
01553                   }
01554                 if (limm_reloc_p
01555                     && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
01556                     && (operand->flags &
01557                        (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
01558                   {
01559                     fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
01560                   }
01561               }
01562              ++syn;
01563            }
01564          /* Are we finished with suffixes?  */
01565          else if (!past_opcode_p)
01566            {
01567              int found;
01568              char c;
01569              char *s, *t;
01570              const struct arc_operand_value *suf, *suffix_end;
01571              const struct arc_operand_value *suffix = NULL;
01572 
01573              if (!(operand->flags & ARC_OPERAND_SUFFIX))
01574               abort ();
01575 
01576              /* If we're at a space in the input string, we want to skip the
01577                remaining suffixes.  There may be some fake ones though, so
01578                just go on to try the next one.  */
01579              if (*str == ' ')
01580               {
01581                 ++syn;
01582                 continue;
01583               }
01584 
01585              s = str;
01586              if (mods & ARC_MOD_DOT)
01587               {
01588                 if (*s != '.')
01589                   break;
01590                 ++s;
01591               }
01592              else
01593               {
01594                 /* This can happen in "b.nd foo" and we're currently looking
01595                    for "%q" (ie: a condition code suffix).  */
01596                 if (*s == '.')
01597                   {
01598                     ++syn;
01599                     continue;
01600                   }
01601               }
01602 
01603              /* Pick the suffix out and look it up via the hash table.  */
01604              for (t = s; *t && ISALNUM (*t); ++t)
01605               continue;
01606              c = *t;
01607              *t = '\0';
01608              if ((suf = get_ext_suffix (s)))
01609               ext_suffix_p = 1;
01610              else
01611               suf = hash_find (arc_suffix_hash, s);
01612              if (!suf)
01613               {
01614                 /* This can happen in "blle foo" and we're currently using
01615                    the template "b%q%.n %j".  The "bl" insn occurs later in
01616                    the table so "lle" isn't an illegal suffix.  */
01617                 *t = c;
01618                 break;
01619               }
01620 
01621              /* Is it the right type?  Note that the same character is used
01622                several times, so we have to examine all of them.  This is
01623                relatively efficient as equivalent entries are kept
01624                together.  If it's not the right type, don't increment `str'
01625                so we try the next one in the series.  */
01626              found = 0;
01627              if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
01628               {
01629                 /* Insert the suffix's value into the insn.  */
01630                 *t = c;
01631                 if (operand->insert)
01632                   insn = (*operand->insert) (insn, operand,
01633                                           mods, NULL, suf->value,
01634                                           NULL);
01635                 else
01636                   insn |= suf->value << operand->shift;
01637                 suffix = suf;
01638                 str = t;
01639                 found = 1;
01640               }
01641              else
01642               {
01643                 *t = c;
01644                 suffix_end = arc_suffixes + arc_suffixes_count;
01645                 for (suffix = suf;
01646                      suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
01647                      ++suffix)
01648                   {
01649                     if (arc_operands[suffix->type].fmt == *syn)
01650                      {
01651                        /* Insert the suffix's value into the insn.  */
01652                        if (operand->insert)
01653                          insn = (*operand->insert) (insn, operand,
01654                                                  mods, NULL, suffix->value,
01655                                                  NULL);
01656                        else
01657                          insn |= suffix->value << operand->shift;
01658 
01659                        str = t;
01660                        found = 1;
01661                        break;
01662                      }
01663                   }
01664               }
01665              ++syn;
01666              if (!found)
01667               /* Wrong type.  Just go on to try next insn entry.  */
01668               ;
01669              else
01670               {
01671                 if (num_suffixes == MAX_SUFFIXES)
01672                   as_bad ("too many suffixes");
01673                 else
01674                   insn_suffixes[num_suffixes++] = suffix;
01675               }
01676            }
01677          else
01678            /* This is either a register or an expression of some kind.  */
01679            {
01680              char *hold;
01681              const struct arc_operand_value *reg = NULL;
01682              long value = 0;
01683              expressionS exp;
01684 
01685              if (operand->flags & ARC_OPERAND_SUFFIX)
01686               abort ();
01687 
01688              /* Is there anything left to parse?
01689                We don't check for this at the top because we want to parse
01690                any trailing fake arguments in the syntax string.  */
01691              if (is_end_of_line[(unsigned char) *str])
01692               break;
01693 
01694              /* Parse the operand.  */
01695              hold = input_line_pointer;
01696              input_line_pointer = str;
01697              expression (&exp);
01698              str = input_line_pointer;
01699              input_line_pointer = hold;
01700 
01701              if (exp.X_op == O_illegal)
01702               as_bad ("illegal operand");
01703              else if (exp.X_op == O_absent)
01704               as_bad ("missing operand");
01705              else if (exp.X_op == O_constant)
01706               value = exp.X_add_number;
01707              else if (exp.X_op == O_register)
01708               reg = (struct arc_operand_value *) exp.X_add_number;
01709 #define IS_REG_DEST_OPERAND(o) ((o) == 'a')
01710              else if (IS_REG_DEST_OPERAND (*syn))
01711               as_bad ("symbol as destination register");
01712              else
01713               {
01714                 if (!strncmp (str, "@h30", 4))
01715                   {
01716                     arc_code_symbol (&exp);
01717                     str += 4;
01718                   }
01719                 /* We need to generate a fixup for this expression.  */
01720                 if (fc >= MAX_FIXUPS)
01721                   as_fatal ("too many fixups");
01722                 fixups[fc].exp = exp;
01723                 /* We don't support shimm relocs. break here to force
01724                    the assembler to output a limm.  */
01725 #define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
01726                 if (IS_REG_SHIMM_OFFSET (*syn))
01727                   break;
01728                 /* If this is a register constant (IE: one whose
01729                    register value gets stored as 61-63) then this
01730                    must be a limm.  */
01731                 /* ??? This bit could use some cleaning up.
01732                    Referencing the format chars like this goes
01733                    against style.  */
01734                 if (IS_SYMBOL_OPERAND (*syn))
01735                   {
01736                     const char *junk;
01737                     limm_reloc_p = 1;
01738                     /* Save this, we don't yet know what reloc to use.  */
01739                     fix_up_at = fc;
01740                     /* Tell insert_reg we need a limm.  This is
01741                       needed because the value at this point is
01742                       zero, a shimm.  */
01743                     /* ??? We need a cleaner interface than this.  */
01744                     (*arc_operands[arc_operand_map['Q']].insert)
01745                      (insn, operand, mods, reg, 0L, &junk);
01746                   }
01747                 else
01748                   fixups[fc].opindex = arc_operand_map[(int) *syn];
01749                 ++fc;
01750                 value = 0;
01751               }
01752 
01753              /* Insert the register or expression into the instruction.  */
01754              if (operand->insert)
01755               {
01756                 const char *errmsg = NULL;
01757                 insn = (*operand->insert) (insn, operand, mods,
01758                                         reg, (long) value, &errmsg);
01759                 if (errmsg != (const char *) NULL)
01760                   {
01761                     last_errmsg = errmsg;
01762                     if (operand->flags & ARC_OPERAND_ERROR)
01763                      {
01764                        as_bad (errmsg);
01765                        return;
01766                      }
01767                     else if (operand->flags & ARC_OPERAND_WARN)
01768                      as_warn (errmsg);
01769                     break;
01770                   }
01771               }
01772              else
01773               insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
01774 
01775              ++syn;
01776            }
01777        }
01778 
01779       /* If we're at the end of the syntax string, we're done.  */
01780       /* FIXME: try to move this to a separate function.  */
01781       if (*syn == '\0')
01782        {
01783          int i;
01784          char *f;
01785          long limm, limm_p;
01786 
01787          /* For the moment we assume a valid `str' can only contain blanks
01788             now.  IE: We needn't try again with a longer version of the
01789             insn and it is assumed that longer versions of insns appear
01790             before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
01791 
01792          while (ISSPACE (*str))
01793            ++str;
01794 
01795          if (!is_end_of_line[(unsigned char) *str])
01796            as_bad ("junk at end of line: `%s'", str);
01797 
01798          /* Is there a limm value?  */
01799          limm_p = arc_opcode_limm_p (&limm);
01800 
01801          /* Perform various error and warning tests.  */
01802 
01803          {
01804            static int in_delay_slot_p = 0;
01805            static int prev_insn_needs_cc_nop_p = 0;
01806            /* delay slot type seen */
01807            int delay_slot_type = ARC_DELAY_NONE;
01808            /* conditional execution flag seen */
01809            int conditional = 0;
01810            /* 1 if condition codes are being set */
01811            int cc_set_p = 0;
01812            /* 1 if conditional branch, including `b' "branch always" */
01813            int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
01814 
01815            for (i = 0; i < num_suffixes; ++i)
01816              {
01817               switch (arc_operands[insn_suffixes[i]->type].fmt)
01818                 {
01819                 case 'n':
01820                   delay_slot_type = insn_suffixes[i]->value;
01821                   break;
01822                 case 'q':
01823                   conditional = insn_suffixes[i]->value;
01824                   break;
01825                 case 'f':
01826                   cc_set_p = 1;
01827                   break;
01828                 }
01829              }
01830 
01831            /* Putting an insn with a limm value in a delay slot is supposed to
01832               be legal, but let's warn the user anyway.  Ditto for 8 byte
01833               jumps with delay slots.  */
01834            if (in_delay_slot_p && limm_p)
01835              as_warn ("8 byte instruction in delay slot");
01836            if (delay_slot_type != ARC_DELAY_NONE
01837               && limm_p && arc_insn_not_jl (insn)) /* except for jl  addr */
01838              as_warn ("8 byte jump instruction with delay slot");
01839            in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
01840 
01841            /* Warn when a conditional branch immediately follows a set of
01842               the condition codes.  Note that this needn't be done if the
01843               insn that sets the condition codes uses a limm.  */
01844            if (cond_branch_p && conditional != 0 /* 0 = "always" */
01845               && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
01846              as_warn ("conditional branch follows set of flags");
01847            prev_insn_needs_cc_nop_p =
01848              /* FIXME: ??? not required:
01849                (delay_slot_type != ARC_DELAY_NONE) &&  */
01850              cc_set_p && !limm_p;
01851          }
01852 
01853          /* Write out the instruction.
01854             It is important to fetch enough space in one call to `frag_more'.
01855             We use (f - frag_now->fr_literal) to compute where we are and we
01856             don't want frag_now to change between calls.  */
01857          if (limm_p)
01858            {
01859              f = frag_more (8);
01860              md_number_to_chars (f, insn, 4);
01861              md_number_to_chars (f + 4, limm, 4);
01862              dwarf2_emit_insn (8);
01863            }
01864          else if (limm_reloc_p)
01865            /* We need a limm reloc, but the tables think we don't.  */
01866            abort ();
01867          else
01868            {
01869              f = frag_more (4);
01870              md_number_to_chars (f, insn, 4);
01871              dwarf2_emit_insn (4);
01872            }
01873 
01874          /* Create any fixups.  */
01875          for (i = 0; i < fc; ++i)
01876            {
01877              int op_type, reloc_type;
01878              expressionS exptmp;
01879              const struct arc_operand *operand;
01880 
01881              /* Create a fixup for this operand.
01882                At this point we do not use a bfd_reloc_code_real_type for
01883                operands residing in the insn, but instead just use the
01884                operand index.  This lets us easily handle fixups for any
01885                operand type, although that is admittedly not a very exciting
01886                feature.  We pick a BFD reloc type in md_apply_fix.
01887 
01888                Limm values (4 byte immediate "constants") must be treated
01889                normally because they're not part of the actual insn word
01890                and thus the insertion routines don't handle them.  */
01891 
01892              if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
01893               {
01894                 /* Modify the fixup addend as required by the cpu.  */
01895                 fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
01896                 op_type = fixups[i].opindex;
01897                 /* FIXME: can we add this data to the operand table?  */
01898                 if (op_type == arc_operand_map['L']
01899                     || op_type == arc_operand_map['s']
01900                     || op_type == arc_operand_map['o']
01901                     || op_type == arc_operand_map['O'])
01902                   reloc_type = BFD_RELOC_32;
01903                 else if (op_type == arc_operand_map['J'])
01904                   reloc_type = BFD_RELOC_ARC_B26;
01905                 else
01906                   abort ();
01907                 reloc_type = get_arc_exp_reloc_type (1, reloc_type,
01908                                                  &fixups[i].exp,
01909                                                  &exptmp);
01910               }
01911              else
01912               {
01913                 op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
01914                                               &fixups[i].exp, &exptmp);
01915                 reloc_type = op_type + (int) BFD_RELOC_UNUSED;
01916               }
01917              operand = &arc_operands[op_type];
01918              fix_new_exp (frag_now,
01919                         ((f - frag_now->fr_literal)
01920                          + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
01921                         &exptmp,
01922                         (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
01923                         (bfd_reloc_code_real_type) reloc_type);
01924            }
01925          return;
01926        }
01927     }
01928 
01929   if (NULL == last_errmsg)
01930     as_bad ("bad instruction `%s'", start);
01931   else
01932     as_bad (last_errmsg);
01933 }