Home | History | Annotate | Line # | Download | only in config
tc-arc.c revision 1.1.1.10
      1 /* tc-arc.c -- Assembler for the ARC
      2    Copyright (C) 1994-2025 Free Software Foundation, Inc.
      3 
      4    Contributor: Claudiu Zissulescu <claziss (at) synopsys.com>
      5 
      6    This file is part of GAS, the GNU Assembler.
      7 
      8    GAS is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3, or (at your option)
     11    any later version.
     12 
     13    GAS is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with GAS; see the file COPYING.  If not, write to the Free
     20    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     21    02110-1301, USA.  */
     22 
     23 #include "as.h"
     24 #include "subsegs.h"
     25 #include "dwarf2dbg.h"
     26 #include "dw2gencfi.h"
     27 #include "safe-ctype.h"
     28 
     29 #include "opcode/arc.h"
     30 #include "opcode/arc-attrs.h"
     31 #include "elf/arc.h"
     32 #include "../opcodes/arc-ext.h"
     33 
     34 /* Defines section.  */
     35 
     36 #define MAX_INSN_FIXUPS      2
     37 #define MAX_CONSTR_STR       20
     38 #define FRAG_MAX_GROWTH      8
     39 
     40 #ifdef DEBUG
     41 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
     42 #else
     43 # define pr_debug(fmt, args...)
     44 #endif
     45 
     46 #define MAJOR_OPCODE(x)  (((x) & 0xF8000000) >> 27)
     47 #define SUB_OPCODE(x)	 (((x) & 0x003F0000) >> 16)
     48 #define LP_INSN(x)	 ((MAJOR_OPCODE (x) == 0x4) \
     49 			  && (SUB_OPCODE (x) == 0x28))
     50 
     51 #ifndef TARGET_WITH_CPU
     52 #define TARGET_WITH_CPU "hs38_linux"
     53 #endif /* TARGET_WITH_CPU */
     54 
     55 #define ARC_GET_FLAG(s)   	(*symbol_get_tc (s))
     56 #define ARC_SET_FLAG(s,v) 	(*symbol_get_tc (s) |= (v))
     57 #define streq(a, b)	      (strcmp (a, b) == 0)
     58 
     59 /* Enum used to enumerate the relaxable ins operands.  */
     60 enum rlx_operand_type
     61 {
     62   EMPTY = 0,
     63   REGISTER,
     64   REGISTER_S,     /* Register for short instruction(s).  */
     65   REGISTER_NO_GP, /* Is a register but not gp register specifically.  */
     66   REGISTER_DUP,   /* Duplication of previous operand of type register.  */
     67   IMMEDIATE,
     68   BRACKET
     69 };
     70 
     71 enum arc_rlx_types
     72 {
     73   ARC_RLX_NONE = 0,
     74   ARC_RLX_BL_S,
     75   ARC_RLX_BL,
     76   ARC_RLX_B_S,
     77   ARC_RLX_B,
     78   ARC_RLX_ADD_U3,
     79   ARC_RLX_ADD_U6,
     80   ARC_RLX_ADD_LIMM,
     81   ARC_RLX_LD_U7,
     82   ARC_RLX_LD_S9,
     83   ARC_RLX_LD_LIMM,
     84   ARC_RLX_MOV_U8,
     85   ARC_RLX_MOV_S12,
     86   ARC_RLX_MOV_LIMM,
     87   ARC_RLX_SUB_U3,
     88   ARC_RLX_SUB_U6,
     89   ARC_RLX_SUB_LIMM,
     90   ARC_RLX_MPY_U6,
     91   ARC_RLX_MPY_LIMM,
     92   ARC_RLX_MOV_RU6,
     93   ARC_RLX_MOV_RLIMM,
     94   ARC_RLX_ADD_RRU6,
     95   ARC_RLX_ADD_RRLIMM,
     96 };
     97 
     98 /* Macros section.  */
     99 
    100 #define regno(x)		((x) & 0x3F)
    101 #define is_ir_num(x)		(((x) & ~0x3F) == 0)
    102 #define is_code_density_p(sc)   (((sc) == CD1 || (sc) == CD2))
    103 #define is_spfp_p(op)           (((sc) == SPX))
    104 #define is_dpfp_p(op)           (((sc) == DPX))
    105 #define is_fpuda_p(op)          (((sc) == DPA))
    106 #define is_br_jmp_insn_p(op)    (((op)->insn_class == BRANCH		\
    107 				  || (op)->insn_class == JUMP		\
    108 				  || (op)->insn_class == BRCC		\
    109 				  || (op)->insn_class == BBIT0		\
    110 				  || (op)->insn_class == BBIT1		\
    111 				  || (op)->insn_class == BI		\
    112 				  || (op)->insn_class == DBNZ		\
    113 				  || (op)->insn_class == EI		\
    114 				  || (op)->insn_class == ENTER		\
    115 				  || (op)->insn_class == JLI		\
    116 				  || (op)->insn_class == LOOP		\
    117 				  || (op)->insn_class == LEAVE		\
    118 				  ))
    119 #define is_kernel_insn_p(op)    (((op)->insn_class == KERNEL))
    120 #define is_nps400_p(op)         (((sc) == NPS400))
    121 
    122 /* Generic assembler global variables which must be defined by all
    123    targets.  */
    124 
    125 /* Characters which always start a comment.  */
    126 const char comment_chars[] = "#;";
    127 
    128 /* Characters which start a comment at the beginning of a line.  */
    129 const char line_comment_chars[] = "#";
    130 
    131 /* Characters which may be used to separate multiple commands on a
    132    single line.  */
    133 const char line_separator_chars[] = "`";
    134 
    135 /* Characters which are used to indicate an exponent in a floating
    136    point number.  */
    137 const char EXP_CHARS[] = "eE";
    138 
    139 /* Chars that mean this number is a floating point constant
    140    As in 0f12.456 or 0d1.2345e12.  */
    141 const char FLT_CHARS[] = "rRsSfFdD";
    142 
    143 /* Byte order.  */
    144 extern int target_big_endian;
    145 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
    146 static int byte_order = DEFAULT_BYTE_ORDER;
    147 
    148 /* Arc extension section.  */
    149 static segT arcext_section;
    150 
    151 /* By default relaxation is disabled.  */
    152 static int relaxation_state = 0;
    153 
    154 extern int arc_get_mach (char *);
    155 
    156 /* Forward declarations.  */
    157 static void arc_lcomm (int);
    158 static void arc_option (int);
    159 static void arc_extra_reloc (int);
    160 static void arc_extinsn (int);
    161 static void arc_extcorereg (int);
    162 static void arc_attribute (int);
    163 
    164 const pseudo_typeS md_pseudo_table[] =
    165 {
    166   /* Make sure that .word is 32 bits.  */
    167   { "word", cons, 4 },
    168 
    169   { "align",   s_align_bytes, 0 }, /* Defaulting is invalid (0).  */
    170   { "lcomm",   arc_lcomm, 0 },
    171   { "lcommon", arc_lcomm, 0 },
    172   { "cpu",     arc_option, 0 },
    173 
    174   { "arc_attribute",   arc_attribute, 0 },
    175   { "extinstruction",  arc_extinsn, 0 },
    176   { "extcoreregister", arc_extcorereg, EXT_CORE_REGISTER },
    177   { "extauxregister",  arc_extcorereg, EXT_AUX_REGISTER },
    178   { "extcondcode",     arc_extcorereg, EXT_COND_CODE },
    179 
    180   { "tls_gd_ld",   arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
    181   { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
    182 
    183   { NULL, NULL, 0 }
    184 };
    185 
    186 const char md_shortopts[] = "";
    187 
    188 enum options
    189 {
    190   OPTION_EB = OPTION_MD_BASE,
    191   OPTION_EL,
    192 
    193   OPTION_ARC600,
    194   OPTION_ARC601,
    195   OPTION_ARC700,
    196   OPTION_ARCEM,
    197   OPTION_ARCHS,
    198 
    199   OPTION_MCPU,
    200   OPTION_CD,
    201   OPTION_RELAX,
    202   OPTION_NPS400,
    203 
    204   OPTION_SPFP,
    205   OPTION_DPFP,
    206   OPTION_FPUDA,
    207 
    208   /* The following options are deprecated and provided here only for
    209      compatibility reasons.  */
    210   OPTION_USER_MODE,
    211   OPTION_LD_EXT_MASK,
    212   OPTION_SWAP,
    213   OPTION_NORM,
    214   OPTION_BARREL_SHIFT,
    215   OPTION_MIN_MAX,
    216   OPTION_NO_MPY,
    217   OPTION_EA,
    218   OPTION_MUL64,
    219   OPTION_SIMD,
    220   OPTION_XMAC_D16,
    221   OPTION_XMAC_24,
    222   OPTION_DSP_PACKA,
    223   OPTION_CRC,
    224   OPTION_DVBF,
    225   OPTION_TELEPHONY,
    226   OPTION_XYMEMORY,
    227   OPTION_LOCK,
    228   OPTION_SWAPE,
    229   OPTION_RTSC
    230 };
    231 
    232 const struct option md_longopts[] =
    233 {
    234   { "EB",		no_argument,	   NULL, OPTION_EB },
    235   { "EL",		no_argument,	   NULL, OPTION_EL },
    236   { "mcpu",		required_argument, NULL, OPTION_MCPU },
    237   { "mA6",		no_argument,	   NULL, OPTION_ARC600 },
    238   { "mARC600",		no_argument,	   NULL, OPTION_ARC600 },
    239   { "mARC601",		no_argument,	   NULL, OPTION_ARC601 },
    240   { "mARC700",		no_argument,	   NULL, OPTION_ARC700 },
    241   { "mA7",		no_argument,	   NULL, OPTION_ARC700 },
    242   { "mEM",		no_argument,	   NULL, OPTION_ARCEM },
    243   { "mHS",		no_argument,	   NULL, OPTION_ARCHS },
    244   { "mcode-density",	no_argument,	   NULL, OPTION_CD },
    245   { "mrelax",           no_argument,       NULL, OPTION_RELAX },
    246   { "mnps400",          no_argument,       NULL, OPTION_NPS400 },
    247 
    248   /* Floating point options */
    249   { "mspfp", no_argument, NULL, OPTION_SPFP},
    250   { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
    251   { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
    252   { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
    253   { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
    254   { "mdpfp", no_argument, NULL, OPTION_DPFP},
    255   { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
    256   { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
    257   { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
    258   { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
    259   { "mfpuda", no_argument, NULL, OPTION_FPUDA},
    260 
    261   /* The following options are deprecated and provided here only for
    262      compatibility reasons.  */
    263   { "mav2em", no_argument, NULL, OPTION_ARCEM },
    264   { "mav2hs", no_argument, NULL, OPTION_ARCHS },
    265   { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
    266   { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
    267   { "mswap", no_argument, NULL, OPTION_SWAP },
    268   { "mnorm", no_argument, NULL, OPTION_NORM },
    269   { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
    270   { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
    271   { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
    272   { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
    273   { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
    274   { "mea", no_argument, NULL, OPTION_EA },
    275   { "mEA", no_argument, NULL, OPTION_EA },
    276   { "mmul64", no_argument, NULL, OPTION_MUL64 },
    277   { "msimd", no_argument, NULL, OPTION_SIMD},
    278   { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
    279   { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
    280   { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
    281   { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
    282   { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
    283   { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
    284   { "mcrc", no_argument, NULL, OPTION_CRC},
    285   { "mdvbf", no_argument, NULL, OPTION_DVBF},
    286   { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
    287   { "mxy", no_argument, NULL, OPTION_XYMEMORY},
    288   { "mlock", no_argument, NULL, OPTION_LOCK},
    289   { "mswape", no_argument, NULL, OPTION_SWAPE},
    290   { "mrtsc", no_argument, NULL, OPTION_RTSC},
    291 
    292   { NULL,		no_argument, NULL, 0 }
    293 };
    294 
    295 const size_t md_longopts_size = sizeof (md_longopts);
    296 
    297 /* Local data and data types.  */
    298 
    299 /* Used since new relocation types are introduced in this
    300    file (DUMMY_RELOC_LITUSE_*).  */
    301 typedef int extended_bfd_reloc_code_real_type;
    302 
    303 struct arc_fixup
    304 {
    305   expressionS exp;
    306 
    307   extended_bfd_reloc_code_real_type reloc;
    308 
    309   /* index into arc_operands.  */
    310   unsigned int opindex;
    311 
    312   /* PC-relative, used by internals fixups.  */
    313   unsigned char pcrel;
    314 
    315   /* TRUE if this fixup is for LIMM operand.  */
    316   bool islong;
    317 };
    318 
    319 struct arc_insn
    320 {
    321   unsigned long long int insn;
    322   int nfixups;
    323   struct arc_fixup fixups[MAX_INSN_FIXUPS];
    324   long limm;
    325   unsigned int len;     /* Length of instruction in bytes.  */
    326   bool has_limm;	/* Boolean value: TRUE if limm field is valid.  */
    327   bool relax;		/* Boolean value: TRUE if needs relaxation.  */
    328 };
    329 
    330 /* Structure to hold any last two instructions.  */
    331 static struct arc_last_insn
    332 {
    333   /* Saved instruction opcode.  */
    334   const struct arc_opcode *opcode;
    335 
    336   /* Boolean value: TRUE if current insn is short.  */
    337   bool has_limm;
    338 
    339   /* Boolean value: TRUE if current insn has delay slot.  */
    340   bool has_delay_slot;
    341 } arc_last_insns[2];
    342 
    343 /* Extension instruction suffix classes.  */
    344 typedef struct
    345 {
    346   const char *name;
    347   int  len;
    348   int  attr_class;
    349 } attributes_t;
    350 
    351 static const attributes_t suffixclass[] =
    352 {
    353   { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG },
    354   { "SUFFIX_COND", 11, ARC_SUFFIX_COND },
    355   { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE }
    356 };
    357 
    358 /* Extension instruction syntax classes.  */
    359 static const attributes_t syntaxclass[] =
    360 {
    361   { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP },
    362   { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP },
    363   { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP },
    364   { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP }
    365 };
    366 
    367 /* Extension instruction syntax classes modifiers.  */
    368 static const attributes_t syntaxclassmod[] =
    369 {
    370   { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED },
    371   { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM }
    372 };
    373 
    374 /* Extension register type.  */
    375 typedef struct
    376 {
    377   char *name;
    378   int  number;
    379   int  imode;
    380 } extRegister_t;
    381 
    382 /* A structure to hold the additional conditional codes.  */
    383 static struct
    384 {
    385   struct arc_flag_operand *arc_ext_condcode;
    386   int size;
    387 } ext_condcode = { NULL, 0 };
    388 
    389 /* Structure to hold an entry in ARC_OPCODE_HASH.  */
    390 struct arc_opcode_hash_entry
    391 {
    392   /* The number of pointers in the OPCODE list.  */
    393   size_t count;
    394 
    395   /* Points to a list of opcode pointers.  */
    396   const struct arc_opcode **opcode;
    397 };
    398 
    399 /* Structure used for iterating through an arc_opcode_hash_entry.  */
    400 struct arc_opcode_hash_entry_iterator
    401 {
    402   /* Index into the OPCODE element of the arc_opcode_hash_entry.  */
    403   size_t index;
    404 
    405   /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
    406      returned by this iterator.  */
    407   const struct arc_opcode *opcode;
    408 };
    409 
    410 /* Forward declaration.  */
    411 static void assemble_insn
    412   (const struct arc_opcode *, const expressionS *, int,
    413    const struct arc_flags *, int, struct arc_insn *);
    414 
    415 /* The selection of the machine type can come from different sources.  This
    416    enum is used to track how the selection was made in order to perform
    417    error checks.  */
    418 enum mach_selection_type
    419   {
    420     MACH_SELECTION_NONE,
    421     MACH_SELECTION_FROM_DEFAULT,
    422     MACH_SELECTION_FROM_CPU_DIRECTIVE,
    423     MACH_SELECTION_FROM_COMMAND_LINE
    424   };
    425 
    426 /* How the current machine type was selected.  */
    427 static enum mach_selection_type mach_selection_mode = MACH_SELECTION_NONE;
    428 
    429 /* The hash table of instruction opcodes.  */
    430 static htab_t arc_opcode_hash;
    431 
    432 /* The hash table of register symbols.  */
    433 static htab_t arc_reg_hash;
    434 
    435 /* The hash table of aux register symbols.  */
    436 static htab_t arc_aux_hash;
    437 
    438 /* The hash table of address types.  */
    439 static htab_t arc_addrtype_hash;
    440 
    441 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA)			\
    442   { #NAME, ARC_OPCODE_ARC600, bfd_mach_arc_arc600,	\
    443       E_ARC_MACH_ARC600, EXTRA}
    444 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA)			\
    445   { #NAME, ARC_OPCODE_ARC700,  bfd_mach_arc_arc700,	\
    446       E_ARC_MACH_ARC700, EXTRA}
    447 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA)			\
    448   { #NAME,  ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,	\
    449       EF_ARC_CPU_ARCV2EM, EXTRA}
    450 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA)			\
    451   { #NAME,  ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,	\
    452       EF_ARC_CPU_ARCV2HS, EXTRA}
    453 #define ARC_CPU_TYPE_NONE				\
    454   { 0, 0, 0, 0, 0 }
    455 
    456 /* A table of CPU names and opcode sets.  */
    457 static const struct cpu_type
    458 {
    459   const char *name;
    460   unsigned flags;
    461   int mach;
    462   unsigned eflags;
    463   unsigned features;
    464 }
    465   cpu_types[] =
    466 {
    467   #include "elf/arc-cpu.def"
    468 };
    469 
    470 /* Information about the cpu/variant we're assembling for.  */
    471 static struct cpu_type selected_cpu = { 0, 0, 0, E_ARC_OSABI_CURRENT, 0 };
    472 
    473 /* TRUE if current assembly code uses RF16 only registers.  */
    474 static bool rf16_only = true;
    475 
    476 /* MPY option.  */
    477 static unsigned mpy_option = 0;
    478 
    479 /* Use PIC. */
    480 static unsigned pic_option = 0;
    481 
    482 /* Use small data.  */
    483 static unsigned sda_option = 0;
    484 
    485 /* Use TLS.  */
    486 static unsigned tls_option = 0;
    487 
    488 /* Command line given features.  */
    489 static unsigned cl_features = 0;
    490 
    491 /* Used by the arc_reloc_op table.  Order is important.  */
    492 #define O_gotoff  O_md1     /* @gotoff relocation.  */
    493 #define O_gotpc   O_md2     /* @gotpc relocation.  */
    494 #define O_plt     O_md3     /* @plt relocation.  */
    495 #define O_sda     O_md4     /* @sda relocation.  */
    496 #define O_pcl     O_md5     /* @pcl relocation.  */
    497 #define O_tlsgd   O_md6     /* @tlsgd relocation.  */
    498 #define O_tlsie   O_md7     /* @tlsie relocation.  */
    499 #define O_tpoff9  O_md8     /* @tpoff9 relocation.  */
    500 #define O_tpoff   O_md9     /* @tpoff relocation.  */
    501 #define O_dtpoff9 O_md10    /* @dtpoff9 relocation.  */
    502 #define O_dtpoff  O_md11    /* @dtpoff relocation.  */
    503 #define O_last    O_dtpoff
    504 
    505 /* Used to define a bracket as operand in tokens.  */
    506 #define O_bracket O_md32
    507 
    508 /* Used to define a colon as an operand in tokens.  */
    509 #define O_colon O_md31
    510 
    511 /* Used to define address types in nps400.  */
    512 #define O_addrtype O_md30
    513 
    514 /* Dummy relocation, to be sorted out.  */
    515 #define DUMMY_RELOC_ARC_ENTRY     (BFD_RELOC_UNUSED + 1)
    516 
    517 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
    518 
    519 /* A table to map the spelling of a relocation operand into an appropriate
    520    bfd_reloc_code_real_type type.  The table is assumed to be ordered such
    521    that op-O_literal indexes into it.  */
    522 #define ARC_RELOC_TABLE(op)				\
    523   (&arc_reloc_op[ ((!USER_RELOC_P (op))			\
    524 		   ? (abort (), 0)			\
    525 		   : (op) - O_gotoff) ])
    526 
    527 #define DEF(NAME, RELOC, REQ)				\
    528   { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
    529 
    530 static const struct arc_reloc_op_tag
    531 {
    532   /* String to lookup.  */
    533   const char *name;
    534   /* Size of the string.  */
    535   size_t length;
    536   /* Which operator to use.  */
    537   operatorT op;
    538   extended_bfd_reloc_code_real_type reloc;
    539   /* Allows complex relocation expression like identifier@reloc +
    540      const.  */
    541   unsigned int complex_expr : 1;
    542 }
    543   arc_reloc_op[] =
    544 {
    545   DEF (gotoff,  BFD_RELOC_ARC_GOTOFF,		1),
    546   DEF (gotpc,   BFD_RELOC_ARC_GOTPC32,		0),
    547   DEF (plt,	BFD_RELOC_ARC_PLT32,		0),
    548   DEF (sda,	DUMMY_RELOC_ARC_ENTRY,		1),
    549   DEF (pcl,	BFD_RELOC_ARC_PC32,		1),
    550   DEF (tlsgd,   BFD_RELOC_ARC_TLS_GD_GOT,	0),
    551   DEF (tlsie,   BFD_RELOC_ARC_TLS_IE_GOT,	0),
    552   DEF (tpoff9,  BFD_RELOC_ARC_TLS_LE_S9,	0),
    553   DEF (tpoff,   BFD_RELOC_ARC_TLS_LE_32,	1),
    554   DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9,	0),
    555   DEF (dtpoff,  BFD_RELOC_ARC_TLS_DTPOFF,	1),
    556 };
    557 
    558 static const int arc_num_reloc_op
    559 = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
    560 
    561 /* Structure for relaxable instruction that have to be swapped with a
    562    smaller alternative instruction.  */
    563 struct arc_relaxable_ins
    564 {
    565   /* Mnemonic that should be checked.  */
    566   const char *mnemonic_r;
    567 
    568   /* Operands that should be checked.
    569      Indexes of operands from operand array.  */
    570   enum rlx_operand_type operands[6];
    571 
    572   /* Flags that should be checked.  */
    573   unsigned flag_classes[5];
    574 
    575   /* Mnemonic (smaller) alternative to be used later for relaxation.  */
    576   const char *mnemonic_alt;
    577 
    578   /* Index of operand that generic relaxation has to check.  */
    579   unsigned opcheckidx;
    580 
    581   /* Base subtype index used.  */
    582   enum arc_rlx_types subtype;
    583 };
    584 
    585 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT)			\
    586   { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1),	\
    587       (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0,				\
    588       (SIZE),								\
    589       (NEXT) }								\
    590 
    591 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT)	\
    592   { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF,		\
    593       (ISSIGNED) ? -(0x7FFFFFFF) : 0,                   \
    594       (SIZE),                                           \
    595       (NEXT) }                                          \
    596 
    597 
    598 /* ARC relaxation table.  */
    599 const relax_typeS md_relax_table[] =
    600 {
    601   /* Fake entry.  */
    602   {0, 0, 0, 0},
    603 
    604   /* BL_S s13 ->
    605      BL s25.  */
    606   RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL),
    607   RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE),
    608 
    609   /* B_S s10 ->
    610      B s25.  */
    611   RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B),
    612   RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE),
    613 
    614   /* ADD_S c,b, u3 ->
    615      ADD<.f> a,b,u6 ->
    616      ADD<.f> a,b,limm.  */
    617   RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6),
    618   RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM),
    619   RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
    620 
    621   /* LD_S a, [b, u7] ->
    622      LD<zz><.x><.aa><.di> a, [b, s9] ->
    623      LD<zz><.x><.aa><.di> a, [b, limm] */
    624   RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9),
    625   RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM),
    626   RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE),
    627 
    628   /* MOV_S b, u8 ->
    629      MOV<.f> b, s12 ->
    630      MOV<.f> b, limm.  */
    631   RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12),
    632   RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM),
    633   RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
    634 
    635   /* SUB_S c, b, u3 ->
    636      SUB<.f> a, b, u6 ->
    637      SUB<.f> a, b, limm.  */
    638   RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6),
    639   RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM),
    640   RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
    641 
    642   /* MPY<.f> a, b, u6 ->
    643      MPY<.f> a, b, limm.  */
    644   RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM),
    645   RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
    646 
    647   /* MOV<.f><.cc> b, u6 ->
    648      MOV<.f><.cc> b, limm.  */
    649   RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM),
    650   RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
    651 
    652   /* ADD<.f><.cc> b, b, u6 ->
    653      ADD<.f><.cc> b, b, limm.  */
    654   RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM),
    655   RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
    656 };
    657 
    658 /* Order of this table's entries matters!  */
    659 const struct arc_relaxable_ins arc_relaxable_insns[] =
    660 {
    661   { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S },
    662   { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S },
    663   { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add",
    664     2, ARC_RLX_ADD_RRU6},
    665   { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2,
    666     ARC_RLX_ADD_U3 },
    667   { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2,
    668     ARC_RLX_ADD_U6 },
    669   { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET },
    670     { 0 }, "ld_s", 3, ARC_RLX_LD_U7 },
    671   { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET },
    672     { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 },
    673   { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 },
    674   { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 },
    675   { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 },
    676   { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2,
    677     ARC_RLX_SUB_U3 },
    678   { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2,
    679     ARC_RLX_SUB_U6 },
    680   { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2,
    681     ARC_RLX_MPY_U6 },
    682 };
    683 
    684 const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns);
    685 
    686 /* Pre-defined "_GLOBAL_OFFSET_TABLE_".  */
    687 symbolS * GOT_symbol = 0;
    688 
    689 /* Set to TRUE when we assemble instructions.  */
    690 static bool assembling_insn = false;
    691 
    692 /* List with attributes set explicitly.  */
    693 static bool attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
    694 
    695 /* Functions implementation.  */
    696 
    697 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
    698    ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
    699    are no matching entries in ARC_OPCODE_HASH.  */
    700 
    701 static const struct arc_opcode_hash_entry *
    702 arc_find_opcode (const char *name)
    703 {
    704   const struct arc_opcode_hash_entry *entry;
    705 
    706   entry = str_hash_find (arc_opcode_hash, name);
    707   return entry;
    708 }
    709 
    710 /* Initialise the iterator ITER.  */
    711 
    712 static void
    713 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator *iter)
    714 {
    715   iter->index = 0;
    716   iter->opcode = NULL;
    717 }
    718 
    719 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
    720    calls to this function.  Return NULL when all ARC_OPCODE entries have
    721    been returned.  */
    722 
    723 static const struct arc_opcode *
    724 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry,
    725 				     struct arc_opcode_hash_entry_iterator *iter)
    726 {
    727   if (iter->opcode == NULL && iter->index == 0)
    728     {
    729       gas_assert (entry->count > 0);
    730       iter->opcode = entry->opcode[iter->index];
    731     }
    732   else if (iter->opcode != NULL)
    733     {
    734       const char *old_name = iter->opcode->name;
    735 
    736       iter->opcode++;
    737       if (iter->opcode->name == NULL
    738 	  || strcmp (old_name, iter->opcode->name) != 0)
    739 	{
    740 	  iter->index++;
    741 	  if (iter->index == entry->count)
    742 	    iter->opcode = NULL;
    743 	  else
    744 	    iter->opcode = entry->opcode[iter->index];
    745 	}
    746     }
    747 
    748   return iter->opcode;
    749 }
    750 
    751 /* Insert an opcode into opcode hash structure.  */
    752 
    753 static void
    754 arc_insert_opcode (const struct arc_opcode *opcode)
    755 {
    756   const char *name;
    757   struct arc_opcode_hash_entry *entry;
    758   name = opcode->name;
    759 
    760   entry = str_hash_find (arc_opcode_hash, name);
    761   if (entry == NULL)
    762     {
    763       entry = XNEW (struct arc_opcode_hash_entry);
    764       entry->count = 0;
    765       entry->opcode = NULL;
    766 
    767       if (str_hash_insert (arc_opcode_hash, name, entry, 0) != NULL)
    768 	as_fatal (_("duplicate %s"), name);
    769     }
    770 
    771   entry->opcode = XRESIZEVEC (const struct arc_opcode *, entry->opcode,
    772 			      entry->count + 1);
    773 
    774   entry->opcode[entry->count] = opcode;
    775   entry->count++;
    776 }
    777 
    778 static void
    779 arc_opcode_free (void *elt)
    780 {
    781   string_tuple_t *tuple = elt;
    782   struct arc_opcode_hash_entry *entry = (void *) tuple->value;
    783   free (entry->opcode);
    784   free (entry);
    785   free (tuple);
    786 }
    787 
    788 /* Like md_number_to_chars but for middle-endian values.  The 4-byte limm
    789    value, is encoded as 'middle-endian' for a little-endian target.  This
    790    function is used for regular 4, 6, and 8 byte instructions as well.  */
    791 
    792 static void
    793 md_number_to_chars_midend (char *buf, unsigned long long val, int n)
    794 {
    795   switch (n)
    796     {
    797     case 2:
    798       md_number_to_chars (buf, val, n);
    799       break;
    800     case 6:
    801       md_number_to_chars (buf, (val & 0xffff00000000ull) >> 32, 2);
    802       md_number_to_chars_midend (buf + 2, (val & 0xffffffff), 4);
    803       break;
    804     case 4:
    805       md_number_to_chars (buf,     (val & 0xffff0000) >> 16, 2);
    806       md_number_to_chars (buf + 2, (val & 0xffff), 2);
    807       break;
    808     case 8:
    809       md_number_to_chars_midend (buf, (val & 0xffffffff00000000ull) >> 32, 4);
    810       md_number_to_chars_midend (buf + 4, (val & 0xffffffff), 4);
    811       break;
    812     default:
    813       abort ();
    814     }
    815 }
    816 
    817 /* Check if a feature is allowed for a specific CPU.  */
    818 
    819 static void
    820 arc_check_feature (void)
    821 {
    822   unsigned i;
    823 
    824   if (!selected_cpu.features
    825       || !selected_cpu.name)
    826     return;
    827 
    828   for (i = 0; i < ARRAY_SIZE (feature_list); i++)
    829     if ((selected_cpu.features & feature_list[i].feature)
    830 	&& !(selected_cpu.flags & feature_list[i].cpus))
    831       as_bad (_("invalid %s option for %s cpu"), feature_list[i].name,
    832 	      selected_cpu.name);
    833 
    834   for (i = 0; i < ARRAY_SIZE (conflict_list); i++)
    835     if ((selected_cpu.features & conflict_list[i]) == conflict_list[i])
    836       as_bad(_("conflicting ISA extension attributes."));
    837 }
    838 
    839 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
    840    the relevant static global variables.  Parameter SEL describes where
    841    this selection originated from.  */
    842 
    843 static void
    844 arc_select_cpu (const char *arg, enum mach_selection_type sel)
    845 {
    846   int i;
    847   static struct cpu_type old_cpu = { 0, 0, 0, E_ARC_OSABI_CURRENT, 0 };
    848 
    849   /* We should only set a default if we've not made a selection from some
    850      other source.  */
    851   gas_assert (sel != MACH_SELECTION_FROM_DEFAULT
    852               || mach_selection_mode == MACH_SELECTION_NONE);
    853 
    854   if ((mach_selection_mode == MACH_SELECTION_FROM_CPU_DIRECTIVE)
    855       && (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE))
    856     as_bad (_("Multiple .cpu directives found"));
    857 
    858   /* Look for a matching entry in CPU_TYPES array.  */
    859   for (i = 0; cpu_types[i].name; ++i)
    860     {
    861       if (!strcasecmp (cpu_types[i].name, arg))
    862         {
    863           /* If a previous selection was made on the command line, then we
    864              allow later selections on the command line to override earlier
    865              ones.  However, a selection from a '.cpu NAME' directive must
    866              match the command line selection, or we give a warning.  */
    867           if (mach_selection_mode == MACH_SELECTION_FROM_COMMAND_LINE)
    868             {
    869               gas_assert (sel == MACH_SELECTION_FROM_COMMAND_LINE
    870                           || sel == MACH_SELECTION_FROM_CPU_DIRECTIVE);
    871               if (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE
    872                   && selected_cpu.mach != cpu_types[i].mach)
    873                 {
    874                   as_warn (_("Command-line value overrides \".cpu\" directive"));
    875                 }
    876 	      return;
    877             }
    878 	  /* Initialise static global data about selected machine type.  */
    879 	  selected_cpu.flags = cpu_types[i].flags;
    880 	  selected_cpu.name = cpu_types[i].name;
    881 	  selected_cpu.features = cpu_types[i].features | cl_features;
    882 	  selected_cpu.mach = cpu_types[i].mach;
    883 	  selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_MACH_MSK)
    884 				 | cpu_types[i].eflags);
    885           break;
    886         }
    887     }
    888 
    889   if (!cpu_types[i].name)
    890     as_fatal (_("unknown architecture: %s\n"), arg);
    891 
    892   /* Check if set features are compatible with the chosen CPU.  */
    893   arc_check_feature ();
    894 
    895   /* If we change the CPU, we need to re-init the bfd.  */
    896   if (mach_selection_mode != MACH_SELECTION_NONE
    897       && (old_cpu.mach != selected_cpu.mach))
    898     {
    899       bfd_find_target (arc_target_format, stdoutput);
    900       if (! bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
    901 	as_warn (_("Could not set architecture and machine"));
    902     }
    903 
    904   mach_selection_mode = sel;
    905   old_cpu = selected_cpu;
    906 }
    907 
    908 /* Here ends all the ARCompact extension instruction assembling
    909    stuff.  */
    910 
    911 static void
    912 arc_extra_reloc (int r_type)
    913 {
    914   char *sym_name, c;
    915   symbolS *sym, *lab = NULL;
    916 
    917   if (*input_line_pointer == '@')
    918     input_line_pointer++;
    919   c = get_symbol_name (&sym_name);
    920   sym = symbol_find_or_make (sym_name);
    921   restore_line_pointer (c);
    922   if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
    923     {
    924       ++input_line_pointer;
    925       char *lab_name;
    926       c = get_symbol_name (&lab_name);
    927       lab = symbol_find_or_make (lab_name);
    928       restore_line_pointer (c);
    929     }
    930 
    931   /* These relocations exist as a mechanism for the compiler to tell the
    932      linker how to patch the code if the tls model is optimised.  However,
    933      the relocation itself does not require any space within the assembler
    934      fragment, and so we pass a size of 0.
    935 
    936      The lines that generate these relocations look like this:
    937 
    938          .tls_gd_ld @.tdata`bl __tls_get_addr@plt
    939 
    940      The '.tls_gd_ld @.tdata' is processed first and generates the
    941      additional relocation, while the 'bl __tls_get_addr@plt' is processed
    942      second and generates the additional branch.
    943 
    944      It is possible that the additional relocation generated by the
    945      '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
    946      while the 'bl __tls_get_addr@plt' will be generated as the first thing
    947      in the next fragment.  This will be fine; both relocations will still
    948      appear to be at the same address in the generated object file.
    949      However, this only works as the additional relocation is generated
    950      with size of 0 bytes.  */
    951   fixS *fixP
    952     = fix_new (frag_now,	/* Which frag?  */
    953 	       frag_now_fix (),	/* Where in that frag?  */
    954 	       0,		/* size: 1, 2, or 4 usually.  */
    955 	       sym,		/* X_add_symbol.  */
    956 	       0,		/* X_add_number.  */
    957 	       false,		/* TRUE if PC-relative relocation.  */
    958 	       r_type		/* Relocation type.  */);
    959   fixP->fx_subsy = lab;
    960 }
    961 
    962 static symbolS *
    963 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
    964 		    symbolS *symbolP, addressT size)
    965 {
    966   addressT align = 0;
    967   SKIP_WHITESPACE ();
    968 
    969   if (*input_line_pointer == ',')
    970     {
    971       align = parse_align (1);
    972 
    973       if (align == (addressT) -1)
    974 	return NULL;
    975     }
    976   else
    977     {
    978       if (size >= 8)
    979 	align = 3;
    980       else if (size >= 4)
    981 	align = 2;
    982       else if (size >= 2)
    983 	align = 1;
    984       else
    985 	align = 0;
    986     }
    987 
    988   bss_alloc (symbolP, size, align);
    989   S_CLEAR_EXTERNAL (symbolP);
    990 
    991   return symbolP;
    992 }
    993 
    994 static void
    995 arc_lcomm (int ignore)
    996 {
    997   symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
    998 
    999   if (symbolP)
   1000     symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
   1001 }
   1002 
   1003 /* Select the cpu we're assembling for.  */
   1004 
   1005 static void
   1006 arc_option (int ignore ATTRIBUTE_UNUSED)
   1007 {
   1008   char c;
   1009   char *cpu;
   1010   const char *cpu_name;
   1011 
   1012   c = get_symbol_name (&cpu);
   1013 
   1014   cpu_name = cpu;
   1015   if ((!strcmp ("ARC600", cpu))
   1016       || (!strcmp ("ARC601", cpu))
   1017       || (!strcmp ("A6", cpu)))
   1018     cpu_name = "arc600";
   1019   else if ((!strcmp ("ARC700", cpu))
   1020            || (!strcmp ("A7", cpu)))
   1021     cpu_name = "arc700";
   1022   else if (!strcmp ("EM", cpu))
   1023     cpu_name = "arcem";
   1024   else if (!strcmp ("HS", cpu))
   1025     cpu_name = "archs";
   1026   else if (!strcmp ("NPS400", cpu))
   1027     cpu_name = "nps400";
   1028 
   1029   arc_select_cpu (cpu_name, MACH_SELECTION_FROM_CPU_DIRECTIVE);
   1030 
   1031   restore_line_pointer (c);
   1032   demand_empty_rest_of_line ();
   1033 }
   1034 
   1035 /* Smartly print an expression.  */
   1036 
   1037 static void
   1038 debug_exp (expressionS *t)
   1039 {
   1040   const char *name ATTRIBUTE_UNUSED;
   1041   const char *namemd ATTRIBUTE_UNUSED;
   1042 
   1043   pr_debug ("debug_exp: ");
   1044 
   1045   switch (t->X_op)
   1046     {
   1047     default:			name = "unknown";		break;
   1048     case O_illegal:		name = "O_illegal";		break;
   1049     case O_absent:		name = "O_absent";		break;
   1050     case O_constant:		name = "O_constant";		break;
   1051     case O_symbol:		name = "O_symbol";		break;
   1052     case O_symbol_rva:		name = "O_symbol_rva";		break;
   1053     case O_register:		name = "O_register";		break;
   1054     case O_big:			name = "O_big";			break;
   1055     case O_uminus:		name = "O_uminus";		break;
   1056     case O_bit_not:		name = "O_bit_not";		break;
   1057     case O_logical_not:		name = "O_logical_not";		break;
   1058     case O_multiply:		name = "O_multiply";		break;
   1059     case O_divide:		name = "O_divide";		break;
   1060     case O_modulus:		name = "O_modulus";		break;
   1061     case O_left_shift:		name = "O_left_shift";		break;
   1062     case O_right_shift:		name = "O_right_shift";		break;
   1063     case O_bit_inclusive_or:	name = "O_bit_inclusive_or";	break;
   1064     case O_bit_or_not:		name = "O_bit_or_not";		break;
   1065     case O_bit_exclusive_or:	name = "O_bit_exclusive_or";	break;
   1066     case O_bit_and:		name = "O_bit_and";		break;
   1067     case O_add:			name = "O_add";			break;
   1068     case O_subtract:		name = "O_subtract";		break;
   1069     case O_eq:			name = "O_eq";			break;
   1070     case O_ne:			name = "O_ne";			break;
   1071     case O_lt:			name = "O_lt";			break;
   1072     case O_le:			name = "O_le";			break;
   1073     case O_ge:			name = "O_ge";			break;
   1074     case O_gt:			name = "O_gt";			break;
   1075     case O_logical_and:		name = "O_logical_and";		break;
   1076     case O_logical_or:		name = "O_logical_or";		break;
   1077     case O_index:		name = "O_index";		break;
   1078     case O_bracket:		name = "O_bracket";		break;
   1079     case O_colon:		name = "O_colon";               break;
   1080     case O_addrtype:		name = "O_addrtype";            break;
   1081     }
   1082 
   1083   switch (t->X_md)
   1084     {
   1085     default:			namemd = "unknown";		break;
   1086     case O_gotoff:		namemd = "O_gotoff";		break;
   1087     case O_gotpc:		namemd = "O_gotpc";		break;
   1088     case O_plt:			namemd = "O_plt";		break;
   1089     case O_sda:			namemd = "O_sda";		break;
   1090     case O_pcl:			namemd = "O_pcl";		break;
   1091     case O_tlsgd:		namemd = "O_tlsgd";		break;
   1092     case O_tlsie:		namemd = "O_tlsie";		break;
   1093     case O_tpoff9:		namemd = "O_tpoff9";		break;
   1094     case O_tpoff:		namemd = "O_tpoff";		break;
   1095     case O_dtpoff9:		namemd = "O_dtpoff9";		break;
   1096     case O_dtpoff:		namemd = "O_dtpoff";		break;
   1097     }
   1098 
   1099   pr_debug ("%s (%s, %s, %d, %s)", name,
   1100 	    (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
   1101 	    (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
   1102 	    (int) t->X_add_number,
   1103 	    (t->X_md) ? namemd : "--");
   1104   pr_debug ("\n");
   1105   fflush (stderr);
   1106 }
   1107 
   1108 /* Helper for parsing an argument, used for sorting out the relocation
   1109    type.  */
   1110 
   1111 static void
   1112 parse_reloc_symbol (expressionS *resultP)
   1113 {
   1114   char *reloc_name, c, *sym_name;
   1115   size_t len;
   1116   int i;
   1117   const struct arc_reloc_op_tag *r;
   1118   expressionS right;
   1119   symbolS *base;
   1120 
   1121   /* A relocation operand has the following form
   1122      @identifier@relocation_type.  The identifier is already in
   1123      tok!  */
   1124   if (resultP->X_op != O_symbol)
   1125     {
   1126       as_bad (_("No valid label relocation operand"));
   1127       resultP->X_op = O_illegal;
   1128       return;
   1129     }
   1130 
   1131   /* Parse @relocation_type.  */
   1132   input_line_pointer++;
   1133   c = get_symbol_name (&reloc_name);
   1134   len = input_line_pointer - reloc_name;
   1135   if (len == 0)
   1136     {
   1137       as_bad (_("No relocation operand"));
   1138       resultP->X_op = O_illegal;
   1139       return;
   1140     }
   1141 
   1142   /* Go through known relocation and try to find a match.  */
   1143   r = &arc_reloc_op[0];
   1144   for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
   1145     if (len == r->length
   1146 	&& memcmp (reloc_name, r->name, len) == 0)
   1147       break;
   1148   if (i < 0)
   1149     {
   1150       as_bad (_("Unknown relocation operand: @%s"), reloc_name);
   1151       resultP->X_op = O_illegal;
   1152       return;
   1153     }
   1154 
   1155   restore_line_pointer (c);
   1156   SKIP_WHITESPACE ();
   1157   /* Extra check for TLS: base.  */
   1158   if (*input_line_pointer == '@')
   1159     {
   1160       if (resultP->X_op_symbol != NULL
   1161 	  || resultP->X_op != O_symbol)
   1162 	{
   1163 	  as_bad (_("Unable to parse TLS base: %s"),
   1164 		  input_line_pointer);
   1165 	  resultP->X_op = O_illegal;
   1166 	  return;
   1167 	}
   1168       input_line_pointer++;
   1169       c = get_symbol_name (&sym_name);
   1170       base = symbol_find_or_make (sym_name);
   1171       resultP->X_op = O_subtract;
   1172       resultP->X_op_symbol = base;
   1173       restore_line_pointer (c);
   1174       right.X_add_number = 0;
   1175     }
   1176 
   1177   if ((*input_line_pointer != '+')
   1178       && (*input_line_pointer != '-'))
   1179     right.X_add_number = 0;
   1180   else
   1181     {
   1182       /* Parse the constant of a complex relocation expression
   1183 	 like @identifier@reloc +/- const.  */
   1184       if (! r->complex_expr)
   1185 	{
   1186 	  as_bad (_("@%s is not a complex relocation."), r->name);
   1187 	  resultP->X_op = O_illegal;
   1188 	  return;
   1189 	}
   1190       expression (&right);
   1191       if (right.X_op != O_constant)
   1192 	{
   1193 	  as_bad (_("Bad expression: @%s + %s."),
   1194 		  r->name, input_line_pointer);
   1195 	  resultP->X_op = O_illegal;
   1196 	  return;
   1197 	}
   1198     }
   1199 
   1200   resultP->X_md = r->op;
   1201   resultP->X_add_number = right.X_add_number;
   1202 }
   1203 
   1204 /* Parse the arguments to an opcode.  */
   1205 
   1206 static int
   1207 tokenize_arguments (char *str,
   1208 		    expressionS *tok,
   1209 		    int ntok)
   1210 {
   1211   char *old_input_line_pointer;
   1212   bool saw_comma = false;
   1213   bool saw_arg = false;
   1214   int brk_lvl = 0;
   1215   int num_args = 0;
   1216 
   1217   memset (tok, 0, sizeof (*tok) * ntok);
   1218 
   1219   /* Save and restore input_line_pointer around this function.  */
   1220   old_input_line_pointer = input_line_pointer;
   1221   input_line_pointer = str;
   1222 
   1223   while (*input_line_pointer)
   1224     {
   1225       SKIP_WHITESPACE ();
   1226       switch (*input_line_pointer)
   1227 	{
   1228 	case '\0':
   1229 	  goto fini;
   1230 
   1231 	case ',':
   1232 	  input_line_pointer++;
   1233 	  if (saw_comma || !saw_arg)
   1234 	    goto err;
   1235 	  saw_comma = true;
   1236 	  break;
   1237 
   1238 	case '}':
   1239 	case ']':
   1240 	  ++input_line_pointer;
   1241 	  --brk_lvl;
   1242 	  if (!saw_arg || num_args == ntok)
   1243 	    goto err;
   1244 	  tok->X_op = O_bracket;
   1245 	  ++tok;
   1246 	  ++num_args;
   1247 	  break;
   1248 
   1249 	case '{':
   1250 	case '[':
   1251 	  input_line_pointer++;
   1252 	  if (brk_lvl || num_args == ntok)
   1253 	    goto err;
   1254 	  ++brk_lvl;
   1255 	  tok->X_op = O_bracket;
   1256 	  ++tok;
   1257 	  ++num_args;
   1258 	  break;
   1259 
   1260         case ':':
   1261           input_line_pointer++;
   1262           if (!saw_arg || num_args == ntok)
   1263             goto err;
   1264           tok->X_op = O_colon;
   1265           saw_arg = false;
   1266           ++tok;
   1267           ++num_args;
   1268           break;
   1269 
   1270 	case '@':
   1271 	  /* We have labels, function names and relocations, all
   1272 	     starting with @ symbol.  Sort them out.  */
   1273 	  if ((saw_arg && !saw_comma) || num_args == ntok)
   1274 	    goto err;
   1275 
   1276 	  /* Parse @label.  */
   1277 	  input_line_pointer++;
   1278 	  tok->X_op = O_symbol;
   1279 	  tok->X_md = O_absent;
   1280 	  expression (tok);
   1281 
   1282 	  if (*input_line_pointer == '@')
   1283 	    parse_reloc_symbol (tok);
   1284 
   1285 	  debug_exp (tok);
   1286 
   1287 	  if (tok->X_op == O_illegal
   1288               || tok->X_op == O_absent
   1289               || num_args == ntok)
   1290 	    goto err;
   1291 
   1292 	  saw_comma = false;
   1293 	  saw_arg = true;
   1294 	  tok++;
   1295 	  num_args++;
   1296 	  break;
   1297 
   1298 	case '%':
   1299 	  /* Can be a register.  */
   1300 	  ++input_line_pointer;
   1301 	  /* Fall through.  */
   1302 	default:
   1303 
   1304 	  if ((saw_arg && !saw_comma) || num_args == ntok)
   1305 	    goto err;
   1306 
   1307 	  tok->X_op = O_absent;
   1308 	  tok->X_md = O_absent;
   1309 	  expression (tok);
   1310 
   1311 	  /* Legacy: There are cases when we have
   1312 	     identifier@relocation_type, if it is the case parse the
   1313 	     relocation type as well.  */
   1314 	  if (*input_line_pointer == '@')
   1315 	    parse_reloc_symbol (tok);
   1316 	  else
   1317 	    resolve_register (tok);
   1318 
   1319 	  debug_exp (tok);
   1320 
   1321 	  if (tok->X_op == O_illegal
   1322               || tok->X_op == O_absent
   1323               || num_args == ntok)
   1324 	    goto err;
   1325 
   1326 	  saw_comma = false;
   1327 	  saw_arg = true;
   1328 	  tok++;
   1329 	  num_args++;
   1330 	  break;
   1331 	}
   1332     }
   1333 
   1334  fini:
   1335   if (saw_comma || brk_lvl)
   1336     goto err;
   1337   input_line_pointer = old_input_line_pointer;
   1338 
   1339   return num_args;
   1340 
   1341  err:
   1342   if (brk_lvl)
   1343     as_bad (_("Brackets in operand field incorrect"));
   1344   else if (saw_comma)
   1345     as_bad (_("extra comma"));
   1346   else if (!saw_arg)
   1347     as_bad (_("missing argument"));
   1348   else
   1349     as_bad (_("missing comma or colon"));
   1350   input_line_pointer = old_input_line_pointer;
   1351   return -1;
   1352 }
   1353 
   1354 /* Parse the flags to a structure.  */
   1355 
   1356 static int
   1357 tokenize_flags (const char *str,
   1358 		struct arc_flags flags[],
   1359 		int nflg)
   1360 {
   1361   char *old_input_line_pointer;
   1362   bool saw_flg = false;
   1363   bool saw_dot = false;
   1364   int num_flags  = 0;
   1365   size_t flgnamelen;
   1366 
   1367   memset (flags, 0, sizeof (*flags) * nflg);
   1368 
   1369   /* Save and restore input_line_pointer around this function.  */
   1370   old_input_line_pointer = input_line_pointer;
   1371   input_line_pointer = (char *) str;
   1372 
   1373   while (*input_line_pointer)
   1374     {
   1375       switch (*input_line_pointer)
   1376 	{
   1377 	case '.':
   1378 	  input_line_pointer++;
   1379 	  if (saw_dot)
   1380 	    goto err;
   1381 	  saw_dot = true;
   1382 	  saw_flg = false;
   1383 	  break;
   1384 
   1385 	default:
   1386 	  if (is_end_of_stmt (*input_line_pointer)
   1387 	      || is_whitespace (*input_line_pointer))
   1388 	    goto fini;
   1389 
   1390 	  if (saw_flg && !saw_dot)
   1391 	    goto err;
   1392 
   1393 	  if (num_flags >= nflg)
   1394 	    goto err;
   1395 
   1396 	  flgnamelen = strspn (input_line_pointer,
   1397 			       "abcdefghijklmnopqrstuvwxyz0123456789");
   1398 	  if (flgnamelen > MAX_FLAG_NAME_LENGTH)
   1399 	    goto err;
   1400 
   1401 	  memcpy (flags->name, input_line_pointer, flgnamelen);
   1402 
   1403 	  input_line_pointer += flgnamelen;
   1404 	  flags++;
   1405 	  saw_dot = false;
   1406 	  saw_flg = true;
   1407 	  num_flags++;
   1408 	  break;
   1409 	}
   1410     }
   1411 
   1412  fini:
   1413   input_line_pointer = old_input_line_pointer;
   1414   return num_flags;
   1415 
   1416  err:
   1417   if (saw_dot)
   1418     as_bad (_("extra dot"));
   1419   else if (!saw_flg)
   1420     as_bad (_("unrecognized flag"));
   1421   else
   1422     as_bad (_("failed to parse flags"));
   1423   input_line_pointer = old_input_line_pointer;
   1424   return -1;
   1425 }
   1426 
   1427 /* Apply the fixups in order.  */
   1428 
   1429 static void
   1430 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
   1431 {
   1432   int i;
   1433 
   1434   for (i = 0; i < insn->nfixups; i++)
   1435     {
   1436       struct arc_fixup *fixup = &insn->fixups[i];
   1437       int size, pcrel, offset = 0;
   1438 
   1439       /* FIXME! the reloc size is wrong in the BFD file.
   1440 	 When it is fixed please delete me.  */
   1441       size = ((insn->len == 2) && !fixup->islong) ? 2 : 4;
   1442 
   1443       if (fixup->islong)
   1444 	offset = insn->len;
   1445 
   1446       /* Some fixups are only used internally, thus no howto.  */
   1447       if (fixup->reloc == 0)
   1448 	as_fatal (_("Unhandled reloc type"));
   1449 
   1450       if ((int) fixup->reloc < 0)
   1451 	{
   1452 	  /* FIXME! the reloc size is wrong in the BFD file.
   1453 	     When it is fixed please enable me.
   1454 	     size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
   1455 	  pcrel = fixup->pcrel;
   1456 	}
   1457       else
   1458 	{
   1459 	  reloc_howto_type *reloc_howto =
   1460 	    bfd_reloc_type_lookup (stdoutput, fixup->reloc);
   1461 	  gas_assert (reloc_howto);
   1462 
   1463 	  /* FIXME! the reloc size is wrong in the BFD file.
   1464 	     When it is fixed please enable me.
   1465 	     size = bfd_get_reloc_size (reloc_howto); */
   1466 	  pcrel = reloc_howto->pc_relative;
   1467 	}
   1468 
   1469       pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
   1470 offset %d + %d\n",
   1471 		fragP->fr_file, fragP->fr_line,
   1472 		(fixup->reloc < 0) ? "Internal" :
   1473 		bfd_get_reloc_code_name (fixup->reloc),
   1474 		pcrel ? "Y" : "N",
   1475 		size, fix, offset);
   1476       fix_new_exp (fragP, fix + offset,
   1477 		   size, &fixup->exp, pcrel, fixup->reloc);
   1478 
   1479       /* Check for ZOLs, and update symbol info if any.  */
   1480       if (LP_INSN (insn->insn))
   1481 	{
   1482 	  gas_assert (fixup->exp.X_add_symbol);
   1483 	  ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
   1484 	}
   1485     }
   1486 }
   1487 
   1488 /* Actually output an instruction with its fixup.  */
   1489 
   1490 static void
   1491 emit_insn0 (struct arc_insn *insn, char *where, bool relax)
   1492 {
   1493   char *f = where;
   1494   size_t total_len;
   1495 
   1496   pr_debug ("Emit insn : 0x%llx\n", insn->insn);
   1497   pr_debug ("\tLength  : %d\n", insn->len);
   1498   pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
   1499 
   1500   /* Write out the instruction.  */
   1501   total_len = insn->len + (insn->has_limm ? 4 : 0);
   1502   if (!relax)
   1503     f = frag_more (total_len);
   1504 
   1505   md_number_to_chars_midend(f, insn->insn, insn->len);
   1506 
   1507   if (insn->has_limm)
   1508     md_number_to_chars_midend (f + insn->len, insn->limm, 4);
   1509   dwarf2_emit_insn (total_len);
   1510 
   1511   if (!relax)
   1512     apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
   1513 }
   1514 
   1515 static void
   1516 emit_insn1 (struct arc_insn *insn)
   1517 {
   1518   /* How frag_var's args are currently configured:
   1519      - rs_machine_dependent, to dictate it's a relaxation frag.
   1520      - FRAG_MAX_GROWTH, maximum size of instruction
   1521      - 0, variable size that might grow...unused by generic relaxation.
   1522      - frag_now->fr_subtype, fr_subtype starting value, set previously.
   1523      - s, opand expression.
   1524      - 0, offset but it's unused.
   1525      - 0, opcode but it's unused.  */
   1526   symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
   1527   frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
   1528 
   1529   if (frag_room () < FRAG_MAX_GROWTH)
   1530     {
   1531       /* Handle differently when frag literal memory is exhausted.
   1532 	 This is used because when there's not enough memory left in
   1533 	 the current frag, a new frag is created and the information
   1534 	 we put into frag_now->tc_frag_data is disregarded.  */
   1535 
   1536       struct arc_relax_type relax_info_copy;
   1537       relax_substateT subtype = frag_now->fr_subtype;
   1538 
   1539       memcpy (&relax_info_copy, &frag_now->tc_frag_data,
   1540 	      sizeof (struct arc_relax_type));
   1541 
   1542       frag_wane (frag_now);
   1543       frag_grow (FRAG_MAX_GROWTH);
   1544 
   1545       memcpy (&frag_now->tc_frag_data, &relax_info_copy,
   1546 	      sizeof (struct arc_relax_type));
   1547 
   1548       frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
   1549 		subtype, s, 0, 0);
   1550     }
   1551   else
   1552     frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
   1553 	      frag_now->fr_subtype, s, 0, 0);
   1554 }
   1555 
   1556 static void
   1557 emit_insn (struct arc_insn *insn)
   1558 {
   1559   if (insn->relax)
   1560     emit_insn1 (insn);
   1561   else
   1562     emit_insn0 (insn, NULL, false);
   1563 }
   1564 
   1565 /* Check whether a symbol involves a register.  */
   1566 
   1567 static bool
   1568 contains_register (symbolS *sym)
   1569 {
   1570   if (sym)
   1571     {
   1572       expressionS *ex = symbol_get_value_expression (sym);
   1573 
   1574       return ((O_register == ex->X_op)
   1575 	      && !contains_register (ex->X_add_symbol)
   1576 	      && !contains_register (ex->X_op_symbol));
   1577     }
   1578 
   1579   return false;
   1580 }
   1581 
   1582 /* Returns the register number within a symbol.  */
   1583 
   1584 static int
   1585 get_register (symbolS *sym)
   1586 {
   1587   if (!contains_register (sym))
   1588     return -1;
   1589 
   1590   expressionS *ex = symbol_get_value_expression (sym);
   1591   return regno (ex->X_add_number);
   1592 }
   1593 
   1594 /* Return true if a RELOC is generic.  A generic reloc is PC-rel of a
   1595    simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32.  */
   1596 
   1597 static bool
   1598 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
   1599 {
   1600   if (!reloc)
   1601     return false;
   1602 
   1603   switch (reloc)
   1604     {
   1605     case BFD_RELOC_ARC_SDA_LDST:
   1606     case BFD_RELOC_ARC_SDA_LDST1:
   1607     case BFD_RELOC_ARC_SDA_LDST2:
   1608     case BFD_RELOC_ARC_SDA16_LD:
   1609     case BFD_RELOC_ARC_SDA16_LD1:
   1610     case BFD_RELOC_ARC_SDA16_LD2:
   1611     case BFD_RELOC_ARC_SDA16_ST2:
   1612     case BFD_RELOC_ARC_SDA32_ME:
   1613       return false;
   1614     default:
   1615       return true;
   1616     }
   1617 }
   1618 
   1619 /* Allocates a tok entry.  */
   1620 
   1621 static int
   1622 allocate_tok (expressionS *tok, int ntok, int cidx)
   1623 {
   1624   if (ntok > MAX_INSN_ARGS - 2)
   1625     return 0; /* No space left.  */
   1626 
   1627   if (cidx > ntok)
   1628     return 0; /* Incorrect args.  */
   1629 
   1630   memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
   1631 
   1632   if (cidx == ntok)
   1633     return 1; /* Success.  */
   1634   return allocate_tok (tok, ntok - 1, cidx);
   1635 }
   1636 
   1637 /* Check if an particular ARC feature is enabled.  */
   1638 
   1639 static bool
   1640 check_cpu_feature (insn_subclass_t sc)
   1641 {
   1642   if (is_code_density_p (sc) && !(selected_cpu.features & CD))
   1643     return false;
   1644 
   1645   if (is_spfp_p (sc) && !(selected_cpu.features & SPX))
   1646     return false;
   1647 
   1648   if (is_dpfp_p (sc) && !(selected_cpu.features & DPX))
   1649     return false;
   1650 
   1651   if (is_fpuda_p (sc) && !(selected_cpu.features & DPA))
   1652     return false;
   1653 
   1654   if (is_nps400_p (sc) && !(selected_cpu.features & NPS400))
   1655     return false;
   1656 
   1657   return true;
   1658 }
   1659 
   1660 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
   1661    operands in OPCODE.  Stores the matching OPCODES into the FIRST_PFLAG
   1662    array and returns TRUE if the flag operands all match, otherwise,
   1663    returns FALSE, in which case the FIRST_PFLAG array may have been
   1664    modified.  */
   1665 
   1666 static bool
   1667 parse_opcode_flags (const struct arc_opcode *opcode,
   1668                     int nflgs,
   1669                     struct arc_flags *first_pflag)
   1670 {
   1671   int lnflg, i;
   1672   const unsigned char *flgidx;
   1673 
   1674   lnflg = nflgs;
   1675   for (i = 0; i < nflgs; i++)
   1676     first_pflag[i].flgp = NULL;
   1677 
   1678   /* Check the flags.  Iterate over the valid flag classes.  */
   1679   for (flgidx = opcode->flags; *flgidx; ++flgidx)
   1680     {
   1681       /* Get a valid flag class.  */
   1682       const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
   1683       const unsigned *flgopridx;
   1684       int cl_matches = 0;
   1685       struct arc_flags *pflag = NULL;
   1686 
   1687       /* Check if opcode has implicit flag classes.  */
   1688       if (cl_flags->flag_class & F_CLASS_IMPLICIT)
   1689 	continue;
   1690 
   1691       /* Check for extension conditional codes.  */
   1692       if (ext_condcode.arc_ext_condcode
   1693           && cl_flags->flag_class & F_CLASS_EXTEND)
   1694         {
   1695           struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode;
   1696           while (pf->name)
   1697             {
   1698               pflag = first_pflag;
   1699               for (i = 0; i < nflgs; i++, pflag++)
   1700                 {
   1701                   if (!strcmp (pf->name, pflag->name))
   1702                     {
   1703                       if (pflag->flgp != NULL)
   1704                         return false;
   1705                       /* Found it.  */
   1706                       cl_matches++;
   1707                       pflag->flgp = pf;
   1708                       lnflg--;
   1709                       break;
   1710                     }
   1711                 }
   1712               pf++;
   1713             }
   1714         }
   1715 
   1716       for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
   1717         {
   1718           const struct arc_flag_operand *flg_operand;
   1719 
   1720           pflag = first_pflag;
   1721           flg_operand = &arc_flag_operands[*flgopridx];
   1722           for (i = 0; i < nflgs; i++, pflag++)
   1723             {
   1724               /* Match against the parsed flags.  */
   1725               if (!strcmp (flg_operand->name, pflag->name))
   1726                 {
   1727                   if (pflag->flgp != NULL)
   1728                     return false;
   1729                   cl_matches++;
   1730                   pflag->flgp = flg_operand;
   1731                   lnflg--;
   1732                   break; /* goto next flag class and parsed flag.  */
   1733                 }
   1734             }
   1735         }
   1736 
   1737       if ((cl_flags->flag_class & F_CLASS_REQUIRED) && cl_matches == 0)
   1738         return false;
   1739       if ((cl_flags->flag_class & F_CLASS_OPTIONAL) && cl_matches > 1)
   1740         return false;
   1741     }
   1742 
   1743   /* Did I check all the parsed flags?  */
   1744   return lnflg == 0;
   1745 }
   1746 
   1747 
   1748 /* Search forward through all variants of an opcode looking for a
   1749    syntax match.  */
   1750 
   1751 static const struct arc_opcode *
   1752 find_opcode_match (const struct arc_opcode_hash_entry *entry,
   1753 		   expressionS *tok,
   1754 		   int *pntok,
   1755 		   struct arc_flags *first_pflag,
   1756 		   int nflgs,
   1757 		   int *pcpumatch,
   1758 		   const char **errmsg)
   1759 {
   1760   const struct arc_opcode *opcode;
   1761   struct arc_opcode_hash_entry_iterator iter;
   1762   int ntok = *pntok;
   1763   int got_cpu_match = 0;
   1764   expressionS bktok[MAX_INSN_ARGS];
   1765   int bkntok, maxerridx = 0;
   1766   expressionS emptyE;
   1767   const char *tmpmsg = NULL;
   1768 
   1769   arc_opcode_hash_entry_iterator_init (&iter);
   1770   memset (&emptyE, 0, sizeof (emptyE));
   1771   memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
   1772   bkntok = ntok;
   1773 
   1774   for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter);
   1775        opcode != NULL;
   1776        opcode = arc_opcode_hash_entry_iterator_next (entry, &iter))
   1777     {
   1778       const unsigned char *opidx;
   1779       int tokidx = 0;
   1780       const expressionS *t = &emptyE;
   1781 
   1782       pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
   1783 		frag_now->fr_file, frag_now->fr_line, opcode->opcode);
   1784 
   1785       /* Don't match opcodes that don't exist on this
   1786 	 architecture.  */
   1787       if (!(opcode->cpu & selected_cpu.flags))
   1788 	goto match_failed;
   1789 
   1790       if (!check_cpu_feature (opcode->subclass))
   1791 	goto match_failed;
   1792 
   1793       got_cpu_match = 1;
   1794       pr_debug ("cpu ");
   1795 
   1796       /* Check the operands.  */
   1797       for (opidx = opcode->operands; *opidx; ++opidx)
   1798 	{
   1799 	  const struct arc_operand *operand = &arc_operands[*opidx];
   1800 
   1801 	  /* Only take input from real operands.  */
   1802 	  if (ARC_OPERAND_IS_FAKE (operand))
   1803 	    continue;
   1804 
   1805 	  /* When we expect input, make sure we have it.  */
   1806 	  if (tokidx >= ntok)
   1807 	    goto match_failed;
   1808 
   1809 	  /* Match operand type with expression type.  */
   1810 	  switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
   1811 	    {
   1812             case ARC_OPERAND_ADDRTYPE:
   1813 	      {
   1814 		tmpmsg = NULL;
   1815 
   1816 		/* Check to be an address type.  */
   1817 		if (tok[tokidx].X_op != O_addrtype)
   1818 		  goto match_failed;
   1819 
   1820 		/* All address type operands need to have an insert
   1821 		   method in order to check that we have the correct
   1822 		   address type.  */
   1823 		gas_assert (operand->insert != NULL);
   1824 		(*operand->insert) (0, tok[tokidx].X_add_number,
   1825 				    &tmpmsg);
   1826 		if (tmpmsg != NULL)
   1827 		  goto match_failed;
   1828 	      }
   1829               break;
   1830 
   1831 	    case ARC_OPERAND_IR:
   1832 	      /* Check to be a register.  */
   1833 	      if ((tok[tokidx].X_op != O_register
   1834 		   || !is_ir_num (tok[tokidx].X_add_number))
   1835 		  && !(operand->flags & ARC_OPERAND_IGNORE))
   1836 		goto match_failed;
   1837 
   1838 	      /* If expect duplicate, make sure it is duplicate.  */
   1839 	      if (operand->flags & ARC_OPERAND_DUPLICATE)
   1840 		{
   1841 		  /* Check for duplicate.  */
   1842 		  if (t->X_op != O_register
   1843 		      || !is_ir_num (t->X_add_number)
   1844 		      || (regno (t->X_add_number) !=
   1845 			  regno (tok[tokidx].X_add_number)))
   1846 		    goto match_failed;
   1847 		}
   1848 
   1849 	      /* Special handling?  */
   1850 	      if (operand->insert)
   1851 		{
   1852 		  tmpmsg = NULL;
   1853 		  (*operand->insert)(0,
   1854 				     regno (tok[tokidx].X_add_number),
   1855 				     &tmpmsg);
   1856 		  if (tmpmsg)
   1857 		    {
   1858 		      if (operand->flags & ARC_OPERAND_IGNORE)
   1859 			{
   1860 			  /* Missing argument, create one.  */
   1861 			  if (!allocate_tok (tok, ntok - 1, tokidx))
   1862 			    goto match_failed;
   1863 
   1864 			  tok[tokidx].X_op = O_absent;
   1865 			  ++ntok;
   1866 			}
   1867 		      else
   1868 			goto match_failed;
   1869 		    }
   1870 		}
   1871 
   1872 	      t = &tok[tokidx];
   1873 	      break;
   1874 
   1875 	    case ARC_OPERAND_BRAKET:
   1876 	      /* Check if bracket is also in opcode table as
   1877 		 operand.  */
   1878 	      if (tok[tokidx].X_op != O_bracket)
   1879 		goto match_failed;
   1880 	      break;
   1881 
   1882             case ARC_OPERAND_COLON:
   1883               /* Check if colon is also in opcode table as operand.  */
   1884               if (tok[tokidx].X_op != O_colon)
   1885                 goto match_failed;
   1886               break;
   1887 
   1888 	    case ARC_OPERAND_LIMM:
   1889 	    case ARC_OPERAND_SIGNED:
   1890 	    case ARC_OPERAND_UNSIGNED:
   1891 	      switch (tok[tokidx].X_op)
   1892 		{
   1893 		case O_illegal:
   1894 		case O_absent:
   1895 		case O_register:
   1896 		  goto match_failed;
   1897 
   1898 		case O_bracket:
   1899 		  /* Got an (too) early bracket, check if it is an
   1900 		     ignored operand.  N.B. This procedure works only
   1901 		     when bracket is the last operand!  */
   1902 		  if (!(operand->flags & ARC_OPERAND_IGNORE))
   1903 		    goto match_failed;
   1904 		  /* Insert the missing operand.  */
   1905 		  if (!allocate_tok (tok, ntok - 1, tokidx))
   1906 		    goto match_failed;
   1907 
   1908 		  tok[tokidx].X_op = O_absent;
   1909 		  ++ntok;
   1910 		  break;
   1911 
   1912 		case O_symbol:
   1913 		  {
   1914 		    const char *p;
   1915 		    char *tmpp, *pp;
   1916 		    const struct arc_aux_reg *auxr;
   1917 
   1918 		    if (opcode->insn_class != AUXREG)
   1919 		      goto de_fault;
   1920 		    p = S_GET_NAME (tok[tokidx].X_add_symbol);
   1921 
   1922 		    /* For compatibility reasons, an aux register can
   1923 		       be spelled with upper or lower case
   1924 		       letters.  */
   1925 		    tmpp = strdup (p);
   1926 		    for (pp = tmpp; *pp; ++pp) *pp = TOLOWER (*pp);
   1927 
   1928 		    auxr = str_hash_find (arc_aux_hash, tmpp);
   1929 		    if (auxr)
   1930 		      {
   1931 			/* We modify the token array here, safe in the
   1932 			   knowledge, that if this was the wrong
   1933 			   choice then the original contents will be
   1934 			   restored from BKTOK.  */
   1935 			tok[tokidx].X_op = O_constant;
   1936 			tok[tokidx].X_add_number = auxr->address;
   1937 			ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX);
   1938 		      }
   1939 		    free (tmpp);
   1940 
   1941 		    if (tok[tokidx].X_op != O_constant)
   1942 		      goto de_fault;
   1943 		  }
   1944 		  /* Fall through.  */
   1945 		case O_constant:
   1946 		  /* Check the range.  */
   1947 		  if (operand->bits != 32
   1948 		      && !(operand->flags & ARC_OPERAND_NCHK))
   1949 		    {
   1950 		      offsetT min, max, val;
   1951 		      val = tok[tokidx].X_add_number;
   1952 
   1953 		      if (operand->flags & ARC_OPERAND_SIGNED)
   1954 			{
   1955 			  max = (1 << (operand->bits - 1)) - 1;
   1956 			  min = -(1 << (operand->bits - 1));
   1957 			}
   1958 		      else
   1959 			{
   1960 			  max = (1 << operand->bits) - 1;
   1961 			  min = 0;
   1962 			}
   1963 
   1964 		      if (val < min || val > max)
   1965 			{
   1966 			  tmpmsg = _("immediate is out of bounds");
   1967 			  goto match_failed;
   1968 			}
   1969 
   1970 		      /* Check alignments.  */
   1971 		      if ((operand->flags & ARC_OPERAND_ALIGNED32)
   1972 			  && (val & 0x03))
   1973 			{
   1974 			  tmpmsg = _("immediate is not 32bit aligned");
   1975 			  goto match_failed;
   1976 			}
   1977 
   1978 		      if ((operand->flags & ARC_OPERAND_ALIGNED16)
   1979 			  && (val & 0x01))
   1980 			{
   1981 			  tmpmsg = _("immediate is not 16bit aligned");
   1982 			  goto match_failed;
   1983 			}
   1984 		    }
   1985 		  else if (operand->flags & ARC_OPERAND_NCHK)
   1986 		    {
   1987 		      if (operand->insert)
   1988 			{
   1989 			  tmpmsg = NULL;
   1990 			  (*operand->insert)(0,
   1991 					     tok[tokidx].X_add_number,
   1992 					     &tmpmsg);
   1993 			  if (tmpmsg)
   1994 			    goto match_failed;
   1995 			}
   1996 		      else if (!(operand->flags & ARC_OPERAND_IGNORE))
   1997 			goto match_failed;
   1998 		    }
   1999 		  break;
   2000 
   2001 		case O_subtract:
   2002 		  /* Check if it is register range.  */
   2003 		  if ((tok[tokidx].X_add_number == 0)
   2004 		      && contains_register (tok[tokidx].X_add_symbol)
   2005 		      && contains_register (tok[tokidx].X_op_symbol))
   2006 		    {
   2007 		      int regs;
   2008 
   2009 		      regs = get_register (tok[tokidx].X_add_symbol);
   2010 		      regs <<= 16;
   2011 		      regs |= get_register (tok[tokidx].X_op_symbol);
   2012 		      if (operand->insert)
   2013 			{
   2014 			  tmpmsg = NULL;
   2015 			  (*operand->insert)(0,
   2016 					     regs,
   2017 					     &tmpmsg);
   2018 			  if (tmpmsg)
   2019 			    goto match_failed;
   2020 			}
   2021 		      else
   2022 			goto match_failed;
   2023 		      break;
   2024 		    }
   2025 		  /* Fall through.  */
   2026 		default:
   2027 		de_fault:
   2028 		  if (operand->default_reloc == 0)
   2029 		    goto match_failed; /* The operand needs relocation.  */
   2030 
   2031 		  /* Relocs requiring long immediate.  FIXME! make it
   2032 		     generic and move it to a function.  */
   2033 		  switch (tok[tokidx].X_md)
   2034 		    {
   2035 		    case O_gotoff:
   2036 		    case O_gotpc:
   2037 		    case O_pcl:
   2038 		    case O_tpoff:
   2039 		    case O_dtpoff:
   2040 		    case O_tlsgd:
   2041 		    case O_tlsie:
   2042 		      if (!(operand->flags & ARC_OPERAND_LIMM))
   2043 			goto match_failed;
   2044 		      /* Fall through.  */
   2045 		    case O_absent:
   2046 		      if (!generic_reloc_p (operand->default_reloc))
   2047 			goto match_failed;
   2048 		      break;
   2049 		    default:
   2050 		      break;
   2051 		    }
   2052 		  break;
   2053 		}
   2054 	      /* If expect duplicate, make sure it is duplicate.  */
   2055 	      if (operand->flags & ARC_OPERAND_DUPLICATE)
   2056 		{
   2057 		  if (t->X_op == O_illegal
   2058 		      || t->X_op == O_absent
   2059 		      || t->X_op == O_register
   2060 		      || (t->X_add_number != tok[tokidx].X_add_number))
   2061 		    {
   2062 		      tmpmsg = _("operand is not duplicate of the "
   2063 				 "previous one");
   2064 		      goto match_failed;
   2065 		    }
   2066 		}
   2067 	      t = &tok[tokidx];
   2068 	      break;
   2069 
   2070 	    default:
   2071 	      /* Everything else should have been fake.  */
   2072 	      abort ();
   2073 	    }
   2074 
   2075 	  ++tokidx;
   2076 	}
   2077       pr_debug ("opr ");
   2078 
   2079       /* Setup ready for flag parsing.  */
   2080       if (!parse_opcode_flags (opcode, nflgs, first_pflag))
   2081 	{
   2082 	  tmpmsg = _("flag mismatch");
   2083 	  goto match_failed;
   2084 	}
   2085 
   2086       pr_debug ("flg");
   2087       /* Possible match -- did we use all of our input?  */
   2088       if (tokidx == ntok)
   2089 	{
   2090 	  *pntok = ntok;
   2091 	  pr_debug ("\n");
   2092 	  return opcode;
   2093 	}
   2094       tmpmsg = _("too many arguments");
   2095 
   2096     match_failed:;
   2097       pr_debug ("\n");
   2098       /* Restore the original parameters.  */
   2099       memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
   2100       ntok = bkntok;
   2101       if (tokidx >= maxerridx
   2102 	  && tmpmsg)
   2103 	{
   2104 	  maxerridx = tokidx;
   2105 	  *errmsg = tmpmsg;
   2106 	}
   2107     }
   2108 
   2109   if (*pcpumatch)
   2110     *pcpumatch = got_cpu_match;
   2111 
   2112   return NULL;
   2113 }
   2114 
   2115 /* Swap operand tokens.  */
   2116 
   2117 static void
   2118 swap_operand (expressionS *operand_array,
   2119 	      unsigned source,
   2120 	      unsigned destination)
   2121 {
   2122   expressionS cpy_operand;
   2123   expressionS *src_operand;
   2124   expressionS *dst_operand;
   2125   size_t size;
   2126 
   2127   if (source == destination)
   2128     return;
   2129 
   2130   src_operand = &operand_array[source];
   2131   dst_operand = &operand_array[destination];
   2132   size = sizeof (expressionS);
   2133 
   2134   /* Make copy of operand to swap with and swap.  */
   2135   memcpy (&cpy_operand, dst_operand, size);
   2136   memcpy (dst_operand, src_operand, size);
   2137   memcpy (src_operand, &cpy_operand, size);
   2138 }
   2139 
   2140 /* Check if *op matches *tok type.
   2141    Returns FALSE if they don't match, TRUE if they match.  */
   2142 
   2143 static bool
   2144 pseudo_operand_match (const expressionS *tok,
   2145 		      const struct arc_operand_operation *op)
   2146 {
   2147   offsetT min, max, val;
   2148   bool ret;
   2149   const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
   2150 
   2151   ret = false;
   2152   switch (tok->X_op)
   2153     {
   2154     case O_constant:
   2155       if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
   2156 	ret = 1;
   2157       else if (!(operand_real->flags & ARC_OPERAND_IR))
   2158 	{
   2159 	  val = tok->X_add_number + op->count;
   2160 	  if (operand_real->flags & ARC_OPERAND_SIGNED)
   2161 	    {
   2162 	      max = (1 << (operand_real->bits - 1)) - 1;
   2163 	      min = -(1 << (operand_real->bits - 1));
   2164 	    }
   2165 	  else
   2166 	    {
   2167 	      max = (1 << operand_real->bits) - 1;
   2168 	      min = 0;
   2169 	    }
   2170 	  if (min <= val && val <= max)
   2171 	    ret = true;
   2172 	}
   2173       break;
   2174 
   2175     case O_symbol:
   2176       /* Handle all symbols as long immediates or signed 9.  */
   2177       if (operand_real->flags & ARC_OPERAND_LIMM
   2178 	  || ((operand_real->flags & ARC_OPERAND_SIGNED)
   2179 	      && operand_real->bits == 9))
   2180 	ret = true;
   2181       break;
   2182 
   2183     case O_register:
   2184       if (operand_real->flags & ARC_OPERAND_IR)
   2185 	ret = true;
   2186       break;
   2187 
   2188     case O_bracket:
   2189       if (operand_real->flags & ARC_OPERAND_BRAKET)
   2190 	ret = true;
   2191       break;
   2192 
   2193     default:
   2194       /* Unknown.  */
   2195       break;
   2196     }
   2197   return ret;
   2198 }
   2199 
   2200 /* Find pseudo instruction in array.  */
   2201 
   2202 static const struct arc_pseudo_insn *
   2203 find_pseudo_insn (const char *opname,
   2204 		  int ntok,
   2205 		  const expressionS *tok)
   2206 {
   2207   const struct arc_pseudo_insn *pseudo_insn = NULL;
   2208   const struct arc_operand_operation *op;
   2209   unsigned int i;
   2210   int j;
   2211 
   2212   for (i = 0; i < arc_num_pseudo_insn; ++i)
   2213     {
   2214       pseudo_insn = &arc_pseudo_insns[i];
   2215       if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
   2216 	{
   2217 	  op = pseudo_insn->operand;
   2218 	  for (j = 0; j < ntok; ++j)
   2219 	    if (!pseudo_operand_match (&tok[j], &op[j]))
   2220 	      break;
   2221 
   2222 	  /* Found the right instruction.  */
   2223 	  if (j == ntok)
   2224 	    return pseudo_insn;
   2225 	}
   2226     }
   2227   return NULL;
   2228 }
   2229 
   2230 /* Assumes the expressionS *tok is of sufficient size.  */
   2231 
   2232 static const struct arc_opcode_hash_entry *
   2233 find_special_case_pseudo (const char *opname,
   2234 			  int *ntok,
   2235 			  expressionS *tok,
   2236 			  int *nflgs,
   2237 			  struct arc_flags *pflags)
   2238 {
   2239   const struct arc_pseudo_insn *pseudo_insn = NULL;
   2240   const struct arc_operand_operation *operand_pseudo;
   2241   const struct arc_operand *operand_real;
   2242   unsigned i;
   2243   char construct_operand[MAX_CONSTR_STR];
   2244 
   2245   /* Find whether opname is in pseudo instruction array.  */
   2246   pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
   2247 
   2248   if (pseudo_insn == NULL)
   2249     return NULL;
   2250 
   2251   /* Handle flag, Limited to one flag at the moment.  */
   2252   if (pseudo_insn->flag_r != NULL)
   2253     *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
   2254 			      MAX_INSN_FLGS - *nflgs);
   2255 
   2256   /* Handle operand operations.  */
   2257   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
   2258     {
   2259       operand_pseudo = &pseudo_insn->operand[i];
   2260       operand_real = &arc_operands[operand_pseudo->operand_idx];
   2261 
   2262       if (operand_real->flags & ARC_OPERAND_BRAKET
   2263 	  && !operand_pseudo->needs_insert)
   2264 	continue;
   2265 
   2266       /* Has to be inserted (i.e. this token does not exist yet).  */
   2267       if (operand_pseudo->needs_insert)
   2268 	{
   2269 	  if (operand_real->flags & ARC_OPERAND_BRAKET)
   2270 	    {
   2271 	      tok[i].X_op = O_bracket;
   2272 	      ++(*ntok);
   2273 	      continue;
   2274 	    }
   2275 
   2276 	  /* Check if operand is a register or constant and handle it
   2277 	     by type.  */
   2278 	  if (operand_real->flags & ARC_OPERAND_IR)
   2279 	    snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
   2280 		      operand_pseudo->count);
   2281 	  else
   2282 	    snprintf (construct_operand, MAX_CONSTR_STR, "%d",
   2283 		      operand_pseudo->count);
   2284 
   2285 	  tokenize_arguments (construct_operand, &tok[i], 1);
   2286 	  ++(*ntok);
   2287 	}
   2288 
   2289       else if (operand_pseudo->count)
   2290 	{
   2291 	  /* Operand number has to be adjusted accordingly (by operand
   2292 	     type).  */
   2293 	  switch (tok[i].X_op)
   2294 	    {
   2295 	    case O_constant:
   2296 	      tok[i].X_add_number += operand_pseudo->count;
   2297 	      break;
   2298 
   2299 	    case O_symbol:
   2300 	      break;
   2301 
   2302 	    default:
   2303 	      /* Ignored.  */
   2304 	      break;
   2305 	    }
   2306 	}
   2307     }
   2308 
   2309   /* Swap operands if necessary.  Only supports one swap at the
   2310      moment.  */
   2311   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
   2312     {
   2313       operand_pseudo = &pseudo_insn->operand[i];
   2314 
   2315       if (operand_pseudo->swap_operand_idx == i)
   2316 	continue;
   2317 
   2318       swap_operand (tok, i, operand_pseudo->swap_operand_idx);
   2319 
   2320       /* Prevent a swap back later by breaking out.  */
   2321       break;
   2322     }
   2323 
   2324   return arc_find_opcode (pseudo_insn->mnemonic_r);
   2325 }
   2326 
   2327 static const struct arc_opcode_hash_entry *
   2328 find_special_case_flag (const char *opname,
   2329 			int *nflgs,
   2330 			struct arc_flags *pflags)
   2331 {
   2332   unsigned int i;
   2333   const char *flagnm;
   2334   unsigned flag_idx, flag_arr_idx;
   2335   size_t flaglen, oplen;
   2336   const struct arc_flag_special *arc_flag_special_opcode;
   2337   const struct arc_opcode_hash_entry *entry;
   2338 
   2339   /* Search for special case instruction.  */
   2340   for (i = 0; i < arc_num_flag_special; i++)
   2341     {
   2342       arc_flag_special_opcode = &arc_flag_special_cases[i];
   2343       oplen = strlen (arc_flag_special_opcode->name);
   2344 
   2345       if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
   2346 	continue;
   2347 
   2348       /* Found a potential special case instruction, now test for
   2349 	 flags.  */
   2350       for (flag_arr_idx = 0;; ++flag_arr_idx)
   2351 	{
   2352 	  flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
   2353 	  if (flag_idx == 0)
   2354 	    break;  /* End of array, nothing found.  */
   2355 
   2356 	  flagnm = arc_flag_operands[flag_idx].name;
   2357 	  flaglen = strlen (flagnm);
   2358 	  if (strcmp (opname + oplen, flagnm) == 0)
   2359 	    {
   2360               entry = arc_find_opcode (arc_flag_special_opcode->name);
   2361 
   2362 	      if (*nflgs + 1 > MAX_INSN_FLGS)
   2363 		break;
   2364 	      memcpy (pflags[*nflgs].name, flagnm, flaglen);
   2365 	      pflags[*nflgs].name[flaglen] = '\0';
   2366 	      (*nflgs)++;
   2367 	      return entry;
   2368 	    }
   2369 	}
   2370     }
   2371   return NULL;
   2372 }
   2373 
   2374 /* Used to find special case opcode.  */
   2375 
   2376 static const struct arc_opcode_hash_entry *
   2377 find_special_case (const char *opname,
   2378 		   int *nflgs,
   2379 		   struct arc_flags *pflags,
   2380 		   expressionS *tok,
   2381 		   int *ntok)
   2382 {
   2383   const struct arc_opcode_hash_entry *entry;
   2384 
   2385   entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
   2386 
   2387   if (entry == NULL)
   2388     entry = find_special_case_flag (opname, nflgs, pflags);
   2389 
   2390   return entry;
   2391 }
   2392 
   2393 /* Autodetect cpu attribute list.  */
   2394 
   2395 static void
   2396 autodetect_attributes (const struct arc_opcode *opcode,
   2397 			 const expressionS *tok,
   2398 			 int ntok)
   2399 {
   2400   unsigned i;
   2401   struct mpy_type
   2402   {
   2403     unsigned feature;
   2404     unsigned encoding;
   2405   } mpy_list[] = {{ MPY1E, 1 }, { MPY6E, 6 }, { MPY7E, 7 }, { MPY8E, 8 },
   2406 		 { MPY9E, 9 }};
   2407 
   2408   for (i = 0; i < ARRAY_SIZE (feature_list); i++)
   2409     if (opcode->subclass == feature_list[i].feature)
   2410       selected_cpu.features |= feature_list[i].feature;
   2411 
   2412   for (i = 0; i < ARRAY_SIZE (mpy_list); i++)
   2413     if (opcode->subclass == mpy_list[i].feature)
   2414       mpy_option = mpy_list[i].encoding;
   2415 
   2416   for (i = 0; i < (unsigned) ntok; i++)
   2417     {
   2418       switch (tok[i].X_md)
   2419 	{
   2420 	case O_gotoff:
   2421 	case O_gotpc:
   2422 	case O_plt:
   2423 	  pic_option = 2;
   2424 	  break;
   2425 	case O_sda:
   2426 	  sda_option = 2;
   2427 	  break;
   2428 	case O_tlsgd:
   2429 	case O_tlsie:
   2430 	case O_tpoff9:
   2431 	case O_tpoff:
   2432 	case O_dtpoff9:
   2433 	case O_dtpoff:
   2434 	  tls_option = 1;
   2435 	  break;
   2436 	default:
   2437 	  break;
   2438 	}
   2439 
   2440       switch (tok[i].X_op)
   2441 	{
   2442 	case O_register:
   2443 	  if ((tok[i].X_add_number >= 4 && tok[i].X_add_number <= 9)
   2444 	      || (tok[i].X_add_number >= 16 && tok[i].X_add_number <= 25))
   2445 	    rf16_only = false;
   2446 	  break;
   2447 	default:
   2448 	  break;
   2449 	}
   2450     }
   2451 }
   2452 
   2453 /* Given an opcode name, pre-tockenized set of argumenst and the
   2454    opcode flags, take it all the way through emission.  */
   2455 
   2456 static void
   2457 assemble_tokens (const char *opname,
   2458 		 expressionS *tok,
   2459 		 int ntok,
   2460 		 struct arc_flags *pflags,
   2461 		 int nflgs)
   2462 {
   2463   bool found_something = false;
   2464   const struct arc_opcode_hash_entry *entry;
   2465   int cpumatch = 1;
   2466   const char *errmsg = NULL;
   2467 
   2468   /* Search opcodes.  */
   2469   entry = arc_find_opcode (opname);
   2470 
   2471   /* Couldn't find opcode conventional way, try special cases.  */
   2472   if (entry == NULL)
   2473     entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
   2474 
   2475   if (entry != NULL)
   2476     {
   2477       const struct arc_opcode *opcode;
   2478 
   2479       pr_debug ("%s:%d: assemble_tokens: %s\n",
   2480 		frag_now->fr_file, frag_now->fr_line, opname);
   2481       found_something = true;
   2482       opcode = find_opcode_match (entry, tok, &ntok, pflags,
   2483 				  nflgs, &cpumatch, &errmsg);
   2484       if (opcode != NULL)
   2485 	{
   2486 	  struct arc_insn insn;
   2487 
   2488 	  autodetect_attributes (opcode,  tok, ntok);
   2489 	  assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
   2490 	  emit_insn (&insn);
   2491 	  return;
   2492 	}
   2493     }
   2494 
   2495   if (found_something)
   2496     {
   2497       if (cpumatch)
   2498 	if (errmsg)
   2499 	  as_bad (_("%s for instruction '%s'"), errmsg, opname);
   2500 	else
   2501 	  as_bad (_("inappropriate arguments for opcode '%s'"), opname);
   2502       else
   2503 	as_bad (_("opcode '%s' not supported for target %s"), opname,
   2504 		selected_cpu.name);
   2505     }
   2506   else
   2507     as_bad (_("unknown opcode '%s'"), opname);
   2508 }
   2509 
   2510 /* The public interface to the instruction assembler.  */
   2511 
   2512 void
   2513 md_assemble (char *str)
   2514 {
   2515   char *opname;
   2516   expressionS tok[MAX_INSN_ARGS];
   2517   int ntok, nflg;
   2518   size_t opnamelen;
   2519   struct arc_flags flags[MAX_INSN_FLGS];
   2520 
   2521   /* Split off the opcode.  */
   2522   opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123456789");
   2523   opname = xmemdup0 (str, opnamelen);
   2524 
   2525   /* Signalize we are assembling the instructions.  */
   2526   assembling_insn = true;
   2527 
   2528   /* Tokenize the flags.  */
   2529   if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
   2530     {
   2531       as_bad (_("syntax error"));
   2532       return;
   2533     }
   2534 
   2535   /* Scan up to the end of the mnemonic which must end in space or end
   2536      of string.  */
   2537   str += opnamelen;
   2538   for (; !is_end_of_stmt (*str); str++)
   2539     if (is_whitespace (*str))
   2540       break;
   2541 
   2542   /* Tokenize the rest of the line.  */
   2543   if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
   2544     {
   2545       as_bad (_("syntax error"));
   2546       return;
   2547     }
   2548 
   2549   /* Finish it off.  */
   2550   assemble_tokens (opname, tok, ntok, flags, nflg);
   2551   assembling_insn = false;
   2552 }
   2553 
   2554 /* Callback to insert a register into the hash table.  */
   2555 
   2556 static void
   2557 declare_register (const char *name, int number)
   2558 {
   2559   symbolS *regS = symbol_create (name, reg_section,
   2560 				 &zero_address_frag, number);
   2561 
   2562   if (str_hash_insert (arc_reg_hash, S_GET_NAME (regS), regS, 0) != NULL)
   2563     as_fatal (_("duplicate %s"), name);
   2564 }
   2565 
   2566 /* Construct symbols for each of the general registers.  */
   2567 
   2568 static void
   2569 declare_register_set (void)
   2570 {
   2571   int i;
   2572   for (i = 0; i < 64; ++i)
   2573     {
   2574       char name[32];
   2575 
   2576       sprintf (name, "r%d", i);
   2577       declare_register (name, i);
   2578       if ((i & 0x01) == 0)
   2579 	{
   2580 	  sprintf (name, "r%dr%d", i, i+1);
   2581 	  declare_register (name, i);
   2582 	}
   2583     }
   2584 }
   2585 
   2586 /* Construct a symbol for an address type.  */
   2587 
   2588 static void
   2589 declare_addrtype (const char *name, int number)
   2590 {
   2591   symbolS *addrtypeS = symbol_create (name, undefined_section,
   2592 				      &zero_address_frag, number);
   2593 
   2594   if (str_hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS), addrtypeS, 0))
   2595     as_fatal (_("duplicate %s"), name);
   2596 }
   2597 
   2598 /* Port-specific assembler initialization.  This function is called
   2599    once, at assembler startup time.  */
   2600 
   2601 void
   2602 md_begin (void)
   2603 {
   2604   const struct arc_opcode *opcode = arc_opcodes;
   2605 
   2606   if (mach_selection_mode == MACH_SELECTION_NONE)
   2607     arc_select_cpu (TARGET_WITH_CPU, MACH_SELECTION_FROM_DEFAULT);
   2608 
   2609   /* The endianness can be chosen "at the factory".  */
   2610   target_big_endian = byte_order == BIG_ENDIAN;
   2611 
   2612   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
   2613     as_warn (_("could not set architecture and machine"));
   2614 
   2615   /* Set elf header flags.  */
   2616   bfd_set_private_flags (stdoutput, selected_cpu.eflags);
   2617 
   2618   /* Set up a hash table for the instructions.  */
   2619   arc_opcode_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
   2620 				       arc_opcode_free, xcalloc, free);
   2621 
   2622   /* Initialize the hash table with the insns.  */
   2623   do
   2624     {
   2625       const char *name = opcode->name;
   2626 
   2627       arc_insert_opcode (opcode);
   2628 
   2629       while (++opcode && opcode->name
   2630 	     && (opcode->name == name
   2631 		 || !strcmp (opcode->name, name)))
   2632 	continue;
   2633     }while (opcode->name);
   2634 
   2635   /* Register declaration.  */
   2636   arc_reg_hash = str_htab_create ();
   2637 
   2638   declare_register_set ();
   2639   declare_register ("gp", 26);
   2640   declare_register ("fp", 27);
   2641   declare_register ("sp", 28);
   2642   declare_register ("ilink", 29);
   2643   declare_register ("ilink1", 29);
   2644   declare_register ("ilink2", 30);
   2645   declare_register ("blink", 31);
   2646 
   2647   /* XY memory registers.  */
   2648   declare_register ("x0_u0", 32);
   2649   declare_register ("x0_u1", 33);
   2650   declare_register ("x1_u0", 34);
   2651   declare_register ("x1_u1", 35);
   2652   declare_register ("x2_u0", 36);
   2653   declare_register ("x2_u1", 37);
   2654   declare_register ("x3_u0", 38);
   2655   declare_register ("x3_u1", 39);
   2656   declare_register ("y0_u0", 40);
   2657   declare_register ("y0_u1", 41);
   2658   declare_register ("y1_u0", 42);
   2659   declare_register ("y1_u1", 43);
   2660   declare_register ("y2_u0", 44);
   2661   declare_register ("y2_u1", 45);
   2662   declare_register ("y3_u0", 46);
   2663   declare_register ("y3_u1", 47);
   2664   declare_register ("x0_nu", 48);
   2665   declare_register ("x1_nu", 49);
   2666   declare_register ("x2_nu", 50);
   2667   declare_register ("x3_nu", 51);
   2668   declare_register ("y0_nu", 52);
   2669   declare_register ("y1_nu", 53);
   2670   declare_register ("y2_nu", 54);
   2671   declare_register ("y3_nu", 55);
   2672 
   2673   declare_register ("mlo", 57);
   2674   declare_register ("mmid", 58);
   2675   declare_register ("mhi", 59);
   2676 
   2677   declare_register ("acc1", 56);
   2678   declare_register ("acc2", 57);
   2679 
   2680   declare_register ("lp_count", 60);
   2681   declare_register ("pcl", 63);
   2682 
   2683   /* Initialize the last instructions.  */
   2684   memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
   2685 
   2686   /* Aux register declaration.  */
   2687   arc_aux_hash = str_htab_create ();
   2688 
   2689   const struct arc_aux_reg *auxr = &arc_aux_regs[0];
   2690   unsigned int i;
   2691   for (i = 0; i < arc_num_aux_regs; i++, auxr++)
   2692     {
   2693       if (!(auxr->cpu & selected_cpu.flags))
   2694 	continue;
   2695 
   2696       if ((auxr->subclass != NONE)
   2697 	  && !check_cpu_feature (auxr->subclass))
   2698 	continue;
   2699 
   2700       if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != 0)
   2701 	as_fatal (_("duplicate %s"), auxr->name);
   2702     }
   2703 
   2704   /* Address type declaration.  */
   2705   arc_addrtype_hash = str_htab_create ();
   2706 
   2707   declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD);
   2708   declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID);
   2709   declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD);
   2710   declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD);
   2711   declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD);
   2712   declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM);
   2713   declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA);
   2714   declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD);
   2715   declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD);
   2716   declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD);
   2717   declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID);
   2718   declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD);
   2719   declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM);
   2720   declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD);
   2721   declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA);
   2722   declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD);
   2723 }
   2724 
   2725 void
   2726 arc_md_end (void)
   2727 {
   2728   htab_delete (arc_opcode_hash);
   2729   htab_delete (arc_reg_hash);
   2730   htab_delete (arc_aux_hash);
   2731   htab_delete (arc_addrtype_hash);
   2732 }
   2733 
   2734 /* Write a value out to the object file, using the appropriate
   2735    endianness.  */
   2736 
   2737 void
   2738 md_number_to_chars (char *buf,
   2739 		    valueT val,
   2740 		    int n)
   2741 {
   2742   if (target_big_endian)
   2743     number_to_chars_bigendian (buf, val, n);
   2744   else
   2745     number_to_chars_littleendian (buf, val, n);
   2746 }
   2747 
   2748 /* Round up a section size to the appropriate boundary.  */
   2749 
   2750 valueT
   2751 md_section_align (segT segment,
   2752 		  valueT size)
   2753 {
   2754   int align = bfd_section_alignment (segment);
   2755 
   2756   return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
   2757 }
   2758 
   2759 /* The location from which a PC relative jump should be calculated,
   2760    given a PC relative reloc.  */
   2761 
   2762 long
   2763 md_pcrel_from_section (fixS *fixP,
   2764 		       segT sec)
   2765 {
   2766   offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
   2767 
   2768   pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
   2769 
   2770   if (fixP->fx_addsy != NULL
   2771       && (!S_IS_DEFINED (fixP->fx_addsy)
   2772 	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
   2773     {
   2774       pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
   2775 
   2776       /* The symbol is undefined (or is defined but not in this section).
   2777 	 Let the linker figure it out.  */
   2778       return 0;
   2779     }
   2780 
   2781   if ((int) fixP->fx_r_type < 0)
   2782     {
   2783       /* These are the "internal" relocations.  Align them to
   2784 	 32 bit boundary (PCL), for the moment.  */
   2785       base &= ~3;
   2786     }
   2787   else
   2788     {
   2789       switch (fixP->fx_r_type)
   2790 	{
   2791 	case BFD_RELOC_ARC_PC32:
   2792 	  /* The hardware calculates relative to the start of the
   2793 	     insn, but this relocation is relative to location of the
   2794 	     LIMM, compensate.  The base always needs to be
   2795 	     subtracted by 4 as we do not support this type of PCrel
   2796 	     relocation for short instructions.  */
   2797 	  base -= 4;
   2798 	  /* Fall through.  */
   2799 	case BFD_RELOC_ARC_PLT32:
   2800 	case BFD_RELOC_ARC_S25H_PCREL_PLT:
   2801 	case BFD_RELOC_ARC_S21H_PCREL_PLT:
   2802 	case BFD_RELOC_ARC_S25W_PCREL_PLT:
   2803 	case BFD_RELOC_ARC_S21W_PCREL_PLT:
   2804 
   2805 	case BFD_RELOC_ARC_S21H_PCREL:
   2806 	case BFD_RELOC_ARC_S25H_PCREL:
   2807 	case BFD_RELOC_ARC_S13_PCREL:
   2808 	case BFD_RELOC_ARC_S21W_PCREL:
   2809 	case BFD_RELOC_ARC_S25W_PCREL:
   2810 	  base &= ~3;
   2811 	  break;
   2812 	default:
   2813 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   2814 			_("unhandled reloc %s in md_pcrel_from_section"),
   2815 		  bfd_get_reloc_code_name (fixP->fx_r_type));
   2816 	  break;
   2817 	}
   2818     }
   2819 
   2820   pr_debug ("pcrel from %" PRIx64 " + %lx = %" PRIx64 ", "
   2821 	    "symbol: %s (%" PRIx64 ")\n",
   2822 	    (uint64_t) fixP->fx_frag->fr_address, fixP->fx_where, (uint64_t) base,
   2823 	    fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
   2824 	    fixP->fx_addsy ? (uint64_t) S_GET_VALUE (fixP->fx_addsy) : (uint64_t) 0);
   2825 
   2826   return base;
   2827 }
   2828 
   2829 /* Given a BFD relocation find the corresponding operand.  */
   2830 
   2831 static const struct arc_operand *
   2832 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
   2833 {
   2834   unsigned i;
   2835 
   2836   for (i = 0; i < arc_num_operands; i++)
   2837     if (arc_operands[i].default_reloc == reloc)
   2838       return  &arc_operands[i];
   2839   return NULL;
   2840 }
   2841 
   2842 /* Insert an operand value into an instruction.  */
   2843 
   2844 static unsigned long long
   2845 insert_operand (unsigned long long insn,
   2846 		const struct arc_operand *operand,
   2847 		long long val,
   2848 		const char *file,
   2849 		unsigned line)
   2850 {
   2851   offsetT min = 0, max = 0;
   2852 
   2853   if (operand->bits != 32
   2854       && !(operand->flags & ARC_OPERAND_NCHK)
   2855       && !(operand->flags & ARC_OPERAND_FAKE))
   2856     {
   2857       if (operand->flags & ARC_OPERAND_SIGNED)
   2858 	{
   2859 	  max = (1 << (operand->bits - 1)) - 1;
   2860 	  min = -(1 << (operand->bits - 1));
   2861 	}
   2862       else
   2863 	{
   2864 	  max = (1 << operand->bits) - 1;
   2865 	  min = 0;
   2866 	}
   2867 
   2868       if (val < min || val > max)
   2869 	as_bad_value_out_of_range (_("operand"),
   2870 				   val, min, max, file, line);
   2871     }
   2872 
   2873   pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
   2874 	    min, val, max, insn);
   2875 
   2876   if ((operand->flags & ARC_OPERAND_ALIGNED32)
   2877       && (val & 0x03))
   2878     as_bad_where (file, line,
   2879 		  _("Unaligned operand. Needs to be 32bit aligned"));
   2880 
   2881   if ((operand->flags & ARC_OPERAND_ALIGNED16)
   2882       && (val & 0x01))
   2883     as_bad_where (file, line,
   2884 		  _("Unaligned operand. Needs to be 16bit aligned"));
   2885 
   2886   if (operand->insert)
   2887     {
   2888       const char *errmsg = NULL;
   2889 
   2890       insn = (*operand->insert) (insn, val, &errmsg);
   2891       if (errmsg)
   2892 	as_warn_where (file, line, "%s", errmsg);
   2893     }
   2894   else
   2895     {
   2896       if (operand->flags & ARC_OPERAND_TRUNCATE)
   2897 	{
   2898 	  if (operand->flags & ARC_OPERAND_ALIGNED32)
   2899 	    val >>= 2;
   2900 	  if (operand->flags & ARC_OPERAND_ALIGNED16)
   2901 	    val >>= 1;
   2902 	}
   2903       insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
   2904     }
   2905   return insn;
   2906 }
   2907 
   2908 /* Apply a fixup to the object code.  At this point all symbol values
   2909    should be fully resolved, and we attempt to completely resolve the
   2910    reloc.  If we can not do that, we determine the correct reloc code
   2911    and put it back in the fixup.  To indicate that a fixup has been
   2912    eliminated, set fixP->fx_done.  */
   2913 
   2914 void
   2915 md_apply_fix (fixS *fixP,
   2916 	      valueT *valP,
   2917 	      segT seg)
   2918 {
   2919   char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
   2920   valueT value = *valP;
   2921   unsigned insn = 0;
   2922   symbolS *fx_addsy, *fx_subsy;
   2923   offsetT fx_offset;
   2924   segT add_symbol_segment = absolute_section;
   2925   segT sub_symbol_segment = absolute_section;
   2926   const struct arc_operand *operand = NULL;
   2927   extended_bfd_reloc_code_real_type reloc;
   2928 
   2929   pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
   2930 	    fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
   2931 	    ((int) fixP->fx_r_type < 0) ? "Internal":
   2932 	    bfd_get_reloc_code_name (fixP->fx_r_type), value,
   2933 	    fixP->fx_offset);
   2934 
   2935   fx_addsy = fixP->fx_addsy;
   2936   fx_subsy = fixP->fx_subsy;
   2937   fx_offset = 0;
   2938 
   2939   if (fx_addsy)
   2940     {
   2941       add_symbol_segment = S_GET_SEGMENT (fx_addsy);
   2942     }
   2943 
   2944   if (fx_subsy
   2945       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
   2946       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
   2947       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
   2948     {
   2949       resolve_symbol_value (fx_subsy);
   2950       sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
   2951 
   2952       if (sub_symbol_segment == absolute_section)
   2953 	{
   2954 	  /* The symbol is really a constant.  */
   2955 	  fx_offset -= S_GET_VALUE (fx_subsy);
   2956 	  fx_subsy = NULL;
   2957 	}
   2958       else
   2959 	{
   2960 	  as_bad_subtract (fixP);
   2961 	  return;
   2962 	}
   2963     }
   2964 
   2965   if (fx_addsy
   2966       && !S_IS_WEAK (fx_addsy))
   2967     {
   2968       if (add_symbol_segment == seg
   2969 	  && fixP->fx_pcrel)
   2970 	{
   2971 	  value += S_GET_VALUE (fx_addsy);
   2972 	  value -= md_pcrel_from_section (fixP, seg);
   2973 	  fx_addsy = NULL;
   2974 	  fixP->fx_pcrel = false;
   2975 	}
   2976       else if (add_symbol_segment == absolute_section)
   2977 	{
   2978 	  value = fixP->fx_offset;
   2979 	  fx_offset += S_GET_VALUE (fixP->fx_addsy);
   2980 	  fx_addsy = NULL;
   2981 	  fixP->fx_pcrel = false;
   2982 	}
   2983     }
   2984 
   2985   if (!fx_addsy)
   2986     fixP->fx_done = true;
   2987 
   2988   if (fixP->fx_pcrel)
   2989     {
   2990       if (fx_addsy
   2991 	  && ((S_IS_DEFINED (fx_addsy)
   2992 	       && S_GET_SEGMENT (fx_addsy) != seg)
   2993 	      || S_IS_WEAK (fx_addsy)))
   2994 	value += md_pcrel_from_section (fixP, seg);
   2995 
   2996       switch (fixP->fx_r_type)
   2997 	{
   2998 	case BFD_RELOC_ARC_32_ME:
   2999 	  /* This is a pc-relative value in a LIMM.  Adjust it to the
   3000 	     address of the instruction not to the address of the
   3001 	     LIMM.  Note: it is not any longer valid this affirmation as
   3002 	     the linker consider ARC_PC32 a fixup to entire 64 bit
   3003 	     insn.  */
   3004 	  fixP->fx_offset += fixP->fx_frag->fr_address;
   3005 	  /* Fall through.  */
   3006 	case BFD_RELOC_32:
   3007 	  fixP->fx_r_type = BFD_RELOC_ARC_PC32;
   3008 	  /* Fall through.  */
   3009 	case BFD_RELOC_ARC_PC32:
   3010 	  /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
   3011 	  break;
   3012 	default:
   3013 	  if ((int) fixP->fx_r_type < 0)
   3014 	    as_bad_where (fixP->fx_file, fixP->fx_line,
   3015 			  _("PC relative relocation not allowed for (internal)"
   3016 			    " type %d"),
   3017 			  fixP->fx_r_type);
   3018 	  break;
   3019 	}
   3020     }
   3021 
   3022   pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
   3023 	    fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
   3024 	    ((int) fixP->fx_r_type < 0) ? "Internal":
   3025 	    bfd_get_reloc_code_name (fixP->fx_r_type), value,
   3026 	    fixP->fx_offset);
   3027 
   3028 
   3029   /* Now check for TLS relocations.  */
   3030   reloc = fixP->fx_r_type;
   3031   switch (reloc)
   3032     {
   3033     case BFD_RELOC_ARC_TLS_DTPOFF:
   3034     case BFD_RELOC_ARC_TLS_LE_32:
   3035       if (fixP->fx_done)
   3036 	break;
   3037       /* Fall through.  */
   3038     case BFD_RELOC_ARC_TLS_GD_GOT:
   3039     case BFD_RELOC_ARC_TLS_IE_GOT:
   3040       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   3041       break;
   3042 
   3043     case BFD_RELOC_ARC_TLS_GD_LD:
   3044       gas_assert (!fixP->fx_offset);
   3045       if (fixP->fx_subsy)
   3046 	fixP->fx_offset
   3047 	  = (S_GET_VALUE (fixP->fx_subsy)
   3048 	     - fixP->fx_frag->fr_address- fixP->fx_where);
   3049       fixP->fx_subsy = NULL;
   3050       /* Fall through.  */
   3051     case BFD_RELOC_ARC_TLS_GD_CALL:
   3052       /* These two relocs are there just to allow ld to change the tls
   3053 	 model for this symbol, by patching the code.  The offset -
   3054 	 and scale, if any - will be installed by the linker.  */
   3055       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   3056       break;
   3057 
   3058     case BFD_RELOC_ARC_TLS_LE_S9:
   3059     case BFD_RELOC_ARC_TLS_DTPOFF_S9:
   3060       as_bad (_("TLS_*_S9 relocs are not supported yet"));
   3061       break;
   3062 
   3063     default:
   3064       break;
   3065     }
   3066 
   3067   if (!fixP->fx_done)
   3068     {
   3069       return;
   3070     }
   3071 
   3072   /* Adjust the value if we have a constant.  */
   3073   value += fx_offset;
   3074 
   3075   /* For hosts with longs bigger than 32-bits make sure that the top
   3076      bits of a 32-bit negative value read in by the parser are set,
   3077      so that the correct comparisons are made.  */
   3078   if (value & 0x80000000)
   3079     value |= (-1UL << 31);
   3080 
   3081   reloc = fixP->fx_r_type;
   3082   switch (reloc)
   3083     {
   3084     case BFD_RELOC_8:
   3085     case BFD_RELOC_16:
   3086     case BFD_RELOC_24:
   3087     case BFD_RELOC_32:
   3088     case BFD_RELOC_64:
   3089     case BFD_RELOC_ARC_32_PCREL:
   3090       md_number_to_chars (fixpos, value, fixP->fx_size);
   3091       return;
   3092 
   3093     case BFD_RELOC_ARC_GOTPC32:
   3094       /* I cannot fix an GOTPC relocation because I need to relax it
   3095 	 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc.  */
   3096       as_bad (_("Unsupported operation on reloc"));
   3097       return;
   3098 
   3099     case BFD_RELOC_ARC_TLS_DTPOFF:
   3100     case BFD_RELOC_ARC_TLS_LE_32:
   3101       gas_assert (!fixP->fx_addsy);
   3102       gas_assert (!fixP->fx_subsy);
   3103       /* Fall through.  */
   3104 
   3105     case BFD_RELOC_ARC_GOTOFF:
   3106     case BFD_RELOC_ARC_32_ME:
   3107     case BFD_RELOC_ARC_PC32:
   3108       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
   3109       return;
   3110 
   3111     case BFD_RELOC_ARC_PLT32:
   3112       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
   3113       return;
   3114 
   3115     case BFD_RELOC_ARC_S25H_PCREL_PLT:
   3116       reloc = BFD_RELOC_ARC_S25W_PCREL;
   3117       goto solve_plt;
   3118 
   3119     case BFD_RELOC_ARC_S21H_PCREL_PLT:
   3120       reloc = BFD_RELOC_ARC_S21H_PCREL;
   3121       goto solve_plt;
   3122 
   3123     case BFD_RELOC_ARC_S25W_PCREL_PLT:
   3124       reloc = BFD_RELOC_ARC_S25W_PCREL;
   3125       goto solve_plt;
   3126 
   3127     case BFD_RELOC_ARC_S21W_PCREL_PLT:
   3128       reloc = BFD_RELOC_ARC_S21W_PCREL;
   3129       /* Fall through.  */
   3130 
   3131     case BFD_RELOC_ARC_S25W_PCREL:
   3132     case BFD_RELOC_ARC_S21W_PCREL:
   3133     case BFD_RELOC_ARC_S21H_PCREL:
   3134     case BFD_RELOC_ARC_S25H_PCREL:
   3135     case BFD_RELOC_ARC_S13_PCREL:
   3136     solve_plt:
   3137       operand = find_operand_for_reloc (reloc);
   3138       gas_assert (operand);
   3139       break;
   3140 
   3141     default:
   3142       {
   3143 	if ((int) fixP->fx_r_type >= 0)
   3144 	  as_fatal (_("unhandled relocation type %s"),
   3145 		    bfd_get_reloc_code_name (fixP->fx_r_type));
   3146 
   3147 	/* The rest of these fixups needs to be completely resolved as
   3148 	   constants.  */
   3149 	if (fixP->fx_addsy != 0
   3150 	    && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
   3151 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   3152 			_("non-absolute expression in constant field"));
   3153 
   3154 	gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
   3155 	operand = &arc_operands[-(int) fixP->fx_r_type];
   3156 	break;
   3157       }
   3158     }
   3159 
   3160   if (target_big_endian)
   3161     {
   3162       switch (fixP->fx_size)
   3163 	{
   3164 	case 4:
   3165 	  insn = bfd_getb32 (fixpos);
   3166 	  break;
   3167 	case 2:
   3168 	  insn = bfd_getb16 (fixpos);
   3169 	  break;
   3170 	default:
   3171 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   3172 			_("unknown fixup size"));
   3173 	}
   3174     }
   3175   else
   3176     {
   3177       insn = 0;
   3178       switch (fixP->fx_size)
   3179 	{
   3180 	case 4:
   3181 	  insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
   3182 	  break;
   3183 	case 2:
   3184 	  insn = bfd_getl16 (fixpos);
   3185 	  break;
   3186 	default:
   3187 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   3188 			_("unknown fixup size"));
   3189 	}
   3190     }
   3191 
   3192   insn = insert_operand (insn, operand, (offsetT) value,
   3193 			 fixP->fx_file, fixP->fx_line);
   3194 
   3195   md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
   3196 }
   3197 
   3198 /* Prepare machine-dependent frags for relaxation.
   3199 
   3200    Called just before relaxation starts.  Any symbol that is now undefined
   3201    will not become defined.
   3202 
   3203    Return the correct fr_subtype in the frag.
   3204 
   3205    Return the initial "guess for fr_var" to caller.  The guess for fr_var
   3206    is *actually* the growth beyond fr_fix.  Whatever we do to grow fr_fix
   3207    or fr_var contributes to our returned value.
   3208 
   3209    Although it may not be explicit in the frag, pretend
   3210    fr_var starts with a value.  */
   3211 
   3212 int
   3213 md_estimate_size_before_relax (fragS *fragP,
   3214 			       segT segment)
   3215 {
   3216   int growth;
   3217 
   3218   /* If the symbol is not located within the same section AND it's not
   3219      an absolute section, use the maximum.  OR if the symbol is a
   3220      constant AND the insn is by nature not pc-rel, use the maximum.
   3221      OR if the symbol is being equated against another symbol, use the
   3222      maximum.  OR if the symbol is weak use the maximum.  */
   3223   if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
   3224        && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
   3225       || (symbol_constant_p (fragP->fr_symbol)
   3226 	  && !fragP->tc_frag_data.pcrel)
   3227       || symbol_equated_p (fragP->fr_symbol)
   3228       || S_IS_WEAK (fragP->fr_symbol))
   3229     {
   3230       while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
   3231 	++fragP->fr_subtype;
   3232     }
   3233 
   3234   growth = md_relax_table[fragP->fr_subtype].rlx_length;
   3235   fragP->fr_var = growth;
   3236 
   3237   pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
   3238 	   fragP->fr_file, fragP->fr_line, growth);
   3239 
   3240   return growth;
   3241 }
   3242 
   3243 /* Translate internal representation of relocation info to BFD target
   3244    format.  */
   3245 
   3246 arelent *
   3247 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
   3248 	      fixS *fixP)
   3249 {
   3250   arelent *reloc;
   3251   bfd_reloc_code_real_type code;
   3252 
   3253   reloc = notes_alloc (sizeof (arelent));
   3254   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   3255   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   3256   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   3257 
   3258   /* Make sure none of our internal relocations make it this far.
   3259      They'd better have been fully resolved by this point.  */
   3260   gas_assert ((int) fixP->fx_r_type > 0);
   3261 
   3262   code = fixP->fx_r_type;
   3263 
   3264   /* if we have something like add gp, pcl,
   3265      _GLOBAL_OFFSET_TABLE_@gotpc.  */
   3266   if (code == BFD_RELOC_ARC_GOTPC32
   3267       && GOT_symbol
   3268       && fixP->fx_addsy == GOT_symbol)
   3269     code = BFD_RELOC_ARC_GOTPC;
   3270 
   3271   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   3272   if (reloc->howto == NULL)
   3273     {
   3274       as_bad_where (fixP->fx_file, fixP->fx_line,
   3275 		    _("cannot represent `%s' relocation in object file"),
   3276 		    bfd_get_reloc_code_name (code));
   3277       return NULL;
   3278     }
   3279 
   3280   if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
   3281     as_fatal (_("internal error? cannot generate `%s' relocation"),
   3282 	      bfd_get_reloc_code_name (code));
   3283 
   3284   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
   3285 
   3286   reloc->addend = fixP->fx_offset;
   3287 
   3288   return reloc;
   3289 }
   3290 
   3291 /* Perform post-processing of machine-dependent frags after relaxation.
   3292    Called after relaxation is finished.
   3293    In:	Address of frag.
   3294    fr_type == rs_machine_dependent.
   3295    fr_subtype is what the address relaxed to.
   3296 
   3297    Out: Any fixS:s and constants are set up.  */
   3298 
   3299 void
   3300 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   3301 		 segT segment ATTRIBUTE_UNUSED,
   3302 		 fragS *fragP)
   3303 {
   3304   const relax_typeS *table_entry;
   3305   char *dest;
   3306   const struct arc_opcode *opcode;
   3307   struct arc_insn insn;
   3308   int size, fix;
   3309   struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
   3310 
   3311   fix = fragP->fr_fix;
   3312   dest = fragP->fr_literal + fix;
   3313   table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
   3314 
   3315   pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
   3316 	    "var: %" PRId64 "\n",
   3317 	    fragP->fr_file, fragP->fr_line,
   3318 	    fragP->fr_subtype, fix, (int64_t) fragP->fr_var);
   3319 
   3320   if (fragP->fr_subtype <= 0
   3321       && fragP->fr_subtype >= arc_num_relax_opcodes)
   3322     as_fatal (_("no relaxation found for this instruction."));
   3323 
   3324   opcode = &arc_relax_opcodes[fragP->fr_subtype];
   3325 
   3326   assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
   3327 	relax_arg->nflg, &insn);
   3328 
   3329   apply_fixups (&insn, fragP, fix);
   3330 
   3331   size = insn.len + (insn.has_limm ? 4 : 0);
   3332   gas_assert (table_entry->rlx_length == size);
   3333   emit_insn0 (&insn, dest, true);
   3334 
   3335   fragP->fr_fix += table_entry->rlx_length;
   3336   fragP->fr_var = 0;
   3337 }
   3338 
   3339 /* We have no need to default values of symbols.  We could catch
   3340    register names here, but that is handled by inserting them all in
   3341    the symbol table to begin with.  */
   3342 
   3343 symbolS *
   3344 md_undefined_symbol (char *name)
   3345 {
   3346   /* The arc abi demands that a GOT[0] should be referencible as
   3347      [pc+_DYNAMIC@gotpc].  Hence we convert a _DYNAMIC@gotpc to a
   3348      GOTPC reference to _GLOBAL_OFFSET_TABLE_.  */
   3349   if (((*name == '_')
   3350        && (*(name+1) == 'G')
   3351        && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)))
   3352     {
   3353       if (!GOT_symbol)
   3354 	{
   3355 	  if (symbol_find (name))
   3356 	    as_bad ("GOT already in symbol table");
   3357 
   3358 	  GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
   3359 				   &zero_address_frag, 0);
   3360 	};
   3361       return GOT_symbol;
   3362     }
   3363   return NULL;
   3364 }
   3365 
   3366 /* Turn a string in input_line_pointer into a floating point constant
   3367    of type type, and store the appropriate bytes in *litP.  The number
   3368    of LITTLENUMS emitted is stored in *sizeP.  An error message is
   3369    returned, or NULL on OK.  */
   3370 
   3371 const char *
   3372 md_atof (int type, char *litP, int *sizeP)
   3373 {
   3374   return ieee_md_atof (type, litP, sizeP, target_big_endian);
   3375 }
   3376 
   3377 /* Called for any expression that can not be recognized.  When the
   3378    function is called, `input_line_pointer' will point to the start of
   3379    the expression.  We use it when we have complex operations like
   3380    @label1 - @label2.  */
   3381 
   3382 void
   3383 md_operand (expressionS *expressionP)
   3384 {
   3385   char *p = input_line_pointer;
   3386   if (*p == '@')
   3387     {
   3388       input_line_pointer++;
   3389       expressionP->X_op = O_symbol;
   3390       expressionP->X_md = O_absent;
   3391       expression (expressionP);
   3392     }
   3393 }
   3394 
   3395 /* This function is called from the function 'expression', it attempts
   3396    to parse special names (in our case register names).  It fills in
   3397    the expression with the identified register.  It returns TRUE if
   3398    it is a register and FALSE otherwise.  */
   3399 
   3400 bool
   3401 arc_parse_name (const char *name,
   3402 		struct expressionS *e)
   3403 {
   3404   struct symbol *sym;
   3405 
   3406   if (!assembling_insn)
   3407     return false;
   3408 
   3409   if (e->X_op == O_symbol
   3410       && e->X_md == O_absent)
   3411     return false;
   3412 
   3413   sym = str_hash_find (arc_reg_hash, name);
   3414   if (sym)
   3415     {
   3416       e->X_op = O_register;
   3417       e->X_add_number = S_GET_VALUE (sym);
   3418       return true;
   3419     }
   3420 
   3421   sym = str_hash_find (arc_addrtype_hash, name);
   3422   if (sym)
   3423     {
   3424       e->X_op = O_addrtype;
   3425       e->X_add_number = S_GET_VALUE (sym);
   3426       return true;
   3427     }
   3428 
   3429   return false;
   3430 }
   3431 
   3432 /* md_parse_option
   3433    Invocation line includes a switch not recognized by the base assembler.
   3434    See if it's a processor-specific option.
   3435 
   3436    New options (supported) are:
   3437 
   3438    -mcpu=<cpu name>		 Assemble for selected processor
   3439    -EB/-mbig-endian		 Big-endian
   3440    -EL/-mlittle-endian		 Little-endian
   3441    -mrelax                       Enable relaxation
   3442 
   3443    The following CPU names are recognized:
   3444    arc600, arc700, arcem, archs, nps400.  */
   3445 
   3446 int
   3447 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
   3448 {
   3449   switch (c)
   3450     {
   3451     case OPTION_ARC600:
   3452     case OPTION_ARC601:
   3453       return md_parse_option (OPTION_MCPU, "arc600");
   3454 
   3455     case OPTION_ARC700:
   3456       return md_parse_option (OPTION_MCPU, "arc700");
   3457 
   3458     case OPTION_ARCEM:
   3459       return md_parse_option (OPTION_MCPU, "arcem");
   3460 
   3461     case OPTION_ARCHS:
   3462       return md_parse_option (OPTION_MCPU, "archs");
   3463 
   3464     case OPTION_MCPU:
   3465       {
   3466         arc_select_cpu (arg, MACH_SELECTION_FROM_COMMAND_LINE);
   3467 	break;
   3468       }
   3469 
   3470     case OPTION_EB:
   3471       arc_target_format = "elf32-bigarc";
   3472       byte_order = BIG_ENDIAN;
   3473       break;
   3474 
   3475     case OPTION_EL:
   3476       arc_target_format = "elf32-littlearc";
   3477       byte_order = LITTLE_ENDIAN;
   3478       break;
   3479 
   3480     case OPTION_CD:
   3481       selected_cpu.features |= CD;
   3482       cl_features |= CD;
   3483       arc_check_feature ();
   3484       break;
   3485 
   3486     case OPTION_RELAX:
   3487       relaxation_state = 1;
   3488       break;
   3489 
   3490     case OPTION_NPS400:
   3491       selected_cpu.features |= NPS400;
   3492       cl_features |= NPS400;
   3493       arc_check_feature ();
   3494       break;
   3495 
   3496     case OPTION_SPFP:
   3497       selected_cpu.features |= SPX;
   3498       cl_features |= SPX;
   3499       arc_check_feature ();
   3500       break;
   3501 
   3502     case OPTION_DPFP:
   3503       selected_cpu.features |= DPX;
   3504       cl_features |= DPX;
   3505       arc_check_feature ();
   3506       break;
   3507 
   3508     case OPTION_FPUDA:
   3509       selected_cpu.features |= DPA;
   3510       cl_features |= DPA;
   3511       arc_check_feature ();
   3512       break;
   3513 
   3514     /* Dummy options are accepted but have no effect.  */
   3515     case OPTION_USER_MODE:
   3516     case OPTION_LD_EXT_MASK:
   3517     case OPTION_SWAP:
   3518     case OPTION_NORM:
   3519     case OPTION_BARREL_SHIFT:
   3520     case OPTION_MIN_MAX:
   3521     case OPTION_NO_MPY:
   3522     case OPTION_EA:
   3523     case OPTION_MUL64:
   3524     case OPTION_SIMD:
   3525     case OPTION_XMAC_D16:
   3526     case OPTION_XMAC_24:
   3527     case OPTION_DSP_PACKA:
   3528     case OPTION_CRC:
   3529     case OPTION_DVBF:
   3530     case OPTION_TELEPHONY:
   3531     case OPTION_XYMEMORY:
   3532     case OPTION_LOCK:
   3533     case OPTION_SWAPE:
   3534     case OPTION_RTSC:
   3535       break;
   3536 
   3537     default:
   3538       return 0;
   3539     }
   3540 
   3541   return 1;
   3542 }
   3543 
   3544 /* Display the list of cpu names for use in the help text.  */
   3545 
   3546 static void
   3547 arc_show_cpu_list (FILE *stream)
   3548 {
   3549   int i, offset;
   3550   static const char *space_buf = "                          ";
   3551 
   3552   fprintf (stream, "%s", space_buf);
   3553   offset = strlen (space_buf);
   3554   for (i = 0; cpu_types[i].name != NULL; ++i)
   3555     {
   3556       bool last = (cpu_types[i + 1].name == NULL);
   3557 
   3558       /* If displaying the new cpu name string, and the ', ' (for all
   3559          but the last one) will take us past a target width of 80
   3560          characters, then it's time for a new line.  */
   3561       if (offset + strlen (cpu_types[i].name) + (last ? 0 : 2) > 80)
   3562         {
   3563           fprintf (stream, "\n%s", space_buf);
   3564           offset = strlen (space_buf);
   3565         }
   3566 
   3567       fprintf (stream, "%s%s", cpu_types[i].name, (last ? "\n" : ", "));
   3568       offset += strlen (cpu_types [i].name) + (last ? 0 : 2);
   3569     }
   3570 }
   3571 
   3572 void
   3573 md_show_usage (FILE *stream)
   3574 {
   3575   fprintf (stream, _("ARC-specific assembler options:\n"));
   3576 
   3577   fprintf (stream, "  -mcpu=<cpu name>\t  (default: %s), assemble for"
   3578            " CPU <cpu name>, one of:\n", TARGET_WITH_CPU);
   3579   arc_show_cpu_list (stream);
   3580   fprintf (stream, "\n");
   3581   fprintf (stream, "  -mA6/-mARC600/-mARC601  same as -mcpu=arc600\n");
   3582   fprintf (stream, "  -mA7/-mARC700\t\t  same as -mcpu=arc700\n");
   3583   fprintf (stream, "  -mEM\t\t\t  same as -mcpu=arcem\n");
   3584   fprintf (stream, "  -mHS\t\t\t  same as -mcpu=archs\n");
   3585 
   3586   fprintf (stream, "  -mnps400\t\t  enable NPS-400 extended instructions\n");
   3587   fprintf (stream, "  -mspfp\t\t  enable single-precision floating point"
   3588 	   " instructions\n");
   3589   fprintf (stream, "  -mdpfp\t\t  enable double-precision floating point"
   3590 	   " instructions\n");
   3591   fprintf (stream, "  -mfpuda\t\t  enable double-precision assist floating "
   3592                    "point\n\t\t\t  instructions for ARC EM\n");
   3593 
   3594   fprintf (stream,
   3595 	   "  -mcode-density\t  enable code density option for ARC EM\n");
   3596 
   3597   fprintf (stream, _("\
   3598   -EB                     assemble code for a big-endian cpu\n"));
   3599   fprintf (stream, _("\
   3600   -EL                     assemble code for a little-endian cpu\n"));
   3601   fprintf (stream, _("\
   3602   -mrelax                 enable relaxation\n"));
   3603 
   3604   fprintf (stream, _("The following ARC-specific assembler options are "
   3605                      "deprecated and are accepted\nfor compatibility only:\n"));
   3606 
   3607   fprintf (stream, _("  -mEA\n"
   3608                      "  -mbarrel-shifter\n"
   3609                      "  -mbarrel_shifter\n"
   3610                      "  -mcrc\n"
   3611                      "  -mdsp-packa\n"
   3612                      "  -mdsp_packa\n"
   3613                      "  -mdvbf\n"
   3614                      "  -mld-extension-reg-mask\n"
   3615                      "  -mlock\n"
   3616                      "  -mmac-24\n"
   3617                      "  -mmac-d16\n"
   3618                      "  -mmac_24\n"
   3619                      "  -mmac_d16\n"
   3620                      "  -mmin-max\n"
   3621                      "  -mmin_max\n"
   3622                      "  -mmul64\n"
   3623                      "  -mno-mpy\n"
   3624                      "  -mnorm\n"
   3625                      "  -mrtsc\n"
   3626                      "  -msimd\n"
   3627                      "  -mswap\n"
   3628                      "  -mswape\n"
   3629                      "  -mtelephony\n"
   3630 		     "  -muser-mode-only\n"
   3631                      "  -mxy\n"));
   3632 }
   3633 
   3634 /* Find the proper relocation for the given opcode.  */
   3635 
   3636 static extended_bfd_reloc_code_real_type
   3637 find_reloc (const char *name,
   3638 	    const char *opcodename,
   3639 	    const struct arc_flags *pflags,
   3640 	    int nflg,
   3641 	    extended_bfd_reloc_code_real_type reloc)
   3642 {
   3643   unsigned int i;
   3644   int j;
   3645   bool found_flag, tmp;
   3646   extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
   3647 
   3648   for (i = 0; i < arc_num_equiv_tab; i++)
   3649     {
   3650       const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
   3651 
   3652       /* Find the entry.  */
   3653       if (strcmp (name, r->name))
   3654 	continue;
   3655       if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
   3656 	continue;
   3657       if (r->flags[0])
   3658 	{
   3659 	  if (!nflg)
   3660 	    continue;
   3661 	  found_flag = false;
   3662 	  const unsigned *psflg = r->flags;
   3663 	  do
   3664 	    {
   3665 	      tmp = false;
   3666 	      for (j = 0; j < nflg; j++)
   3667 		if (!strcmp (pflags[j].name,
   3668 			     arc_flag_operands[*psflg].name))
   3669 		  {
   3670 		    tmp = true;
   3671 		    break;
   3672 		  }
   3673 	      if (!tmp)
   3674 		{
   3675 		  found_flag = false;
   3676 		  break;
   3677 		}
   3678 	      else
   3679 		{
   3680 		  found_flag = true;
   3681 		}
   3682 	      ++ psflg;
   3683 	    } while (*psflg);
   3684 
   3685 	  if (!found_flag)
   3686 	    continue;
   3687 	}
   3688 
   3689       if (reloc != r->oldreloc)
   3690 	continue;
   3691       /* Found it.  */
   3692       ret = r->newreloc;
   3693       break;
   3694     }
   3695 
   3696   if (ret == BFD_RELOC_UNUSED)
   3697     as_bad (_("Unable to find %s relocation for instruction %s"),
   3698 	    name, opcodename);
   3699   return ret;
   3700 }
   3701 
   3702 /* All the symbol types that are allowed to be used for
   3703    relaxation.  */
   3704 
   3705 static bool
   3706 may_relax_expr (expressionS tok)
   3707 {
   3708   /* Check if we have unrelaxable relocs.  */
   3709   switch (tok.X_md)
   3710     {
   3711     default:
   3712       break;
   3713     case O_plt:
   3714       return false;
   3715     }
   3716 
   3717   switch (tok.X_op)
   3718     {
   3719     case O_symbol:
   3720     case O_multiply:
   3721     case O_divide:
   3722     case O_modulus:
   3723     case O_add:
   3724     case O_subtract:
   3725       break;
   3726 
   3727     default:
   3728       return false;
   3729     }
   3730   return true;
   3731 }
   3732 
   3733 /* Checks if flags are in line with relaxable insn.  */
   3734 
   3735 static bool
   3736 relaxable_flag (const struct arc_relaxable_ins *ins,
   3737 		const struct arc_flags *pflags,
   3738 		int nflgs)
   3739 {
   3740   unsigned flag_class,
   3741     flag,
   3742     flag_class_idx = 0,
   3743     flag_idx = 0;
   3744 
   3745   const struct arc_flag_operand *flag_opand;
   3746   int i, counttrue = 0;
   3747 
   3748   /* Iterate through flags classes.  */
   3749   while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
   3750     {
   3751       /* Iterate through flags in flag class.  */
   3752       while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
   3753 	     != 0)
   3754 	{
   3755 	  flag_opand = &arc_flag_operands[flag];
   3756 	  /* Iterate through flags in ins to compare.  */
   3757 	  for (i = 0; i < nflgs; ++i)
   3758 	    {
   3759 	      if (strcmp (flag_opand->name, pflags[i].name) == 0)
   3760 		++counttrue;
   3761 	    }
   3762 
   3763 	  ++flag_idx;
   3764 	}
   3765 
   3766       ++flag_class_idx;
   3767       flag_idx = 0;
   3768     }
   3769 
   3770   /* If counttrue == nflgs, then all flags have been found.  */
   3771   return counttrue == nflgs;
   3772 }
   3773 
   3774 /* Checks if operands are in line with relaxable insn.  */
   3775 
   3776 static bool
   3777 relaxable_operand (const struct arc_relaxable_ins *ins,
   3778 		   const expressionS *tok,
   3779 		   int ntok)
   3780 {
   3781   const enum rlx_operand_type *operand = &ins->operands[0];
   3782   int i = 0;
   3783 
   3784   while (*operand != EMPTY)
   3785     {
   3786       const expressionS *epr = &tok[i];
   3787 
   3788       if (i != 0 && i >= ntok)
   3789 	return false;
   3790 
   3791       switch (*operand)
   3792 	{
   3793 	case IMMEDIATE:
   3794 	  if (!(epr->X_op == O_multiply
   3795 		|| epr->X_op == O_divide
   3796 		|| epr->X_op == O_modulus
   3797 		|| epr->X_op == O_add
   3798 		|| epr->X_op == O_subtract
   3799 		|| epr->X_op == O_symbol))
   3800 	    return false;
   3801 	  break;
   3802 
   3803 	case REGISTER_DUP:
   3804 	  if ((i <= 0)
   3805 	      || (epr->X_add_number != tok[i - 1].X_add_number))
   3806 	    return false;
   3807 	  /* Fall through.  */
   3808 	case REGISTER:
   3809 	  if (epr->X_op != O_register)
   3810 	    return false;
   3811 	  break;
   3812 
   3813 	case REGISTER_S:
   3814 	  if (epr->X_op != O_register)
   3815 	    return false;
   3816 
   3817 	  switch (epr->X_add_number)
   3818 	    {
   3819 	    case 0: case 1: case 2: case 3:
   3820 	    case 12: case 13: case 14: case 15:
   3821 	      break;
   3822 	    default:
   3823 	      return false;
   3824 	    }
   3825 	  break;
   3826 
   3827 	case REGISTER_NO_GP:
   3828 	  if ((epr->X_op != O_register)
   3829 	      || (epr->X_add_number == 26)) /* 26 is the gp register.  */
   3830 	    return false;
   3831 	  break;
   3832 
   3833 	case BRACKET:
   3834 	  if (epr->X_op != O_bracket)
   3835 	    return false;
   3836 	  break;
   3837 
   3838 	default:
   3839 	  /* Don't understand, bail out.  */
   3840 	  return false;
   3841 	  break;
   3842 	}
   3843 
   3844       ++i;
   3845       operand = &ins->operands[i];
   3846     }
   3847 
   3848   return i == ntok;
   3849 }
   3850 
   3851 /* Return TRUE if this OPDCODE is a candidate for relaxation.  */
   3852 
   3853 static bool
   3854 relax_insn_p (const struct arc_opcode *opcode,
   3855 	      const expressionS *tok,
   3856 	      int ntok,
   3857 	      const struct arc_flags *pflags,
   3858 	      int nflg)
   3859 {
   3860   unsigned i;
   3861   bool rv = false;
   3862 
   3863   /* Check the relaxation table.  */
   3864   for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
   3865     {
   3866       const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
   3867 
   3868       if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
   3869 	  && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
   3870 	  && relaxable_operand (arc_rlx_ins, tok, ntok)
   3871 	  && relaxable_flag (arc_rlx_ins, pflags, nflg))
   3872 	{
   3873 	  rv = true;
   3874 	  frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
   3875 	  memcpy (&frag_now->tc_frag_data.tok, tok,
   3876 		sizeof (expressionS) * ntok);
   3877 	  memcpy (&frag_now->tc_frag_data.pflags, pflags,
   3878 		sizeof (struct arc_flags) * nflg);
   3879 	  frag_now->tc_frag_data.nflg = nflg;
   3880 	  frag_now->tc_frag_data.ntok = ntok;
   3881 	  break;
   3882 	}
   3883     }
   3884 
   3885   return rv;
   3886 }
   3887 
   3888 /* Turn an opcode description and a set of arguments into
   3889    an instruction and a fixup.  */
   3890 
   3891 static void
   3892 assemble_insn (const struct arc_opcode *opcode,
   3893 	       const expressionS *tok,
   3894 	       int ntok,
   3895 	       const struct arc_flags *pflags,
   3896 	       int nflg,
   3897 	       struct arc_insn *insn)
   3898 {
   3899   const expressionS *reloc_exp = NULL;
   3900   unsigned long long image;
   3901   const unsigned char *argidx;
   3902   int i;
   3903   int tokidx = 0;
   3904   unsigned char pcrel = 0;
   3905   bool needGOTSymbol;
   3906   bool has_delay_slot = false;
   3907   extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
   3908 
   3909   memset (insn, 0, sizeof (*insn));
   3910   image = opcode->opcode;
   3911 
   3912   pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
   3913 	    frag_now->fr_file, frag_now->fr_line, opcode->name,
   3914 	    opcode->opcode);
   3915 
   3916   /* Handle operands.  */
   3917   for (argidx = opcode->operands; *argidx; ++argidx)
   3918     {
   3919       const struct arc_operand *operand = &arc_operands[*argidx];
   3920       const expressionS *t = NULL;
   3921 
   3922       if (ARC_OPERAND_IS_FAKE (operand))
   3923 	continue;
   3924 
   3925       if (operand->flags & ARC_OPERAND_DUPLICATE)
   3926 	{
   3927 	  /* Duplicate operand, already inserted.  */
   3928 	  tokidx ++;
   3929 	  continue;
   3930 	}
   3931 
   3932       if (tokidx >= ntok)
   3933 	{
   3934 	  abort ();
   3935 	}
   3936       else
   3937 	t = &tok[tokidx++];
   3938 
   3939       /* Regardless if we have a reloc or not mark the instruction
   3940 	 limm if it is the case.  */
   3941       if (operand->flags & ARC_OPERAND_LIMM)
   3942 	insn->has_limm = true;
   3943 
   3944       switch (t->X_op)
   3945 	{
   3946 	case O_register:
   3947 	  image = insert_operand (image, operand, regno (t->X_add_number),
   3948 				  NULL, 0);
   3949 	  break;
   3950 
   3951 	case O_constant:
   3952 	  image = insert_operand (image, operand, t->X_add_number, NULL, 0);
   3953 	  reloc_exp = t;
   3954 	  if (operand->flags & ARC_OPERAND_LIMM)
   3955 	    insn->limm = t->X_add_number;
   3956 	  break;
   3957 
   3958 	case O_bracket:
   3959         case O_colon:
   3960         case O_addrtype:
   3961 	  /* Ignore brackets, colons, and address types.  */
   3962 	  break;
   3963 
   3964 	case O_absent:
   3965 	  gas_assert (operand->flags & ARC_OPERAND_IGNORE);
   3966 	  break;
   3967 
   3968 	case O_subtract:
   3969 	  /* Maybe register range.  */
   3970 	  if ((t->X_add_number == 0)
   3971 	      && contains_register (t->X_add_symbol)
   3972 	      && contains_register (t->X_op_symbol))
   3973 	    {
   3974 	      int regs;
   3975 
   3976 	      regs = get_register (t->X_add_symbol);
   3977 	      regs <<= 16;
   3978 	      regs |= get_register (t->X_op_symbol);
   3979 	      image = insert_operand (image, operand, regs, NULL, 0);
   3980 	      break;
   3981 	    }
   3982 	  /* Fall through.  */
   3983 
   3984 	default:
   3985 	  /* This operand needs a relocation.  */
   3986 	  needGOTSymbol = false;
   3987 
   3988 	  switch (t->X_md)
   3989 	    {
   3990 	    case O_plt:
   3991 	      if (opcode->insn_class == JUMP)
   3992 		as_bad (_("Unable to use @plt relocation for insn %s"),
   3993 			opcode->name);
   3994 	      needGOTSymbol = true;
   3995 	      reloc = find_reloc ("plt", opcode->name,
   3996 				  pflags, nflg,
   3997 				  operand->default_reloc);
   3998 	      break;
   3999 
   4000 	    case O_gotoff:
   4001 	    case O_gotpc:
   4002 	      needGOTSymbol = true;
   4003 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   4004 	      break;
   4005 	    case O_pcl:
   4006 	      if (operand->flags & ARC_OPERAND_LIMM)
   4007 		{
   4008 		  reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   4009 		  if (arc_opcode_len (opcode) == 2
   4010 		      || opcode->insn_class == JUMP)
   4011 		    as_bad (_("Unable to use @pcl relocation for insn %s"),
   4012 			    opcode->name);
   4013 		}
   4014 	      else
   4015 		{
   4016 		  /* This is a relaxed operand which initially was
   4017 		     limm, choose whatever we have defined in the
   4018 		     opcode as reloc.  */
   4019 		  reloc = operand->default_reloc;
   4020 		}
   4021 	      break;
   4022 	    case O_sda:
   4023 	      reloc = find_reloc ("sda", opcode->name,
   4024 				  pflags, nflg,
   4025 				  operand->default_reloc);
   4026 	      break;
   4027 	    case O_tlsgd:
   4028 	    case O_tlsie:
   4029 	      needGOTSymbol = true;
   4030 	      /* Fall-through.  */
   4031 
   4032 	    case O_tpoff:
   4033 	    case O_dtpoff:
   4034 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   4035 	      break;
   4036 
   4037 	    case O_tpoff9: /*FIXME! Check for the conditionality of
   4038 			     the insn.  */
   4039 	    case O_dtpoff9: /*FIXME! Check for the conditionality of
   4040 			      the insn.  */
   4041 	      as_bad (_("TLS_*_S9 relocs are not supported yet"));
   4042 	      break;
   4043 
   4044 	    default:
   4045 	      /* Just consider the default relocation.  */
   4046 	      reloc = operand->default_reloc;
   4047 	      break;
   4048 	    }
   4049 
   4050 	  if (needGOTSymbol && (GOT_symbol == NULL))
   4051 	    GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
   4052 
   4053 	  reloc_exp = t;
   4054 
   4055 #if 0
   4056 	  if (reloc > 0)
   4057 	    {
   4058 	      /* sanity checks.  */
   4059 	      reloc_howto_type *reloc_howto
   4060 		= bfd_reloc_type_lookup (stdoutput, reloc);
   4061 	      unsigned reloc_bitsize = reloc_howto->bitsize;
   4062 	      if (reloc_howto->rightshift)
   4063 		reloc_bitsize -= reloc_howto->rightshift;
   4064 	      if (reloc_bitsize != operand->bits)
   4065 		{
   4066 		  as_bad (_("invalid relocation %s for field"),
   4067 			  bfd_get_reloc_code_name (reloc));
   4068 		  return;
   4069 		}
   4070 	    }
   4071 #endif
   4072 	  if (insn->nfixups >= MAX_INSN_FIXUPS)
   4073 	    as_fatal (_("too many fixups"));
   4074 
   4075 	  struct arc_fixup *fixup;
   4076 	  fixup = &insn->fixups[insn->nfixups++];
   4077 	  fixup->exp = *t;
   4078 	  fixup->reloc = reloc;
   4079 	  if ((int) reloc < 0)
   4080 	    pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
   4081 	  else
   4082 	    {
   4083 	      reloc_howto_type *reloc_howto =
   4084 		bfd_reloc_type_lookup (stdoutput, fixup->reloc);
   4085 	      pcrel = reloc_howto->pc_relative;
   4086 	    }
   4087 	  fixup->pcrel = pcrel;
   4088 	  fixup->islong = (operand->flags & ARC_OPERAND_LIMM) != 0;
   4089 	  break;
   4090 	}
   4091     }
   4092 
   4093   /* Handle flags.  */
   4094   for (i = 0; i < nflg; i++)
   4095     {
   4096       const struct arc_flag_operand *flg_operand = pflags[i].flgp;
   4097 
   4098       /* Check if the instruction has a delay slot.  */
   4099       if (!strcmp (flg_operand->name, "d"))
   4100 	has_delay_slot = true;
   4101 
   4102       /* There is an exceptional case when we cannot insert a flag just as
   4103 	 it is.  On ARCv2 the '.t' and '.nt' flags must be handled in
   4104 	 relation with the relative address.  Unfortunately, some of the
   4105 	 ARC700 extensions (NPS400) also have a '.nt' flag that should be
   4106 	 handled in the normal way.
   4107 
   4108 	 Flag operands don't have an architecture field, so we can't
   4109 	 directly validate that FLAG_OPERAND is valid for the current
   4110 	 architecture, what we do instead is just validate that we're
   4111 	 assembling for an ARCv2 architecture.  */
   4112       if ((selected_cpu.flags & ARC_OPCODE_ARCV2)
   4113 	  && (!strcmp (flg_operand->name, "t")
   4114 	      || !strcmp (flg_operand->name, "nt")))
   4115 	{
   4116 	  unsigned bitYoperand = 0;
   4117 	  /* FIXME! move selection bbit/brcc in arc-opc.c.  */
   4118 	  if (!strcmp (flg_operand->name, "t"))
   4119 	    if (!strcmp (opcode->name, "bbit0")
   4120 		|| !strcmp (opcode->name, "bbit1"))
   4121 	      bitYoperand = arc_NToperand;
   4122 	    else
   4123 	      bitYoperand = arc_Toperand;
   4124 	  else
   4125 	    if (!strcmp (opcode->name, "bbit0")
   4126 		|| !strcmp (opcode->name, "bbit1"))
   4127 	      bitYoperand = arc_Toperand;
   4128 	    else
   4129 	      bitYoperand = arc_NToperand;
   4130 
   4131 	  gas_assert (reloc_exp != NULL);
   4132 	  if (reloc_exp->X_op == O_constant)
   4133 	    {
   4134 	      /* Check if we have a constant and solved it
   4135 		 immediately.  */
   4136 	      offsetT val = reloc_exp->X_add_number;
   4137 	      image |= insert_operand (image, &arc_operands[bitYoperand],
   4138 				       val, NULL, 0);
   4139 	    }
   4140 	  else
   4141 	    {
   4142 	      struct arc_fixup *fixup;
   4143 
   4144 	      if (insn->nfixups >= MAX_INSN_FIXUPS)
   4145 		as_fatal (_("too many fixups"));
   4146 
   4147 	      fixup = &insn->fixups[insn->nfixups++];
   4148 	      fixup->exp = *reloc_exp;
   4149 	      fixup->reloc = -bitYoperand;
   4150 	      fixup->pcrel = pcrel;
   4151 	      fixup->islong = false;
   4152 	    }
   4153 	}
   4154       else
   4155 	image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
   4156 	  << flg_operand->shift;
   4157     }
   4158 
   4159   insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
   4160 
   4161   /* Instruction length.  */
   4162   insn->len = arc_opcode_len (opcode);
   4163 
   4164   insn->insn = image;
   4165 
   4166   /* Update last insn status.  */
   4167   arc_last_insns[1]		   = arc_last_insns[0];
   4168   arc_last_insns[0].opcode	   = opcode;
   4169   arc_last_insns[0].has_limm	   = insn->has_limm;
   4170   arc_last_insns[0].has_delay_slot = has_delay_slot;
   4171 
   4172   /* Check if the current instruction is legally used.  */
   4173   if (arc_last_insns[1].has_delay_slot
   4174       && is_br_jmp_insn_p (arc_last_insns[0].opcode))
   4175     as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."),
   4176 	    arc_last_insns[1].opcode->name,
   4177 	    arc_last_insns[0].opcode->name);
   4178   if (arc_last_insns[1].has_delay_slot
   4179       && arc_last_insns[0].has_limm)
   4180     as_bad (_("Insn %s has an instruction %s with limm in its delay slot."),
   4181 	    arc_last_insns[1].opcode->name,
   4182 	    arc_last_insns[0].opcode->name);
   4183 }
   4184 
   4185 void
   4186 arc_handle_align (fragS* fragP)
   4187 {
   4188   if ((fragP)->fr_type == rs_align_code)
   4189     {
   4190       char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
   4191       valueT count = ((fragP)->fr_next->fr_address
   4192 		      - (fragP)->fr_address - (fragP)->fr_fix);
   4193 
   4194       (fragP)->fr_var = 2;
   4195 
   4196       if (count & 1)/* Padding in the gap till the next 2-byte
   4197 		       boundary with 0s.  */
   4198 	{
   4199 	  (fragP)->fr_fix++;
   4200 	  *dest++ = 0;
   4201 	}
   4202       /* Writing nop_s.  */
   4203       md_number_to_chars (dest, NOP_OPCODE_S, 2);
   4204     }
   4205 }
   4206 
   4207 /* Here we decide which fixups can be adjusted to make them relative
   4208    to the beginning of the section instead of the symbol.  Basically
   4209    we need to make sure that the dynamic relocations are done
   4210    correctly, so in some cases we force the original symbol to be
   4211    used.  */
   4212 
   4213 int
   4214 tc_arc_fix_adjustable (fixS *fixP)
   4215 {
   4216 
   4217   /* Prevent all adjustments to global symbols.  */
   4218   if (S_IS_EXTERNAL (fixP->fx_addsy))
   4219     return 0;
   4220   if (S_IS_WEAK (fixP->fx_addsy))
   4221     return 0;
   4222 
   4223   /* Adjust_reloc_syms doesn't know about the GOT.  */
   4224   switch (fixP->fx_r_type)
   4225     {
   4226     case BFD_RELOC_ARC_GOTPC32:
   4227     case BFD_RELOC_ARC_PLT32:
   4228     case BFD_RELOC_ARC_S25H_PCREL_PLT:
   4229     case BFD_RELOC_ARC_S21H_PCREL_PLT:
   4230     case BFD_RELOC_ARC_S25W_PCREL_PLT:
   4231     case BFD_RELOC_ARC_S21W_PCREL_PLT:
   4232       return 0;
   4233 
   4234     default:
   4235       break;
   4236     }
   4237 
   4238   return 1;
   4239 }
   4240 
   4241 /* Compute the reloc type of an expression EXP.  */
   4242 
   4243 static void
   4244 arc_check_reloc (expressionS *exp,
   4245 		 bfd_reloc_code_real_type *r_type_p)
   4246 {
   4247   if (*r_type_p == BFD_RELOC_32
   4248       && exp->X_op == O_subtract
   4249       && exp->X_op_symbol != NULL
   4250       && S_GET_SEGMENT (exp->X_op_symbol) == now_seg)
   4251     *r_type_p = BFD_RELOC_ARC_32_PCREL;
   4252 }
   4253 
   4254 
   4255 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG.  */
   4256 
   4257 void
   4258 arc_cons_fix_new (fragS *frag,
   4259 		  int off,
   4260 		  int size,
   4261 		  expressionS *exp,
   4262 		  bfd_reloc_code_real_type r_type)
   4263 {
   4264   r_type = BFD_RELOC_UNUSED;
   4265 
   4266   switch (size)
   4267     {
   4268     case 1:
   4269       r_type = BFD_RELOC_8;
   4270       break;
   4271 
   4272     case 2:
   4273       r_type = BFD_RELOC_16;
   4274       break;
   4275 
   4276     case 3:
   4277       r_type = BFD_RELOC_24;
   4278       break;
   4279 
   4280     case 4:
   4281       r_type = BFD_RELOC_32;
   4282       arc_check_reloc (exp, &r_type);
   4283       break;
   4284 
   4285     case 8:
   4286       r_type = BFD_RELOC_64;
   4287       break;
   4288 
   4289     default:
   4290       as_bad (_("unsupported BFD relocation size %u"), size);
   4291       r_type = BFD_RELOC_UNUSED;
   4292     }
   4293 
   4294   fix_new_exp (frag, off, size, exp, 0, r_type);
   4295 }
   4296 
   4297 /* The actual routine that checks the ZOL conditions.  */
   4298 
   4299 static void
   4300 check_zol (symbolS *s)
   4301 {
   4302   switch (selected_cpu.mach)
   4303     {
   4304     case bfd_mach_arc_arcv2:
   4305       if (selected_cpu.flags & ARC_OPCODE_ARCv2EM)
   4306 	return;
   4307 
   4308       if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
   4309 	  || arc_last_insns[1].has_delay_slot)
   4310 	as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
   4311 		S_GET_NAME (s));
   4312 
   4313       break;
   4314     case bfd_mach_arc_arc600:
   4315 
   4316       if (is_kernel_insn_p (arc_last_insns[0].opcode))
   4317 	as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
   4318 		S_GET_NAME (s));
   4319 
   4320       if (arc_last_insns[0].has_limm
   4321 	  && is_br_jmp_insn_p (arc_last_insns[0].opcode))
   4322 	as_bad (_("A jump instruction with long immediate detected at the \
   4323 end of the ZOL label @%s"), S_GET_NAME (s));
   4324 
   4325       /* Fall through.  */
   4326     case bfd_mach_arc_arc700:
   4327       if (arc_last_insns[0].has_delay_slot)
   4328 	as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
   4329 		S_GET_NAME (s));
   4330 
   4331       break;
   4332     default:
   4333       break;
   4334     }
   4335 }
   4336 
   4337 /* If ZOL end check the last two instruction for illegals.  */
   4338 void
   4339 arc_frob_label (symbolS * sym)
   4340 {
   4341   if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
   4342     check_zol (sym);
   4343 
   4344   dwarf2_emit_label (sym);
   4345 }
   4346 
   4347 /* Used because generic relaxation assumes a pc-rel value whilst we
   4348    also relax instructions that use an absolute value resolved out of
   4349    relative values (if that makes any sense).  An example: 'add r1,
   4350    r2, @.L2 - .'  The symbols . and @.L2 are relative to the section
   4351    but if they're in the same section we can subtract the section
   4352    offset relocation which ends up in a resolved value.  So if @.L2 is
   4353    .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
   4354    .text + 0x40 = 0x10.  */
   4355 int
   4356 arc_pcrel_adjust (fragS *fragP)
   4357 {
   4358   pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
   4359 	    fragP->fr_address, fragP->fr_fix,
   4360 	    fragP->tc_frag_data.pcrel ? "Y" : "N");
   4361 
   4362   if (!fragP->tc_frag_data.pcrel)
   4363     return fragP->fr_address + fragP->fr_fix;
   4364 
   4365   /* Take into account the PCL rounding.  */
   4366   return (fragP->fr_address + fragP->fr_fix) & 0x03;
   4367 }
   4368 
   4369 /* Initialize the DWARF-2 unwind information for this procedure.  */
   4370 
   4371 void
   4372 tc_arc_frame_initial_instructions (void)
   4373 {
   4374   /* Stack pointer is register 28.  */
   4375   cfi_add_CFA_def_cfa (28, 0);
   4376 }
   4377 
   4378 int
   4379 tc_arc_regname_to_dw2regnum (char *regname)
   4380 {
   4381   struct symbol *sym;
   4382 
   4383   sym = str_hash_find (arc_reg_hash, regname);
   4384   if (sym)
   4385     return S_GET_VALUE (sym);
   4386 
   4387   return -1;
   4388 }
   4389 
   4390 /* Adjust the symbol table.  Delete found AUX register symbols.  */
   4391 
   4392 void
   4393 arc_adjust_symtab (void)
   4394 {
   4395   symbolS * sym;
   4396 
   4397   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
   4398     {
   4399       /* I've created a symbol during parsing process.  Now, remove
   4400 	 the symbol as it is found to be an AUX register.  */
   4401       if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX)
   4402 	symbol_remove (sym, &symbol_rootP, &symbol_lastP);
   4403     }
   4404 
   4405   /* Now do generic ELF adjustments.  */
   4406   elf_adjust_symtab ();
   4407 }
   4408 
   4409 static void
   4410 tokenize_extinsn (extInstruction_t *einsn)
   4411 {
   4412   char *p, c;
   4413   char *insn_name;
   4414   unsigned char major_opcode;
   4415   unsigned char sub_opcode;
   4416   unsigned char syntax_class = 0;
   4417   unsigned char syntax_class_modifiers = 0;
   4418   unsigned char suffix_class = 0;
   4419   unsigned int i;
   4420 
   4421   SKIP_WHITESPACE ();
   4422 
   4423   /* 1st: get instruction name.  */
   4424   p = input_line_pointer;
   4425   c = get_symbol_name (&p);
   4426 
   4427   insn_name = xstrdup (p);
   4428   restore_line_pointer (c);
   4429 
   4430   /* Convert to lower case.  */
   4431   for (p = insn_name; *p; ++p)
   4432     *p = TOLOWER (*p);
   4433 
   4434   /* 2nd: get major opcode.  */
   4435   if (*input_line_pointer != ',')
   4436     {
   4437       as_bad (_("expected comma after instruction name"));
   4438       ignore_rest_of_line ();
   4439       return;
   4440     }
   4441   input_line_pointer++;
   4442   major_opcode = get_absolute_expression ();
   4443 
   4444   /* 3rd: get sub-opcode.  */
   4445   SKIP_WHITESPACE ();
   4446 
   4447   if (*input_line_pointer != ',')
   4448     {
   4449       as_bad (_("expected comma after major opcode"));
   4450       ignore_rest_of_line ();
   4451       return;
   4452     }
   4453   input_line_pointer++;
   4454   sub_opcode = get_absolute_expression ();
   4455 
   4456   /* 4th: get suffix class.  */
   4457   SKIP_WHITESPACE ();
   4458 
   4459   if (*input_line_pointer != ',')
   4460     {
   4461       as_bad ("expected comma after sub opcode");
   4462       ignore_rest_of_line ();
   4463       return;
   4464     }
   4465   input_line_pointer++;
   4466 
   4467   while (1)
   4468     {
   4469       SKIP_WHITESPACE ();
   4470 
   4471       for (i = 0; i < ARRAY_SIZE (suffixclass); i++)
   4472 	{
   4473 	  if (!strncmp (suffixclass[i].name, input_line_pointer,
   4474 			suffixclass[i].len))
   4475 	    {
   4476 	      suffix_class |= suffixclass[i].attr_class;
   4477 	      input_line_pointer += suffixclass[i].len;
   4478 	      break;
   4479 	    }
   4480 	}
   4481 
   4482       if (i == ARRAY_SIZE (suffixclass))
   4483 	{
   4484 	  as_bad ("invalid suffix class");
   4485 	  ignore_rest_of_line ();
   4486 	  return;
   4487 	}
   4488 
   4489       SKIP_WHITESPACE ();
   4490 
   4491       if (*input_line_pointer == '|')
   4492 	input_line_pointer++;
   4493       else
   4494 	break;
   4495     }
   4496 
   4497   /* 5th: get syntax class and syntax class modifiers.  */
   4498   if (*input_line_pointer != ',')
   4499     {
   4500       as_bad ("expected comma after suffix class");
   4501       ignore_rest_of_line ();
   4502       return;
   4503     }
   4504   input_line_pointer++;
   4505 
   4506   while (1)
   4507     {
   4508       SKIP_WHITESPACE ();
   4509 
   4510       for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++)
   4511 	{
   4512 	  if (!strncmp (syntaxclassmod[i].name,
   4513 			input_line_pointer,
   4514 			syntaxclassmod[i].len))
   4515 	    {
   4516 	      syntax_class_modifiers |= syntaxclassmod[i].attr_class;
   4517 	      input_line_pointer += syntaxclassmod[i].len;
   4518 	      break;
   4519 	    }
   4520 	}
   4521 
   4522       if (i == ARRAY_SIZE (syntaxclassmod))
   4523 	{
   4524 	  for (i = 0; i < ARRAY_SIZE (syntaxclass); i++)
   4525 	    {
   4526 	      if (!strncmp (syntaxclass[i].name,
   4527 			    input_line_pointer,
   4528 			    syntaxclass[i].len))
   4529 		{
   4530 		  syntax_class |= syntaxclass[i].attr_class;
   4531 		  input_line_pointer += syntaxclass[i].len;
   4532 		  break;
   4533 		}
   4534 	    }
   4535 
   4536 	  if (i == ARRAY_SIZE (syntaxclass))
   4537 	    {
   4538 	      as_bad ("missing syntax class");
   4539 	      ignore_rest_of_line ();
   4540 	      return;
   4541 	    }
   4542 	}
   4543 
   4544       SKIP_WHITESPACE ();
   4545 
   4546       if (*input_line_pointer == '|')
   4547 	input_line_pointer++;
   4548       else
   4549 	break;
   4550     }
   4551 
   4552   demand_empty_rest_of_line ();
   4553 
   4554   einsn->name   = insn_name;
   4555   einsn->major  = major_opcode;
   4556   einsn->minor  = sub_opcode;
   4557   einsn->syntax = syntax_class;
   4558   einsn->modsyn = syntax_class_modifiers;
   4559   einsn->suffix = suffix_class;
   4560   einsn->flags  = syntax_class
   4561     | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0);
   4562 }
   4563 
   4564 /* Generate an extension section.  */
   4565 
   4566 static int
   4567 arc_set_ext_seg (void)
   4568 {
   4569   if (!arcext_section)
   4570     {
   4571       arcext_section = subseg_new (".arcextmap", 0);
   4572       bfd_set_section_flags (arcext_section, SEC_READONLY | SEC_HAS_CONTENTS);
   4573     }
   4574   else
   4575     subseg_set (arcext_section, 0);
   4576   return 1;
   4577 }
   4578 
   4579 /* Create an extension instruction description in the arc extension
   4580    section of the output file.
   4581    The structure for an instruction is like this:
   4582    [0]: Length of the record.
   4583    [1]: Type of the record.
   4584 
   4585    [2]: Major opcode.
   4586    [3]: Sub-opcode.
   4587    [4]: Syntax (flags).
   4588    [5]+ Name instruction.
   4589 
   4590    The sequence is terminated by an empty entry.  */
   4591 
   4592 static void
   4593 create_extinst_section (extInstruction_t *einsn)
   4594 {
   4595 
   4596   segT old_sec    = now_seg;
   4597   int old_subsec  = now_subseg;
   4598   char *p;
   4599   int name_len    = strlen (einsn->name);
   4600 
   4601   arc_set_ext_seg ();
   4602 
   4603   p = frag_more (1);
   4604   *p = 5 + name_len + 1;
   4605   p = frag_more (1);
   4606   *p = EXT_INSTRUCTION;
   4607   p = frag_more (1);
   4608   *p = einsn->major;
   4609   p = frag_more (1);
   4610   *p = einsn->minor;
   4611   p = frag_more (1);
   4612   *p = einsn->flags;
   4613   p = frag_more (name_len + 1);
   4614   strcpy (p, einsn->name);
   4615 
   4616   subseg_set (old_sec, old_subsec);
   4617 }
   4618 
   4619 /* Handler .extinstruction pseudo-op.  */
   4620 
   4621 static void
   4622 arc_extinsn (int ignore ATTRIBUTE_UNUSED)
   4623 {
   4624   extInstruction_t einsn;
   4625   struct arc_opcode *arc_ext_opcodes;
   4626   const char *errmsg = NULL;
   4627   unsigned char moplow, mophigh;
   4628 
   4629   memset (&einsn, 0, sizeof (einsn));
   4630   tokenize_extinsn (&einsn);
   4631 
   4632   /* Check if the name is already used.  */
   4633   if (arc_find_opcode (einsn.name))
   4634     as_warn (_("Pseudocode already used %s"), einsn.name);
   4635 
   4636   /* Check the opcode ranges.  */
   4637   moplow = 0x05;
   4638   mophigh = (selected_cpu.flags & (ARC_OPCODE_ARCv2EM
   4639                                    | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a;
   4640 
   4641   if ((einsn.major > mophigh) || (einsn.major < moplow))
   4642     as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh);
   4643 
   4644   if ((einsn.minor > 0x3f) && (einsn.major != 0x0a)
   4645       && (einsn.major != 5) && (einsn.major != 9))
   4646     as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
   4647 
   4648   switch (einsn.syntax & ARC_SYNTAX_MASK)
   4649     {
   4650     case ARC_SYNTAX_3OP:
   4651       if (einsn.modsyn & ARC_OP1_IMM_IMPLIED)
   4652 	as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
   4653       break;
   4654     case ARC_SYNTAX_2OP:
   4655     case ARC_SYNTAX_1OP:
   4656     case ARC_SYNTAX_NOP:
   4657       if (einsn.modsyn & ARC_OP1_MUST_BE_IMM)
   4658 	as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
   4659       break;
   4660     default:
   4661       break;
   4662     }
   4663 
   4664   arc_ext_opcodes = arcExtMap_genOpcode (&einsn, selected_cpu.flags, &errmsg);
   4665   if (arc_ext_opcodes == NULL)
   4666     {
   4667       if (errmsg)
   4668 	as_fatal ("%s", errmsg);
   4669       else
   4670 	as_fatal (_("Couldn't generate extension instruction opcodes"));
   4671     }
   4672   else if (errmsg)
   4673     as_warn ("%s", errmsg);
   4674 
   4675   /* Insert the extension instruction.  */
   4676   arc_insert_opcode (arc_ext_opcodes);
   4677 
   4678   create_extinst_section (&einsn);
   4679 }
   4680 
   4681 static bool
   4682 tokenize_extregister (extRegister_t *ereg, int opertype)
   4683 {
   4684   char *name;
   4685   char *mode;
   4686   char c;
   4687   char *p;
   4688   int number, imode = 0;
   4689   bool isCore_p = opertype == EXT_CORE_REGISTER;
   4690   bool isReg_p = opertype == EXT_CORE_REGISTER || opertype == EXT_AUX_REGISTER;
   4691 
   4692   /* 1st: get register name.  */
   4693   SKIP_WHITESPACE ();
   4694   p = input_line_pointer;
   4695   c = get_symbol_name (&p);
   4696 
   4697   name = xstrdup (p);
   4698   restore_line_pointer (c);
   4699 
   4700   /* 2nd: get register number.  */
   4701   SKIP_WHITESPACE ();
   4702 
   4703   if (*input_line_pointer != ',')
   4704     {
   4705       as_bad (_("expected comma after name"));
   4706       ignore_rest_of_line ();
   4707       free (name);
   4708       return false;
   4709     }
   4710   input_line_pointer++;
   4711   number = get_absolute_expression ();
   4712 
   4713   if ((number < 0)
   4714       && (opertype != EXT_AUX_REGISTER))
   4715     {
   4716       as_bad (_("%s second argument cannot be a negative number %d"),
   4717 	      isCore_p ? "extCoreRegister's" : "extCondCode's",
   4718 	      number);
   4719       ignore_rest_of_line ();
   4720       free (name);
   4721       return false;
   4722     }
   4723 
   4724   if (isReg_p)
   4725     {
   4726       /* 3rd: get register mode.  */
   4727       SKIP_WHITESPACE ();
   4728 
   4729       if (*input_line_pointer != ',')
   4730 	{
   4731 	  as_bad (_("expected comma after register number"));
   4732 	  ignore_rest_of_line ();
   4733 	  free (name);
   4734 	  return false;
   4735 	}
   4736 
   4737       input_line_pointer++;
   4738       mode = input_line_pointer;
   4739 
   4740       if (startswith (mode, "r|w"))
   4741 	{
   4742 	  imode = 0;
   4743 	  input_line_pointer += 3;
   4744 	}
   4745       else if (startswith (mode, "r"))
   4746 	{
   4747 	  imode = ARC_REGISTER_READONLY;
   4748 	  input_line_pointer += 1;
   4749 	}
   4750       else if (!startswith (mode, "w"))
   4751 	{
   4752 	  as_bad (_("invalid mode"));
   4753 	  ignore_rest_of_line ();
   4754 	  free (name);
   4755 	  return false;
   4756 	}
   4757       else
   4758 	{
   4759 	  imode = ARC_REGISTER_WRITEONLY;
   4760 	  input_line_pointer += 1;
   4761 	}
   4762     }
   4763 
   4764   if (isCore_p)
   4765     {
   4766       /* 4th: get core register shortcut.  */
   4767       SKIP_WHITESPACE ();
   4768       if (*input_line_pointer != ',')
   4769 	{
   4770 	  as_bad (_("expected comma after register mode"));
   4771 	  ignore_rest_of_line ();
   4772 	  free (name);
   4773 	  return false;
   4774 	}
   4775 
   4776       input_line_pointer++;
   4777 
   4778       if (startswith (input_line_pointer, "cannot_shortcut"))
   4779 	{
   4780 	  imode |= ARC_REGISTER_NOSHORT_CUT;
   4781 	  input_line_pointer += 15;
   4782 	}
   4783       else if (!startswith (input_line_pointer, "can_shortcut"))
   4784 	{
   4785 	  as_bad (_("shortcut designator invalid"));
   4786 	  ignore_rest_of_line ();
   4787 	  free (name);
   4788 	  return false;
   4789 	}
   4790       else
   4791 	{
   4792 	  input_line_pointer += 12;
   4793 	}
   4794     }
   4795   demand_empty_rest_of_line ();
   4796 
   4797   ereg->name = name;
   4798   ereg->number = number;
   4799   ereg->imode  = imode;
   4800   return true;
   4801 }
   4802 
   4803 /* Create an extension register/condition description in the arc
   4804    extension section of the output file.
   4805 
   4806    The structure for an instruction is like this:
   4807    [0]: Length of the record.
   4808    [1]: Type of the record.
   4809 
   4810    For core regs and condition codes:
   4811    [2]: Value.
   4812    [3]+ Name.
   4813 
   4814    For auxiliary registers:
   4815    [2..5]: Value.
   4816    [6]+ Name
   4817 
   4818    The sequence is terminated by an empty entry.  */
   4819 
   4820 static void
   4821 create_extcore_section (extRegister_t *ereg, int opertype)
   4822 {
   4823   segT old_sec   = now_seg;
   4824   int old_subsec = now_subseg;
   4825   char *p;
   4826   int name_len   = strlen (ereg->name);
   4827 
   4828   arc_set_ext_seg ();
   4829 
   4830   switch (opertype)
   4831     {
   4832     case EXT_COND_CODE:
   4833     case EXT_CORE_REGISTER:
   4834       p = frag_more (1);
   4835       *p = 3 + name_len + 1;
   4836       p = frag_more (1);
   4837       *p = opertype;
   4838       p = frag_more (1);
   4839       *p = ereg->number;
   4840       break;
   4841     case EXT_AUX_REGISTER:
   4842       p = frag_more (1);
   4843       *p = 6 + name_len + 1;
   4844       p = frag_more (1);
   4845       *p = EXT_AUX_REGISTER;
   4846       p = frag_more (1);
   4847       *p = (ereg->number >> 24) & 0xff;
   4848       p = frag_more (1);
   4849       *p = (ereg->number >> 16) & 0xff;
   4850       p = frag_more (1);
   4851       *p = (ereg->number >>  8) & 0xff;
   4852       p = frag_more (1);
   4853       *p = (ereg->number)       & 0xff;
   4854       break;
   4855     default:
   4856       break;
   4857     }
   4858 
   4859   p = frag_more (name_len + 1);
   4860   strcpy (p, ereg->name);
   4861 
   4862   subseg_set (old_sec, old_subsec);
   4863 }
   4864 
   4865 /* Handler .extCoreRegister pseudo-op.  */
   4866 
   4867 static void
   4868 arc_extcorereg (int opertype)
   4869 {
   4870   extRegister_t ereg;
   4871   struct arc_aux_reg *auxr;
   4872   struct arc_flag_operand *ccode;
   4873 
   4874   memset (&ereg, 0, sizeof (ereg));
   4875   if (!tokenize_extregister (&ereg, opertype))
   4876     return;
   4877 
   4878   switch (opertype)
   4879     {
   4880     case EXT_CORE_REGISTER:
   4881       /* Core register.  */
   4882       if (ereg.number > 60)
   4883 	as_bad (_("core register %s value (%d) too large"), ereg.name,
   4884 		ereg.number);
   4885       declare_register (ereg.name, ereg.number);
   4886       break;
   4887     case EXT_AUX_REGISTER:
   4888       /* Auxiliary register.  */
   4889       auxr = XNEW (struct arc_aux_reg);
   4890       auxr->name = ereg.name;
   4891       auxr->cpu = selected_cpu.flags;
   4892       auxr->subclass = NONE;
   4893       auxr->address = ereg.number;
   4894       if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != NULL)
   4895 	as_bad (_("duplicate aux register %s"), auxr->name);
   4896       break;
   4897     case EXT_COND_CODE:
   4898       /* Condition code.  */
   4899       if (ereg.number > 31)
   4900 	as_bad (_("condition code %s value (%d) too large"), ereg.name,
   4901 		ereg.number);
   4902       ext_condcode.size ++;
   4903       ext_condcode.arc_ext_condcode =
   4904 	XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode,
   4905 		    ext_condcode.size + 1);
   4906 
   4907       ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1;
   4908       ccode->name   = ereg.name;
   4909       ccode->code   = ereg.number;
   4910       ccode->bits   = 5;
   4911       ccode->shift  = 0;
   4912       ccode->favail = 0; /* not used.  */
   4913       ccode++;
   4914       memset (ccode, 0, sizeof (struct arc_flag_operand));
   4915       break;
   4916     default:
   4917       as_bad (_("Unknown extension"));
   4918       break;
   4919     }
   4920   create_extcore_section (&ereg, opertype);
   4921 }
   4922 
   4923 /* Parse a .arc_attribute directive.  */
   4924 
   4925 static void
   4926 arc_attribute (int ignored ATTRIBUTE_UNUSED)
   4927 {
   4928   int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
   4929 
   4930   if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
   4931     attributes_set_explicitly[tag] = true;
   4932 }
   4933 
   4934 /* Set an attribute if it has not already been set by the user.  */
   4935 
   4936 static void
   4937 arc_set_attribute_int (int tag, int value)
   4938 {
   4939   if (tag < 1
   4940       || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
   4941       || !attributes_set_explicitly[tag])
   4942     if (!bfd_elf_add_proc_attr_int (stdoutput, tag, value))
   4943       as_fatal (_("error adding attribute: %s"),
   4944 		bfd_errmsg (bfd_get_error ()));
   4945 }
   4946 
   4947 static void
   4948 arc_set_attribute_string (int tag, const char *value)
   4949 {
   4950   if (tag < 1
   4951       || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
   4952       || !attributes_set_explicitly[tag])
   4953     if (!bfd_elf_add_proc_attr_string (stdoutput, tag, value))
   4954       as_fatal (_("error adding attribute: %s"),
   4955 		bfd_errmsg (bfd_get_error ()));
   4956 }
   4957 
   4958 /* Allocate and concatenate two strings.  s1 can be NULL but not
   4959    s2.  s1 pointer is freed at end of this procedure.  */
   4960 
   4961 static char *
   4962 arc_stralloc (char * s1, const char * s2)
   4963 {
   4964   char * p;
   4965   int len = 0;
   4966 
   4967   if (s1)
   4968     len = strlen (s1) + 1;
   4969 
   4970   /* Only s1 can be null.  */
   4971   gas_assert (s2);
   4972   len += strlen (s2) + 1;
   4973 
   4974   p = xmalloc (len);
   4975 
   4976   if (s1)
   4977     {
   4978       strcpy (p, s1);
   4979       strcat (p, ",");
   4980       strcat (p, s2);
   4981       free (s1);
   4982     }
   4983   else
   4984     strcpy (p, s2);
   4985 
   4986   return p;
   4987 }
   4988 
   4989 /* Set the public ARC object attributes.  */
   4990 
   4991 static void
   4992 arc_set_public_attributes (void)
   4993 {
   4994   int base = 0;
   4995   char *s = NULL;
   4996   unsigned int i;
   4997 
   4998   /* Tag_ARC_CPU_name.  */
   4999   arc_set_attribute_string (Tag_ARC_CPU_name, selected_cpu.name);
   5000 
   5001   /* Tag_ARC_CPU_base.  */
   5002   switch (selected_cpu.eflags & EF_ARC_MACH_MSK)
   5003     {
   5004     case E_ARC_MACH_ARC600:
   5005     case E_ARC_MACH_ARC601:
   5006       base = TAG_CPU_ARC6xx;
   5007       break;
   5008     case E_ARC_MACH_ARC700:
   5009       base = TAG_CPU_ARC7xx;
   5010       break;
   5011     case EF_ARC_CPU_ARCV2EM:
   5012       base = TAG_CPU_ARCEM;
   5013       break;
   5014     case EF_ARC_CPU_ARCV2HS:
   5015       base = TAG_CPU_ARCHS;
   5016       break;
   5017     default:
   5018       base = 0;
   5019       break;
   5020     }
   5021   if (attributes_set_explicitly[Tag_ARC_CPU_base]
   5022       && (base != bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
   5023 					    Tag_ARC_CPU_base)))
   5024     as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
   5025   if (!bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_CPU_base, base))
   5026     as_fatal (_("error adding attribute: %s"),
   5027 	      bfd_errmsg (bfd_get_error ()));
   5028 
   5029   /* Tag_ARC_ABI_osver.  */
   5030   if (attributes_set_explicitly[Tag_ARC_ABI_osver])
   5031     {
   5032       int val = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
   5033 					  Tag_ARC_ABI_osver);
   5034 
   5035       selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_OSABI_MSK)
   5036 			     | (val & 0x0f << 8));
   5037     }
   5038   else
   5039     {
   5040       arc_set_attribute_int (Tag_ARC_ABI_osver, E_ARC_OSABI_CURRENT >> 8);
   5041     }
   5042 
   5043   /* Tag_ARC_ISA_config.  */
   5044   arc_check_feature();
   5045 
   5046   for (i = 0; i < ARRAY_SIZE (feature_list); i++)
   5047     if (selected_cpu.features & feature_list[i].feature)
   5048       s = arc_stralloc (s, feature_list[i].attr);
   5049 
   5050   if (s)
   5051     arc_set_attribute_string (Tag_ARC_ISA_config, s);
   5052 
   5053   /* Tag_ARC_ISA_mpy_option.  */
   5054   arc_set_attribute_int (Tag_ARC_ISA_mpy_option, mpy_option);
   5055 
   5056   /* Tag_ARC_ABI_pic.  */
   5057   arc_set_attribute_int (Tag_ARC_ABI_pic, pic_option);
   5058 
   5059   /* Tag_ARC_ABI_sda.  */
   5060   arc_set_attribute_int (Tag_ARC_ABI_sda, sda_option);
   5061 
   5062   /* Tag_ARC_ABI_tls.  */
   5063   arc_set_attribute_int (Tag_ARC_ABI_tls, tls_option);
   5064 
   5065   /* Tag_ARC_ATR_version.  */
   5066   arc_set_attribute_int (Tag_ARC_ATR_version, 1);
   5067 
   5068   /* Tag_ARC_ABI_rf16.  */
   5069   if (attributes_set_explicitly[Tag_ARC_ABI_rf16]
   5070       && bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
   5071 				   Tag_ARC_ABI_rf16)
   5072       && !rf16_only)
   5073     {
   5074       as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full "
   5075 		 "register file"));
   5076       if (!bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_ABI_rf16, 0))
   5077 	as_fatal (_("error adding attribute: %s"),
   5078 		  bfd_errmsg (bfd_get_error ()));
   5079     }
   5080 }
   5081 
   5082 /* Add the default contents for the .ARC.attributes section.  */
   5083 
   5084 void
   5085 arc_md_finish (void)
   5086 {
   5087   arc_set_public_attributes ();
   5088 
   5089   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
   5090     as_fatal (_("could not set architecture and machine"));
   5091 
   5092   bfd_set_private_flags (stdoutput, selected_cpu.eflags);
   5093 }
   5094 
   5095 void arc_copy_symbol_attributes (symbolS *dest, symbolS *src)
   5096 {
   5097   ARC_GET_FLAG (dest) = ARC_GET_FLAG (src);
   5098 }
   5099 
   5100 int arc_convert_symbolic_attribute (const char *name)
   5101 {
   5102   static const struct
   5103   {
   5104     const char * name;
   5105     const int    tag;
   5106   }
   5107   attribute_table[] =
   5108     {
   5109 #define T(tag) {#tag, tag}
   5110   T (Tag_ARC_PCS_config),
   5111   T (Tag_ARC_CPU_base),
   5112   T (Tag_ARC_CPU_variation),
   5113   T (Tag_ARC_CPU_name),
   5114   T (Tag_ARC_ABI_rf16),
   5115   T (Tag_ARC_ABI_osver),
   5116   T (Tag_ARC_ABI_sda),
   5117   T (Tag_ARC_ABI_pic),
   5118   T (Tag_ARC_ABI_tls),
   5119   T (Tag_ARC_ABI_enumsize),
   5120   T (Tag_ARC_ABI_exceptions),
   5121   T (Tag_ARC_ABI_double_size),
   5122   T (Tag_ARC_ISA_config),
   5123   T (Tag_ARC_ISA_apex),
   5124   T (Tag_ARC_ISA_mpy_option),
   5125   T (Tag_ARC_ATR_version)
   5126 #undef T
   5127     };
   5128   unsigned int i;
   5129 
   5130   if (name == NULL)
   5131     return -1;
   5132 
   5133   for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
   5134     if (streq (name, attribute_table[i].name))
   5135       return attribute_table[i].tag;
   5136 
   5137   return -1;
   5138 }
   5139 
   5140 /* Local variables:
   5141    eval: (c-set-style "gnu")
   5142    indent-tabs-mode: t
   5143    End:  */
   5144