Home | History | Annotate | Line # | Download | only in config
tc-arc.c revision 1.1.1.11
      1 /* tc-arc.c -- Assembler for the ARC
      2    Copyright (C) 1994-2026 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_32_PLT_PCREL,		0),
    548   DEF (sda,	DUMMY_RELOC_ARC_ENTRY,		1),
    549   DEF (pcl,	BFD_RELOC_32_PCREL,		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 for a special parsing action when assembling 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 	  expression (tok);
   1279 	  tok->X_md = O_absent;
   1280 
   1281 	  if (*input_line_pointer == '@')
   1282 	    parse_reloc_symbol (tok);
   1283 
   1284 	  debug_exp (tok);
   1285 
   1286 	  if (tok->X_op == O_illegal
   1287               || tok->X_op == O_absent
   1288               || num_args == ntok)
   1289 	    goto err;
   1290 
   1291 	  saw_comma = false;
   1292 	  saw_arg = true;
   1293 	  tok++;
   1294 	  num_args++;
   1295 	  break;
   1296 
   1297 	case '%':
   1298 	  /* Can be a register.  */
   1299 	  ++input_line_pointer;
   1300 	  /* Fall through.  */
   1301 	default:
   1302 
   1303 	  if ((saw_arg && !saw_comma) || num_args == ntok)
   1304 	    goto err;
   1305 
   1306 	  /* Tell arc_parse_name to do its job.  */
   1307 	  assembling_insn = true;
   1308 	  expression (tok);
   1309 	  assembling_insn = false;
   1310 	  tok->X_md = O_absent;
   1311 
   1312 	  /* Legacy: There are cases when we have
   1313 	     identifier@relocation_type, if it is the case parse the
   1314 	     relocation type as well.  */
   1315 	  if (*input_line_pointer == '@')
   1316 	    parse_reloc_symbol (tok);
   1317 	  else
   1318 	    resolve_register (tok);
   1319 
   1320 	  debug_exp (tok);
   1321 
   1322 	  if (tok->X_op == O_illegal
   1323               || tok->X_op == O_absent
   1324               || num_args == ntok)
   1325 	    goto err;
   1326 
   1327 	  saw_comma = false;
   1328 	  saw_arg = true;
   1329 	  tok++;
   1330 	  num_args++;
   1331 	  break;
   1332 	}
   1333     }
   1334 
   1335  fini:
   1336   if (saw_comma || brk_lvl)
   1337     goto err;
   1338   input_line_pointer = old_input_line_pointer;
   1339 
   1340   return num_args;
   1341 
   1342  err:
   1343   if (brk_lvl)
   1344     as_bad (_("Brackets in operand field incorrect"));
   1345   else if (saw_comma)
   1346     as_bad (_("extra comma"));
   1347   else if (!saw_arg)
   1348     as_bad (_("missing argument"));
   1349   else
   1350     as_bad (_("missing comma or colon"));
   1351   input_line_pointer = old_input_line_pointer;
   1352   return -1;
   1353 }
   1354 
   1355 /* Parse the flags to a structure.  */
   1356 
   1357 static int
   1358 tokenize_flags (const char *str,
   1359 		struct arc_flags flags[],
   1360 		int nflg)
   1361 {
   1362   char *old_input_line_pointer;
   1363   bool saw_flg = false;
   1364   bool saw_dot = false;
   1365   int num_flags  = 0;
   1366   size_t flgnamelen;
   1367 
   1368   memset (flags, 0, sizeof (*flags) * nflg);
   1369 
   1370   /* Save and restore input_line_pointer around this function.  */
   1371   old_input_line_pointer = input_line_pointer;
   1372   input_line_pointer = (char *) str;
   1373 
   1374   while (*input_line_pointer)
   1375     {
   1376       switch (*input_line_pointer)
   1377 	{
   1378 	case '.':
   1379 	  input_line_pointer++;
   1380 	  if (saw_dot)
   1381 	    goto err;
   1382 	  saw_dot = true;
   1383 	  saw_flg = false;
   1384 	  break;
   1385 
   1386 	default:
   1387 	  if (is_end_of_stmt (*input_line_pointer)
   1388 	      || is_whitespace (*input_line_pointer))
   1389 	    goto fini;
   1390 
   1391 	  if (saw_flg && !saw_dot)
   1392 	    goto err;
   1393 
   1394 	  if (num_flags >= nflg)
   1395 	    goto err;
   1396 
   1397 	  flgnamelen = strspn (input_line_pointer,
   1398 			       "abcdefghijklmnopqrstuvwxyz0123456789");
   1399 	  if (flgnamelen > MAX_FLAG_NAME_LENGTH)
   1400 	    goto err;
   1401 
   1402 	  memcpy (flags->name, input_line_pointer, flgnamelen);
   1403 
   1404 	  input_line_pointer += flgnamelen;
   1405 	  flags++;
   1406 	  saw_dot = false;
   1407 	  saw_flg = true;
   1408 	  num_flags++;
   1409 	  break;
   1410 	}
   1411     }
   1412 
   1413  fini:
   1414   input_line_pointer = old_input_line_pointer;
   1415   return num_flags;
   1416 
   1417  err:
   1418   if (saw_dot)
   1419     as_bad (_("extra dot"));
   1420   else if (!saw_flg)
   1421     as_bad (_("unrecognized flag"));
   1422   else
   1423     as_bad (_("failed to parse flags"));
   1424   input_line_pointer = old_input_line_pointer;
   1425   return -1;
   1426 }
   1427 
   1428 /* Apply the fixups in order.  */
   1429 
   1430 static void
   1431 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
   1432 {
   1433   int i;
   1434 
   1435   for (i = 0; i < insn->nfixups; i++)
   1436     {
   1437       struct arc_fixup *fixup = &insn->fixups[i];
   1438       int size, pcrel, offset = 0;
   1439 
   1440       /* FIXME! the reloc size is wrong in the BFD file.
   1441 	 When it is fixed please delete me.  */
   1442       size = ((insn->len == 2) && !fixup->islong) ? 2 : 4;
   1443 
   1444       if (fixup->islong)
   1445 	offset = insn->len;
   1446 
   1447       /* Some fixups are only used internally, thus no howto.  */
   1448       if (fixup->reloc == 0)
   1449 	as_fatal (_("Unhandled reloc type"));
   1450 
   1451       if ((int) fixup->reloc < 0)
   1452 	{
   1453 	  /* FIXME! the reloc size is wrong in the BFD file.
   1454 	     When it is fixed please enable me.
   1455 	     size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
   1456 	  pcrel = fixup->pcrel;
   1457 	}
   1458       else
   1459 	{
   1460 	  reloc_howto_type *reloc_howto =
   1461 	    bfd_reloc_type_lookup (stdoutput, fixup->reloc);
   1462 	  gas_assert (reloc_howto);
   1463 
   1464 	  /* FIXME! the reloc size is wrong in the BFD file.
   1465 	     When it is fixed please enable me.
   1466 	     size = bfd_get_reloc_size (reloc_howto); */
   1467 	  pcrel = reloc_howto->pc_relative;
   1468 	}
   1469 
   1470       pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
   1471 offset %d + %d\n",
   1472 		fragP->fr_file, fragP->fr_line,
   1473 		(fixup->reloc < 0) ? "Internal" :
   1474 		bfd_get_reloc_code_name (fixup->reloc),
   1475 		pcrel ? "Y" : "N",
   1476 		size, fix, offset);
   1477       fix_new_exp (fragP, fix + offset,
   1478 		   size, &fixup->exp, pcrel, fixup->reloc);
   1479 
   1480       /* Check for ZOLs, and update symbol info if any.  */
   1481       if (LP_INSN (insn->insn))
   1482 	{
   1483 	  gas_assert (fixup->exp.X_add_symbol);
   1484 	  ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
   1485 	}
   1486     }
   1487 }
   1488 
   1489 /* Actually output an instruction with its fixup.  */
   1490 
   1491 static void
   1492 emit_insn0 (struct arc_insn *insn, char *where, bool relax)
   1493 {
   1494   char *f = where;
   1495   size_t total_len;
   1496 
   1497   pr_debug ("Emit insn : 0x%llx\n", insn->insn);
   1498   pr_debug ("\tLength  : %d\n", insn->len);
   1499   pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
   1500 
   1501   /* Write out the instruction.  */
   1502   total_len = insn->len + (insn->has_limm ? 4 : 0);
   1503   if (!relax)
   1504     f = frag_more (total_len);
   1505 
   1506   md_number_to_chars_midend(f, insn->insn, insn->len);
   1507 
   1508   if (insn->has_limm)
   1509     md_number_to_chars_midend (f + insn->len, insn->limm, 4);
   1510   dwarf2_emit_insn (total_len);
   1511 
   1512   if (!relax)
   1513     apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
   1514 }
   1515 
   1516 static void
   1517 emit_insn1 (struct arc_insn *insn)
   1518 {
   1519   /* How frag_var's args are currently configured:
   1520      - rs_machine_dependent, to dictate it's a relaxation frag.
   1521      - FRAG_MAX_GROWTH, maximum size of instruction
   1522      - 0, variable size that might grow...unused by generic relaxation.
   1523      - frag_now->fr_subtype, fr_subtype starting value, set previously.
   1524      - s, opand expression.
   1525      - 0, offset but it's unused.
   1526      - 0, opcode but it's unused.  */
   1527   symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
   1528   frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
   1529 
   1530   if (frag_room () < FRAG_MAX_GROWTH)
   1531     {
   1532       /* Handle differently when frag literal memory is exhausted.
   1533 	 This is used because when there's not enough memory left in
   1534 	 the current frag, a new frag is created and the information
   1535 	 we put into frag_now->tc_frag_data is disregarded.  */
   1536 
   1537       struct arc_relax_type relax_info_copy;
   1538       relax_substateT subtype = frag_now->fr_subtype;
   1539 
   1540       memcpy (&relax_info_copy, &frag_now->tc_frag_data,
   1541 	      sizeof (struct arc_relax_type));
   1542 
   1543       frag_wane (frag_now);
   1544       frag_grow (FRAG_MAX_GROWTH);
   1545 
   1546       memcpy (&frag_now->tc_frag_data, &relax_info_copy,
   1547 	      sizeof (struct arc_relax_type));
   1548 
   1549       frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
   1550 		subtype, s, 0, 0);
   1551     }
   1552   else
   1553     frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
   1554 	      frag_now->fr_subtype, s, 0, 0);
   1555 }
   1556 
   1557 static void
   1558 emit_insn (struct arc_insn *insn)
   1559 {
   1560   if (insn->relax)
   1561     emit_insn1 (insn);
   1562   else
   1563     emit_insn0 (insn, NULL, false);
   1564 }
   1565 
   1566 /* Check whether a symbol involves a register.  */
   1567 
   1568 static bool
   1569 contains_register (symbolS *sym)
   1570 {
   1571   if (sym)
   1572     {
   1573       expressionS *ex = symbol_get_value_expression (sym);
   1574 
   1575       return ((O_register == ex->X_op)
   1576 	      && !contains_register (ex->X_add_symbol)
   1577 	      && !contains_register (ex->X_op_symbol));
   1578     }
   1579 
   1580   return false;
   1581 }
   1582 
   1583 /* Returns the register number within a symbol.  */
   1584 
   1585 static int
   1586 get_register (symbolS *sym)
   1587 {
   1588   if (!contains_register (sym))
   1589     return -1;
   1590 
   1591   expressionS *ex = symbol_get_value_expression (sym);
   1592   return regno (ex->X_add_number);
   1593 }
   1594 
   1595 /* Return true if a RELOC is generic.  A generic reloc is PC-rel of a
   1596    simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_32_PCREL.  */
   1597 
   1598 static bool
   1599 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
   1600 {
   1601   if (!reloc)
   1602     return false;
   1603 
   1604   switch (reloc)
   1605     {
   1606     case BFD_RELOC_ARC_SDA_LDST:
   1607     case BFD_RELOC_ARC_SDA_LDST1:
   1608     case BFD_RELOC_ARC_SDA_LDST2:
   1609     case BFD_RELOC_ARC_SDA16_LD:
   1610     case BFD_RELOC_ARC_SDA16_LD1:
   1611     case BFD_RELOC_ARC_SDA16_LD2:
   1612     case BFD_RELOC_ARC_SDA16_ST2:
   1613     case BFD_RELOC_ARC_SDA32_ME:
   1614       return false;
   1615     default:
   1616       return true;
   1617     }
   1618 }
   1619 
   1620 /* Allocates a tok entry.  */
   1621 
   1622 static int
   1623 allocate_tok (expressionS *tok, int ntok, int cidx)
   1624 {
   1625   if (ntok > MAX_INSN_ARGS - 2)
   1626     return 0; /* No space left.  */
   1627 
   1628   if (cidx > ntok)
   1629     return 0; /* Incorrect args.  */
   1630 
   1631   memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
   1632 
   1633   if (cidx == ntok)
   1634     return 1; /* Success.  */
   1635   return allocate_tok (tok, ntok - 1, cidx);
   1636 }
   1637 
   1638 /* Check if an particular ARC feature is enabled.  */
   1639 
   1640 static bool
   1641 check_cpu_feature (insn_subclass_t sc)
   1642 {
   1643   if (is_code_density_p (sc) && !(selected_cpu.features & CD))
   1644     return false;
   1645 
   1646   if (is_spfp_p (sc) && !(selected_cpu.features & SPX))
   1647     return false;
   1648 
   1649   if (is_dpfp_p (sc) && !(selected_cpu.features & DPX))
   1650     return false;
   1651 
   1652   if (is_fpuda_p (sc) && !(selected_cpu.features & DPA))
   1653     return false;
   1654 
   1655   if (is_nps400_p (sc) && !(selected_cpu.features & NPS400))
   1656     return false;
   1657 
   1658   return true;
   1659 }
   1660 
   1661 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
   1662    operands in OPCODE.  Stores the matching OPCODES into the FIRST_PFLAG
   1663    array and returns TRUE if the flag operands all match, otherwise,
   1664    returns FALSE, in which case the FIRST_PFLAG array may have been
   1665    modified.  */
   1666 
   1667 static bool
   1668 parse_opcode_flags (const struct arc_opcode *opcode,
   1669                     int nflgs,
   1670                     struct arc_flags *first_pflag)
   1671 {
   1672   int lnflg, i;
   1673   const unsigned char *flgidx;
   1674 
   1675   lnflg = nflgs;
   1676   for (i = 0; i < nflgs; i++)
   1677     first_pflag[i].flgp = NULL;
   1678 
   1679   /* Check the flags.  Iterate over the valid flag classes.  */
   1680   for (flgidx = opcode->flags; *flgidx; ++flgidx)
   1681     {
   1682       /* Get a valid flag class.  */
   1683       const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
   1684       const unsigned *flgopridx;
   1685       int cl_matches = 0;
   1686       struct arc_flags *pflag = NULL;
   1687 
   1688       /* Check if opcode has implicit flag classes.  */
   1689       if (cl_flags->flag_class & F_CLASS_IMPLICIT)
   1690 	continue;
   1691 
   1692       /* Check for extension conditional codes.  */
   1693       if (ext_condcode.arc_ext_condcode
   1694           && cl_flags->flag_class & F_CLASS_EXTEND)
   1695         {
   1696           struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode;
   1697           while (pf->name)
   1698             {
   1699               pflag = first_pflag;
   1700               for (i = 0; i < nflgs; i++, pflag++)
   1701                 {
   1702                   if (!strcmp (pf->name, pflag->name))
   1703                     {
   1704                       if (pflag->flgp != NULL)
   1705                         return false;
   1706                       /* Found it.  */
   1707                       cl_matches++;
   1708                       pflag->flgp = pf;
   1709                       lnflg--;
   1710                       break;
   1711                     }
   1712                 }
   1713               pf++;
   1714             }
   1715         }
   1716 
   1717       for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
   1718         {
   1719           const struct arc_flag_operand *flg_operand;
   1720 
   1721           pflag = first_pflag;
   1722           flg_operand = &arc_flag_operands[*flgopridx];
   1723           for (i = 0; i < nflgs; i++, pflag++)
   1724             {
   1725               /* Match against the parsed flags.  */
   1726               if (!strcmp (flg_operand->name, pflag->name))
   1727                 {
   1728                   if (pflag->flgp != NULL)
   1729                     return false;
   1730                   cl_matches++;
   1731                   pflag->flgp = flg_operand;
   1732                   lnflg--;
   1733                   break; /* goto next flag class and parsed flag.  */
   1734                 }
   1735             }
   1736         }
   1737 
   1738       if ((cl_flags->flag_class & F_CLASS_REQUIRED) && cl_matches == 0)
   1739         return false;
   1740       if ((cl_flags->flag_class & F_CLASS_OPTIONAL) && cl_matches > 1)
   1741         return false;
   1742     }
   1743 
   1744   /* Did I check all the parsed flags?  */
   1745   return lnflg == 0;
   1746 }
   1747 
   1748 
   1749 /* Search forward through all variants of an opcode looking for a
   1750    syntax match.  */
   1751 
   1752 static const struct arc_opcode *
   1753 find_opcode_match (const struct arc_opcode_hash_entry *entry,
   1754 		   expressionS *tok,
   1755 		   int *pntok,
   1756 		   struct arc_flags *first_pflag,
   1757 		   int nflgs,
   1758 		   int *pcpumatch,
   1759 		   const char **errmsg)
   1760 {
   1761   const struct arc_opcode *opcode;
   1762   struct arc_opcode_hash_entry_iterator iter;
   1763   int ntok = *pntok;
   1764   int got_cpu_match = 0;
   1765   expressionS bktok[MAX_INSN_ARGS];
   1766   int bkntok, maxerridx = 0;
   1767   expressionS emptyE;
   1768   const char *tmpmsg = NULL;
   1769 
   1770   arc_opcode_hash_entry_iterator_init (&iter);
   1771   memset (&emptyE, 0, sizeof (emptyE));
   1772   memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
   1773   bkntok = ntok;
   1774 
   1775   for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter);
   1776        opcode != NULL;
   1777        opcode = arc_opcode_hash_entry_iterator_next (entry, &iter))
   1778     {
   1779       const unsigned char *opidx;
   1780       int tokidx = 0;
   1781       const expressionS *t = &emptyE;
   1782 
   1783       pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
   1784 		frag_now->fr_file, frag_now->fr_line, opcode->opcode);
   1785 
   1786       /* Don't match opcodes that don't exist on this
   1787 	 architecture.  */
   1788       if (!(opcode->cpu & selected_cpu.flags))
   1789 	goto match_failed;
   1790 
   1791       if (!check_cpu_feature (opcode->subclass))
   1792 	goto match_failed;
   1793 
   1794       got_cpu_match = 1;
   1795       pr_debug ("cpu ");
   1796 
   1797       /* Check the operands.  */
   1798       for (opidx = opcode->operands; *opidx; ++opidx)
   1799 	{
   1800 	  const struct arc_operand *operand = &arc_operands[*opidx];
   1801 
   1802 	  /* Only take input from real operands.  */
   1803 	  if (ARC_OPERAND_IS_FAKE (operand))
   1804 	    continue;
   1805 
   1806 	  /* When we expect input, make sure we have it.  */
   1807 	  if (tokidx >= ntok)
   1808 	    goto match_failed;
   1809 
   1810 	  /* Match operand type with expression type.  */
   1811 	  switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
   1812 	    {
   1813             case ARC_OPERAND_ADDRTYPE:
   1814 	      {
   1815 		tmpmsg = NULL;
   1816 
   1817 		/* Check to be an address type.  */
   1818 		if (tok[tokidx].X_op != O_addrtype)
   1819 		  goto match_failed;
   1820 
   1821 		/* All address type operands need to have an insert
   1822 		   method in order to check that we have the correct
   1823 		   address type.  */
   1824 		gas_assert (operand->insert != NULL);
   1825 		(*operand->insert) (0, tok[tokidx].X_add_number,
   1826 				    &tmpmsg);
   1827 		if (tmpmsg != NULL)
   1828 		  goto match_failed;
   1829 	      }
   1830               break;
   1831 
   1832 	    case ARC_OPERAND_IR:
   1833 	      /* Check to be a register.  */
   1834 	      if ((tok[tokidx].X_op != O_register
   1835 		   || !is_ir_num (tok[tokidx].X_add_number))
   1836 		  && !(operand->flags & ARC_OPERAND_IGNORE))
   1837 		goto match_failed;
   1838 
   1839 	      /* If expect duplicate, make sure it is duplicate.  */
   1840 	      if (operand->flags & ARC_OPERAND_DUPLICATE)
   1841 		{
   1842 		  /* Check for duplicate.  */
   1843 		  if (t->X_op != O_register
   1844 		      || !is_ir_num (t->X_add_number)
   1845 		      || (regno (t->X_add_number) !=
   1846 			  regno (tok[tokidx].X_add_number)))
   1847 		    goto match_failed;
   1848 		}
   1849 
   1850 	      /* Special handling?  */
   1851 	      if (operand->insert)
   1852 		{
   1853 		  tmpmsg = NULL;
   1854 		  (*operand->insert)(0,
   1855 				     regno (tok[tokidx].X_add_number),
   1856 				     &tmpmsg);
   1857 		  if (tmpmsg)
   1858 		    {
   1859 		      if (operand->flags & ARC_OPERAND_IGNORE)
   1860 			{
   1861 			  /* Missing argument, create one.  */
   1862 			  if (!allocate_tok (tok, ntok - 1, tokidx))
   1863 			    goto match_failed;
   1864 
   1865 			  tok[tokidx].X_op = O_absent;
   1866 			  ++ntok;
   1867 			}
   1868 		      else
   1869 			goto match_failed;
   1870 		    }
   1871 		}
   1872 
   1873 	      t = &tok[tokidx];
   1874 	      break;
   1875 
   1876 	    case ARC_OPERAND_BRAKET:
   1877 	      /* Check if bracket is also in opcode table as
   1878 		 operand.  */
   1879 	      if (tok[tokidx].X_op != O_bracket)
   1880 		goto match_failed;
   1881 	      break;
   1882 
   1883             case ARC_OPERAND_COLON:
   1884               /* Check if colon is also in opcode table as operand.  */
   1885               if (tok[tokidx].X_op != O_colon)
   1886                 goto match_failed;
   1887               break;
   1888 
   1889 	    case ARC_OPERAND_LIMM:
   1890 	    case ARC_OPERAND_SIGNED:
   1891 	    case ARC_OPERAND_UNSIGNED:
   1892 	      switch (tok[tokidx].X_op)
   1893 		{
   1894 		case O_illegal:
   1895 		case O_absent:
   1896 		case O_register:
   1897 		  goto match_failed;
   1898 
   1899 		case O_bracket:
   1900 		  /* Got an (too) early bracket, check if it is an
   1901 		     ignored operand.  N.B. This procedure works only
   1902 		     when bracket is the last operand!  */
   1903 		  if (!(operand->flags & ARC_OPERAND_IGNORE))
   1904 		    goto match_failed;
   1905 		  /* Insert the missing operand.  */
   1906 		  if (!allocate_tok (tok, ntok - 1, tokidx))
   1907 		    goto match_failed;
   1908 
   1909 		  tok[tokidx].X_op = O_absent;
   1910 		  ++ntok;
   1911 		  break;
   1912 
   1913 		case O_symbol:
   1914 		  {
   1915 		    const char *p;
   1916 		    char *tmpp, *pp;
   1917 		    const struct arc_aux_reg *auxr;
   1918 
   1919 		    if (opcode->insn_class != AUXREG)
   1920 		      goto de_fault;
   1921 		    p = S_GET_NAME (tok[tokidx].X_add_symbol);
   1922 
   1923 		    /* For compatibility reasons, an aux register can
   1924 		       be spelled with upper or lower case
   1925 		       letters.  */
   1926 		    tmpp = strdup (p);
   1927 		    for (pp = tmpp; *pp; ++pp) *pp = TOLOWER (*pp);
   1928 
   1929 		    auxr = str_hash_find (arc_aux_hash, tmpp);
   1930 		    if (auxr)
   1931 		      {
   1932 			/* We modify the token array here, safe in the
   1933 			   knowledge, that if this was the wrong
   1934 			   choice then the original contents will be
   1935 			   restored from BKTOK.  */
   1936 			tok[tokidx].X_op = O_constant;
   1937 			tok[tokidx].X_add_number = auxr->address;
   1938 			ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX);
   1939 		      }
   1940 		    free (tmpp);
   1941 
   1942 		    if (tok[tokidx].X_op != O_constant)
   1943 		      goto de_fault;
   1944 		  }
   1945 		  /* Fall through.  */
   1946 		case O_constant:
   1947 		  /* Check the range.  */
   1948 		  if (operand->bits != 32
   1949 		      && !(operand->flags & ARC_OPERAND_NCHK))
   1950 		    {
   1951 		      offsetT min, max, val;
   1952 		      val = tok[tokidx].X_add_number;
   1953 
   1954 		      if (operand->flags & ARC_OPERAND_SIGNED)
   1955 			{
   1956 			  max = (1 << (operand->bits - 1)) - 1;
   1957 			  min = -(1 << (operand->bits - 1));
   1958 			}
   1959 		      else
   1960 			{
   1961 			  max = (1 << operand->bits) - 1;
   1962 			  min = 0;
   1963 			}
   1964 
   1965 		      if (val < min || val > max)
   1966 			{
   1967 			  tmpmsg = _("immediate is out of bounds");
   1968 			  goto match_failed;
   1969 			}
   1970 
   1971 		      /* Check alignments.  */
   1972 		      if ((operand->flags & ARC_OPERAND_ALIGNED32)
   1973 			  && (val & 0x03))
   1974 			{
   1975 			  tmpmsg = _("immediate is not 32bit aligned");
   1976 			  goto match_failed;
   1977 			}
   1978 
   1979 		      if ((operand->flags & ARC_OPERAND_ALIGNED16)
   1980 			  && (val & 0x01))
   1981 			{
   1982 			  tmpmsg = _("immediate is not 16bit aligned");
   1983 			  goto match_failed;
   1984 			}
   1985 		    }
   1986 		  else if (operand->flags & ARC_OPERAND_NCHK)
   1987 		    {
   1988 		      if (operand->insert)
   1989 			{
   1990 			  tmpmsg = NULL;
   1991 			  (*operand->insert)(0,
   1992 					     tok[tokidx].X_add_number,
   1993 					     &tmpmsg);
   1994 			  if (tmpmsg)
   1995 			    goto match_failed;
   1996 			}
   1997 		      else if (!(operand->flags & ARC_OPERAND_IGNORE))
   1998 			goto match_failed;
   1999 		    }
   2000 		  break;
   2001 
   2002 		case O_subtract:
   2003 		  /* Check if it is register range.  */
   2004 		  if ((tok[tokidx].X_add_number == 0)
   2005 		      && contains_register (tok[tokidx].X_add_symbol)
   2006 		      && contains_register (tok[tokidx].X_op_symbol))
   2007 		    {
   2008 		      int regs;
   2009 
   2010 		      regs = get_register (tok[tokidx].X_add_symbol);
   2011 		      regs <<= 16;
   2012 		      regs |= get_register (tok[tokidx].X_op_symbol);
   2013 		      if (operand->insert)
   2014 			{
   2015 			  tmpmsg = NULL;
   2016 			  (*operand->insert)(0,
   2017 					     regs,
   2018 					     &tmpmsg);
   2019 			  if (tmpmsg)
   2020 			    goto match_failed;
   2021 			}
   2022 		      else
   2023 			goto match_failed;
   2024 		      break;
   2025 		    }
   2026 		  /* Fall through.  */
   2027 		default:
   2028 		de_fault:
   2029 		  if (operand->default_reloc == 0)
   2030 		    goto match_failed; /* The operand needs relocation.  */
   2031 
   2032 		  /* Relocs requiring long immediate.  FIXME! make it
   2033 		     generic and move it to a function.  */
   2034 		  switch (tok[tokidx].X_md)
   2035 		    {
   2036 		    case O_gotoff:
   2037 		    case O_gotpc:
   2038 		    case O_pcl:
   2039 		    case O_tpoff:
   2040 		    case O_dtpoff:
   2041 		    case O_tlsgd:
   2042 		    case O_tlsie:
   2043 		      if (!(operand->flags & ARC_OPERAND_LIMM))
   2044 			goto match_failed;
   2045 		      /* Fall through.  */
   2046 		    case O_absent:
   2047 		      if (!generic_reloc_p (operand->default_reloc))
   2048 			goto match_failed;
   2049 		      break;
   2050 		    default:
   2051 		      break;
   2052 		    }
   2053 		  break;
   2054 		}
   2055 	      /* If expect duplicate, make sure it is duplicate.  */
   2056 	      if (operand->flags & ARC_OPERAND_DUPLICATE)
   2057 		{
   2058 		  if (t->X_op == O_illegal
   2059 		      || t->X_op == O_absent
   2060 		      || t->X_op == O_register
   2061 		      || (t->X_add_number != tok[tokidx].X_add_number))
   2062 		    {
   2063 		      tmpmsg = _("operand is not duplicate of the "
   2064 				 "previous one");
   2065 		      goto match_failed;
   2066 		    }
   2067 		}
   2068 	      t = &tok[tokidx];
   2069 	      break;
   2070 
   2071 	    default:
   2072 	      /* Everything else should have been fake.  */
   2073 	      abort ();
   2074 	    }
   2075 
   2076 	  ++tokidx;
   2077 	}
   2078       pr_debug ("opr ");
   2079 
   2080       /* Setup ready for flag parsing.  */
   2081       if (!parse_opcode_flags (opcode, nflgs, first_pflag))
   2082 	{
   2083 	  tmpmsg = _("flag mismatch");
   2084 	  goto match_failed;
   2085 	}
   2086 
   2087       pr_debug ("flg");
   2088       /* Possible match -- did we use all of our input?  */
   2089       if (tokidx == ntok)
   2090 	{
   2091 	  *pntok = ntok;
   2092 	  pr_debug ("\n");
   2093 	  return opcode;
   2094 	}
   2095       tmpmsg = _("too many arguments");
   2096 
   2097     match_failed:;
   2098       pr_debug ("\n");
   2099       /* Restore the original parameters.  */
   2100       memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
   2101       ntok = bkntok;
   2102       if (tokidx >= maxerridx
   2103 	  && tmpmsg)
   2104 	{
   2105 	  maxerridx = tokidx;
   2106 	  *errmsg = tmpmsg;
   2107 	}
   2108     }
   2109 
   2110   if (*pcpumatch)
   2111     *pcpumatch = got_cpu_match;
   2112 
   2113   return NULL;
   2114 }
   2115 
   2116 /* Swap operand tokens.  */
   2117 
   2118 static void
   2119 swap_operand (expressionS *operand_array,
   2120 	      unsigned source,
   2121 	      unsigned destination)
   2122 {
   2123   expressionS cpy_operand;
   2124   expressionS *src_operand;
   2125   expressionS *dst_operand;
   2126   size_t size;
   2127 
   2128   if (source == destination)
   2129     return;
   2130 
   2131   src_operand = &operand_array[source];
   2132   dst_operand = &operand_array[destination];
   2133   size = sizeof (expressionS);
   2134 
   2135   /* Make copy of operand to swap with and swap.  */
   2136   memcpy (&cpy_operand, dst_operand, size);
   2137   memcpy (dst_operand, src_operand, size);
   2138   memcpy (src_operand, &cpy_operand, size);
   2139 }
   2140 
   2141 /* Check if *op matches *tok type.
   2142    Returns FALSE if they don't match, TRUE if they match.  */
   2143 
   2144 static bool
   2145 pseudo_operand_match (const expressionS *tok,
   2146 		      const struct arc_operand_operation *op)
   2147 {
   2148   offsetT min, max, val;
   2149   bool ret;
   2150   const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
   2151 
   2152   ret = false;
   2153   switch (tok->X_op)
   2154     {
   2155     case O_constant:
   2156       if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
   2157 	ret = 1;
   2158       else if (!(operand_real->flags & ARC_OPERAND_IR))
   2159 	{
   2160 	  val = tok->X_add_number + op->count;
   2161 	  if (operand_real->flags & ARC_OPERAND_SIGNED)
   2162 	    {
   2163 	      max = (1 << (operand_real->bits - 1)) - 1;
   2164 	      min = -(1 << (operand_real->bits - 1));
   2165 	    }
   2166 	  else
   2167 	    {
   2168 	      max = (1 << operand_real->bits) - 1;
   2169 	      min = 0;
   2170 	    }
   2171 	  if (min <= val && val <= max)
   2172 	    ret = true;
   2173 	}
   2174       break;
   2175 
   2176     case O_symbol:
   2177       /* Handle all symbols as long immediates or signed 9.  */
   2178       if (operand_real->flags & ARC_OPERAND_LIMM
   2179 	  || ((operand_real->flags & ARC_OPERAND_SIGNED)
   2180 	      && operand_real->bits == 9))
   2181 	ret = true;
   2182       break;
   2183 
   2184     case O_register:
   2185       if (operand_real->flags & ARC_OPERAND_IR)
   2186 	ret = true;
   2187       break;
   2188 
   2189     case O_bracket:
   2190       if (operand_real->flags & ARC_OPERAND_BRAKET)
   2191 	ret = true;
   2192       break;
   2193 
   2194     default:
   2195       /* Unknown.  */
   2196       break;
   2197     }
   2198   return ret;
   2199 }
   2200 
   2201 /* Find pseudo instruction in array.  */
   2202 
   2203 static const struct arc_pseudo_insn *
   2204 find_pseudo_insn (const char *opname,
   2205 		  int ntok,
   2206 		  const expressionS *tok)
   2207 {
   2208   const struct arc_pseudo_insn *pseudo_insn = NULL;
   2209   const struct arc_operand_operation *op;
   2210   unsigned int i;
   2211   int j;
   2212 
   2213   for (i = 0; i < arc_num_pseudo_insn; ++i)
   2214     {
   2215       pseudo_insn = &arc_pseudo_insns[i];
   2216       if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
   2217 	{
   2218 	  op = pseudo_insn->operand;
   2219 	  for (j = 0; j < ntok; ++j)
   2220 	    if (!pseudo_operand_match (&tok[j], &op[j]))
   2221 	      break;
   2222 
   2223 	  /* Found the right instruction.  */
   2224 	  if (j == ntok)
   2225 	    return pseudo_insn;
   2226 	}
   2227     }
   2228   return NULL;
   2229 }
   2230 
   2231 /* Assumes the expressionS *tok is of sufficient size.  */
   2232 
   2233 static const struct arc_opcode_hash_entry *
   2234 find_special_case_pseudo (const char *opname,
   2235 			  int *ntok,
   2236 			  expressionS *tok,
   2237 			  int *nflgs,
   2238 			  struct arc_flags *pflags)
   2239 {
   2240   const struct arc_pseudo_insn *pseudo_insn = NULL;
   2241   const struct arc_operand_operation *operand_pseudo;
   2242   const struct arc_operand *operand_real;
   2243   unsigned i;
   2244   char construct_operand[MAX_CONSTR_STR];
   2245 
   2246   /* Find whether opname is in pseudo instruction array.  */
   2247   pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
   2248 
   2249   if (pseudo_insn == NULL)
   2250     return NULL;
   2251 
   2252   /* Handle flag, Limited to one flag at the moment.  */
   2253   if (pseudo_insn->flag_r != NULL)
   2254     *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
   2255 			      MAX_INSN_FLGS - *nflgs);
   2256 
   2257   /* Handle operand operations.  */
   2258   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
   2259     {
   2260       operand_pseudo = &pseudo_insn->operand[i];
   2261       operand_real = &arc_operands[operand_pseudo->operand_idx];
   2262 
   2263       if (operand_real->flags & ARC_OPERAND_BRAKET
   2264 	  && !operand_pseudo->needs_insert)
   2265 	continue;
   2266 
   2267       /* Has to be inserted (i.e. this token does not exist yet).  */
   2268       if (operand_pseudo->needs_insert)
   2269 	{
   2270 	  if (operand_real->flags & ARC_OPERAND_BRAKET)
   2271 	    {
   2272 	      tok[i].X_op = O_bracket;
   2273 	      ++(*ntok);
   2274 	      continue;
   2275 	    }
   2276 
   2277 	  /* Check if operand is a register or constant and handle it
   2278 	     by type.  */
   2279 	  if (operand_real->flags & ARC_OPERAND_IR)
   2280 	    snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
   2281 		      operand_pseudo->count);
   2282 	  else
   2283 	    snprintf (construct_operand, MAX_CONSTR_STR, "%d",
   2284 		      operand_pseudo->count);
   2285 
   2286 	  tokenize_arguments (construct_operand, &tok[i], 1);
   2287 	  ++(*ntok);
   2288 	}
   2289 
   2290       else if (operand_pseudo->count)
   2291 	{
   2292 	  /* Operand number has to be adjusted accordingly (by operand
   2293 	     type).  */
   2294 	  switch (tok[i].X_op)
   2295 	    {
   2296 	    case O_constant:
   2297 	      tok[i].X_add_number += operand_pseudo->count;
   2298 	      break;
   2299 
   2300 	    case O_symbol:
   2301 	      break;
   2302 
   2303 	    default:
   2304 	      /* Ignored.  */
   2305 	      break;
   2306 	    }
   2307 	}
   2308     }
   2309 
   2310   /* Swap operands if necessary.  Only supports one swap at the
   2311      moment.  */
   2312   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
   2313     {
   2314       operand_pseudo = &pseudo_insn->operand[i];
   2315 
   2316       if (operand_pseudo->swap_operand_idx == i)
   2317 	continue;
   2318 
   2319       swap_operand (tok, i, operand_pseudo->swap_operand_idx);
   2320 
   2321       /* Prevent a swap back later by breaking out.  */
   2322       break;
   2323     }
   2324 
   2325   return arc_find_opcode (pseudo_insn->mnemonic_r);
   2326 }
   2327 
   2328 static const struct arc_opcode_hash_entry *
   2329 find_special_case_flag (const char *opname,
   2330 			int *nflgs,
   2331 			struct arc_flags *pflags)
   2332 {
   2333   unsigned int i;
   2334   const char *flagnm;
   2335   unsigned flag_idx, flag_arr_idx;
   2336   size_t flaglen, oplen;
   2337   const struct arc_flag_special *arc_flag_special_opcode;
   2338   const struct arc_opcode_hash_entry *entry;
   2339 
   2340   /* Search for special case instruction.  */
   2341   for (i = 0; i < arc_num_flag_special; i++)
   2342     {
   2343       arc_flag_special_opcode = &arc_flag_special_cases[i];
   2344       oplen = strlen (arc_flag_special_opcode->name);
   2345 
   2346       if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
   2347 	continue;
   2348 
   2349       /* Found a potential special case instruction, now test for
   2350 	 flags.  */
   2351       for (flag_arr_idx = 0;; ++flag_arr_idx)
   2352 	{
   2353 	  flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
   2354 	  if (flag_idx == 0)
   2355 	    break;  /* End of array, nothing found.  */
   2356 
   2357 	  flagnm = arc_flag_operands[flag_idx].name;
   2358 	  flaglen = strlen (flagnm);
   2359 	  if (strcmp (opname + oplen, flagnm) == 0)
   2360 	    {
   2361               entry = arc_find_opcode (arc_flag_special_opcode->name);
   2362 
   2363 	      if (*nflgs + 1 > MAX_INSN_FLGS)
   2364 		break;
   2365 	      memcpy (pflags[*nflgs].name, flagnm, flaglen);
   2366 	      pflags[*nflgs].name[flaglen] = '\0';
   2367 	      (*nflgs)++;
   2368 	      return entry;
   2369 	    }
   2370 	}
   2371     }
   2372   return NULL;
   2373 }
   2374 
   2375 /* Used to find special case opcode.  */
   2376 
   2377 static const struct arc_opcode_hash_entry *
   2378 find_special_case (const char *opname,
   2379 		   int *nflgs,
   2380 		   struct arc_flags *pflags,
   2381 		   expressionS *tok,
   2382 		   int *ntok)
   2383 {
   2384   const struct arc_opcode_hash_entry *entry;
   2385 
   2386   entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
   2387 
   2388   if (entry == NULL)
   2389     entry = find_special_case_flag (opname, nflgs, pflags);
   2390 
   2391   return entry;
   2392 }
   2393 
   2394 /* Autodetect cpu attribute list.  */
   2395 
   2396 static void
   2397 autodetect_attributes (const struct arc_opcode *opcode,
   2398 			 const expressionS *tok,
   2399 			 int ntok)
   2400 {
   2401   unsigned i;
   2402   struct mpy_type
   2403   {
   2404     unsigned feature;
   2405     unsigned encoding;
   2406   } mpy_list[] = {{ MPY1E, 1 }, { MPY6E, 6 }, { MPY7E, 7 }, { MPY8E, 8 },
   2407 		 { MPY9E, 9 }};
   2408 
   2409   for (i = 0; i < ARRAY_SIZE (feature_list); i++)
   2410     if (opcode->subclass == feature_list[i].feature)
   2411       selected_cpu.features |= feature_list[i].feature;
   2412 
   2413   for (i = 0; i < ARRAY_SIZE (mpy_list); i++)
   2414     if (opcode->subclass == mpy_list[i].feature)
   2415       mpy_option = mpy_list[i].encoding;
   2416 
   2417   for (i = 0; i < (unsigned) ntok; i++)
   2418     {
   2419       switch (tok[i].X_md)
   2420 	{
   2421 	case O_gotoff:
   2422 	case O_gotpc:
   2423 	case O_plt:
   2424 	  pic_option = 2;
   2425 	  break;
   2426 	case O_sda:
   2427 	  sda_option = 2;
   2428 	  break;
   2429 	case O_tlsgd:
   2430 	case O_tlsie:
   2431 	case O_tpoff9:
   2432 	case O_tpoff:
   2433 	case O_dtpoff9:
   2434 	case O_dtpoff:
   2435 	  tls_option = 1;
   2436 	  break;
   2437 	default:
   2438 	  break;
   2439 	}
   2440 
   2441       switch (tok[i].X_op)
   2442 	{
   2443 	case O_register:
   2444 	  if ((tok[i].X_add_number >= 4 && tok[i].X_add_number <= 9)
   2445 	      || (tok[i].X_add_number >= 16 && tok[i].X_add_number <= 25))
   2446 	    rf16_only = false;
   2447 	  break;
   2448 	default:
   2449 	  break;
   2450 	}
   2451     }
   2452 }
   2453 
   2454 /* Given an opcode name, pre-tockenized set of argumenst and the
   2455    opcode flags, take it all the way through emission.  */
   2456 
   2457 static void
   2458 assemble_tokens (const char *opname,
   2459 		 expressionS *tok,
   2460 		 int ntok,
   2461 		 struct arc_flags *pflags,
   2462 		 int nflgs)
   2463 {
   2464   bool found_something = false;
   2465   const struct arc_opcode_hash_entry *entry;
   2466   int cpumatch = 1;
   2467   const char *errmsg = NULL;
   2468 
   2469   /* Search opcodes.  */
   2470   entry = arc_find_opcode (opname);
   2471 
   2472   /* Couldn't find opcode conventional way, try special cases.  */
   2473   if (entry == NULL)
   2474     entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
   2475 
   2476   if (entry != NULL)
   2477     {
   2478       const struct arc_opcode *opcode;
   2479 
   2480       pr_debug ("%s:%d: assemble_tokens: %s\n",
   2481 		frag_now->fr_file, frag_now->fr_line, opname);
   2482       found_something = true;
   2483       opcode = find_opcode_match (entry, tok, &ntok, pflags,
   2484 				  nflgs, &cpumatch, &errmsg);
   2485       if (opcode != NULL)
   2486 	{
   2487 	  struct arc_insn insn;
   2488 
   2489 	  autodetect_attributes (opcode,  tok, ntok);
   2490 	  assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
   2491 	  emit_insn (&insn);
   2492 	  return;
   2493 	}
   2494     }
   2495 
   2496   if (found_something)
   2497     {
   2498       if (cpumatch)
   2499 	if (errmsg)
   2500 	  as_bad (_("%s for instruction '%s'"), errmsg, opname);
   2501 	else
   2502 	  as_bad (_("inappropriate arguments for opcode '%s'"), opname);
   2503       else
   2504 	as_bad (_("opcode '%s' not supported for target %s"), opname,
   2505 		selected_cpu.name);
   2506     }
   2507   else
   2508     as_bad (_("unknown opcode '%s'"), opname);
   2509 }
   2510 
   2511 /* The public interface to the instruction assembler.  */
   2512 
   2513 void
   2514 md_assemble (char *str)
   2515 {
   2516   char *opname;
   2517   expressionS tok[MAX_INSN_ARGS];
   2518   int ntok, nflg;
   2519   size_t opnamelen;
   2520   struct arc_flags flags[MAX_INSN_FLGS];
   2521 
   2522   /* Split off the opcode.  */
   2523   opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123456789");
   2524   opname = xmemdup0 (str, opnamelen);
   2525 
   2526   /* Tokenize the flags.  */
   2527   if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
   2528     {
   2529       as_bad (_("syntax error"));
   2530       return;
   2531     }
   2532 
   2533   /* Scan up to the end of the mnemonic which must end in space or end
   2534      of string.  */
   2535   str += opnamelen;
   2536   for (; !is_end_of_stmt (*str); str++)
   2537     if (is_whitespace (*str))
   2538       break;
   2539 
   2540   /* Tokenize the rest of the line.  */
   2541   if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
   2542     {
   2543       as_bad (_("syntax error"));
   2544       return;
   2545     }
   2546 
   2547   /* Finish it off.  */
   2548   assemble_tokens (opname, tok, ntok, flags, nflg);
   2549 }
   2550 
   2551 /* Callback to insert a register into the hash table.  */
   2552 
   2553 static void
   2554 declare_register (const char *name, int number)
   2555 {
   2556   symbolS *regS = symbol_create (name, reg_section,
   2557 				 &zero_address_frag, number);
   2558 
   2559   if (str_hash_insert (arc_reg_hash, S_GET_NAME (regS), regS, 0) != NULL)
   2560     as_fatal (_("duplicate %s"), name);
   2561 }
   2562 
   2563 /* Construct symbols for each of the general registers.  */
   2564 
   2565 static void
   2566 declare_register_set (void)
   2567 {
   2568   int i;
   2569   for (i = 0; i < 64; ++i)
   2570     {
   2571       char name[32];
   2572 
   2573       sprintf (name, "r%d", i);
   2574       declare_register (name, i);
   2575       if ((i & 0x01) == 0)
   2576 	{
   2577 	  sprintf (name, "r%dr%d", i, i+1);
   2578 	  declare_register (name, i);
   2579 	}
   2580     }
   2581 }
   2582 
   2583 /* Construct a symbol for an address type.  */
   2584 
   2585 static void
   2586 declare_addrtype (const char *name, int number)
   2587 {
   2588   symbolS *addrtypeS = symbol_create (name, undefined_section,
   2589 				      &zero_address_frag, number);
   2590 
   2591   if (str_hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS), addrtypeS, 0))
   2592     as_fatal (_("duplicate %s"), name);
   2593 }
   2594 
   2595 /* Port-specific assembler initialization.  This function is called
   2596    once, at assembler startup time.  */
   2597 
   2598 void
   2599 md_begin (void)
   2600 {
   2601   const struct arc_opcode *opcode = arc_opcodes;
   2602 
   2603   if (mach_selection_mode == MACH_SELECTION_NONE)
   2604     arc_select_cpu (TARGET_WITH_CPU, MACH_SELECTION_FROM_DEFAULT);
   2605 
   2606   /* The endianness can be chosen "at the factory".  */
   2607   target_big_endian = byte_order == BIG_ENDIAN;
   2608 
   2609   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
   2610     as_warn (_("could not set architecture and machine"));
   2611 
   2612   /* Set elf header flags.  */
   2613   bfd_set_private_flags (stdoutput, selected_cpu.eflags);
   2614 
   2615   /* Set up a hash table for the instructions.  */
   2616   arc_opcode_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
   2617 				       arc_opcode_free, xcalloc, free);
   2618 
   2619   /* Initialize the hash table with the insns.  */
   2620   do
   2621     {
   2622       const char *name = opcode->name;
   2623 
   2624       arc_insert_opcode (opcode);
   2625 
   2626       while (++opcode && opcode->name
   2627 	     && (opcode->name == name
   2628 		 || !strcmp (opcode->name, name)))
   2629 	continue;
   2630     }while (opcode->name);
   2631 
   2632   /* Register declaration.  */
   2633   arc_reg_hash = str_htab_create ();
   2634 
   2635   declare_register_set ();
   2636   declare_register ("gp", 26);
   2637   declare_register ("fp", 27);
   2638   declare_register ("sp", 28);
   2639   declare_register ("ilink", 29);
   2640   declare_register ("ilink1", 29);
   2641   declare_register ("ilink2", 30);
   2642   declare_register ("blink", 31);
   2643 
   2644   /* XY memory registers.  */
   2645   declare_register ("x0_u0", 32);
   2646   declare_register ("x0_u1", 33);
   2647   declare_register ("x1_u0", 34);
   2648   declare_register ("x1_u1", 35);
   2649   declare_register ("x2_u0", 36);
   2650   declare_register ("x2_u1", 37);
   2651   declare_register ("x3_u0", 38);
   2652   declare_register ("x3_u1", 39);
   2653   declare_register ("y0_u0", 40);
   2654   declare_register ("y0_u1", 41);
   2655   declare_register ("y1_u0", 42);
   2656   declare_register ("y1_u1", 43);
   2657   declare_register ("y2_u0", 44);
   2658   declare_register ("y2_u1", 45);
   2659   declare_register ("y3_u0", 46);
   2660   declare_register ("y3_u1", 47);
   2661   declare_register ("x0_nu", 48);
   2662   declare_register ("x1_nu", 49);
   2663   declare_register ("x2_nu", 50);
   2664   declare_register ("x3_nu", 51);
   2665   declare_register ("y0_nu", 52);
   2666   declare_register ("y1_nu", 53);
   2667   declare_register ("y2_nu", 54);
   2668   declare_register ("y3_nu", 55);
   2669 
   2670   declare_register ("mlo", 57);
   2671   declare_register ("mmid", 58);
   2672   declare_register ("mhi", 59);
   2673 
   2674   declare_register ("acc1", 56);
   2675   declare_register ("acc2", 57);
   2676 
   2677   declare_register ("lp_count", 60);
   2678   declare_register ("pcl", 63);
   2679 
   2680   /* Initialize the last instructions.  */
   2681   memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
   2682 
   2683   /* Aux register declaration.  */
   2684   arc_aux_hash = str_htab_create ();
   2685 
   2686   const struct arc_aux_reg *auxr = &arc_aux_regs[0];
   2687   unsigned int i;
   2688   for (i = 0; i < arc_num_aux_regs; i++, auxr++)
   2689     {
   2690       if (!(auxr->cpu & selected_cpu.flags))
   2691 	continue;
   2692 
   2693       if ((auxr->subclass != NONE)
   2694 	  && !check_cpu_feature (auxr->subclass))
   2695 	continue;
   2696 
   2697       if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != 0)
   2698 	as_fatal (_("duplicate %s"), auxr->name);
   2699     }
   2700 
   2701   /* Address type declaration.  */
   2702   arc_addrtype_hash = str_htab_create ();
   2703 
   2704   declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD);
   2705   declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID);
   2706   declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD);
   2707   declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD);
   2708   declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD);
   2709   declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM);
   2710   declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA);
   2711   declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD);
   2712   declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD);
   2713   declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD);
   2714   declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID);
   2715   declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD);
   2716   declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM);
   2717   declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD);
   2718   declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA);
   2719   declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD);
   2720 }
   2721 
   2722 void
   2723 arc_md_end (void)
   2724 {
   2725   htab_delete (arc_opcode_hash);
   2726   htab_delete (arc_reg_hash);
   2727   htab_delete (arc_aux_hash);
   2728   htab_delete (arc_addrtype_hash);
   2729 }
   2730 
   2731 /* Write a value out to the object file, using the appropriate
   2732    endianness.  */
   2733 
   2734 void
   2735 md_number_to_chars (char *buf,
   2736 		    valueT val,
   2737 		    int n)
   2738 {
   2739   if (target_big_endian)
   2740     number_to_chars_bigendian (buf, val, n);
   2741   else
   2742     number_to_chars_littleendian (buf, val, n);
   2743 }
   2744 
   2745 /* Round up a section size to the appropriate boundary.  */
   2746 
   2747 valueT
   2748 md_section_align (segT segment,
   2749 		  valueT size)
   2750 {
   2751   int align = bfd_section_alignment (segment);
   2752 
   2753   return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
   2754 }
   2755 
   2756 /* The location from which a PC relative jump should be calculated,
   2757    given a PC relative reloc.  */
   2758 
   2759 long
   2760 md_pcrel_from_section (fixS *fixP,
   2761 		       segT sec)
   2762 {
   2763   offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
   2764 
   2765   pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
   2766 
   2767   if (fixP->fx_addsy != NULL
   2768       && (!S_IS_DEFINED (fixP->fx_addsy)
   2769 	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
   2770     {
   2771       pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
   2772 
   2773       /* The symbol is undefined (or is defined but not in this section).
   2774 	 Let the linker figure it out.  */
   2775       return 0;
   2776     }
   2777 
   2778   if ((int) fixP->fx_r_type < 0)
   2779     {
   2780       /* These are the "internal" relocations.  Align them to
   2781 	 32 bit boundary (PCL), for the moment.  */
   2782       base &= ~3;
   2783     }
   2784   else
   2785     {
   2786       switch (fixP->fx_r_type)
   2787 	{
   2788 	case BFD_RELOC_32_PCREL:
   2789 	  /* The hardware calculates relative to the start of the
   2790 	     insn, but this relocation is relative to location of the
   2791 	     LIMM, compensate.  The base always needs to be
   2792 	     subtracted by 4 as we do not support this type of PCrel
   2793 	     relocation for short instructions.  */
   2794 	  base -= 4;
   2795 	  /* Fall through.  */
   2796 	case BFD_RELOC_32_PLT_PCREL:
   2797 	case BFD_RELOC_ARC_S25H_PCREL_PLT:
   2798 	case BFD_RELOC_ARC_S21H_PCREL_PLT:
   2799 	case BFD_RELOC_ARC_S25W_PCREL_PLT:
   2800 	case BFD_RELOC_ARC_S21W_PCREL_PLT:
   2801 
   2802 	case BFD_RELOC_ARC_S21H_PCREL:
   2803 	case BFD_RELOC_ARC_S25H_PCREL:
   2804 	case BFD_RELOC_ARC_S13_PCREL:
   2805 	case BFD_RELOC_ARC_S21W_PCREL:
   2806 	case BFD_RELOC_ARC_S25W_PCREL:
   2807 	  base &= ~3;
   2808 	  break;
   2809 	default:
   2810 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   2811 			_("unhandled reloc %s in md_pcrel_from_section"),
   2812 		  bfd_get_reloc_code_name (fixP->fx_r_type));
   2813 	  break;
   2814 	}
   2815     }
   2816 
   2817   pr_debug ("pcrel from %" PRIx64 " + %lx = %" PRIx64 ", "
   2818 	    "symbol: %s (%" PRIx64 ")\n",
   2819 	    (uint64_t) fixP->fx_frag->fr_address, fixP->fx_where, (uint64_t) base,
   2820 	    fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
   2821 	    fixP->fx_addsy ? (uint64_t) S_GET_VALUE (fixP->fx_addsy) : (uint64_t) 0);
   2822 
   2823   return base;
   2824 }
   2825 
   2826 /* Given a BFD relocation find the corresponding operand.  */
   2827 
   2828 static const struct arc_operand *
   2829 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
   2830 {
   2831   unsigned i;
   2832 
   2833   for (i = 0; i < arc_num_operands; i++)
   2834     if (arc_operands[i].default_reloc == reloc)
   2835       return  &arc_operands[i];
   2836   return NULL;
   2837 }
   2838 
   2839 /* Insert an operand value into an instruction.  */
   2840 
   2841 static unsigned long long
   2842 insert_operand (unsigned long long insn,
   2843 		const struct arc_operand *operand,
   2844 		long long val,
   2845 		const char *file,
   2846 		unsigned line)
   2847 {
   2848   offsetT min = 0, max = 0;
   2849 
   2850   if (operand->bits != 32
   2851       && !(operand->flags & ARC_OPERAND_NCHK)
   2852       && !(operand->flags & ARC_OPERAND_FAKE))
   2853     {
   2854       if (operand->flags & ARC_OPERAND_SIGNED)
   2855 	{
   2856 	  max = (1 << (operand->bits - 1)) - 1;
   2857 	  min = -(1 << (operand->bits - 1));
   2858 	}
   2859       else
   2860 	{
   2861 	  max = (1 << operand->bits) - 1;
   2862 	  min = 0;
   2863 	}
   2864 
   2865       if (val < min || val > max)
   2866 	as_bad_value_out_of_range (_("operand"),
   2867 				   val, min, max, file, line);
   2868     }
   2869 
   2870   pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
   2871 	    min, val, max, insn);
   2872 
   2873   if ((operand->flags & ARC_OPERAND_ALIGNED32)
   2874       && (val & 0x03))
   2875     as_bad_where (file, line,
   2876 		  _("Unaligned operand. Needs to be 32bit aligned"));
   2877 
   2878   if ((operand->flags & ARC_OPERAND_ALIGNED16)
   2879       && (val & 0x01))
   2880     as_bad_where (file, line,
   2881 		  _("Unaligned operand. Needs to be 16bit aligned"));
   2882 
   2883   if (operand->insert)
   2884     {
   2885       const char *errmsg = NULL;
   2886 
   2887       insn = (*operand->insert) (insn, val, &errmsg);
   2888       if (errmsg)
   2889 	as_warn_where (file, line, "%s", errmsg);
   2890     }
   2891   else
   2892     {
   2893       if (operand->flags & ARC_OPERAND_TRUNCATE)
   2894 	{
   2895 	  if (operand->flags & ARC_OPERAND_ALIGNED32)
   2896 	    val >>= 2;
   2897 	  if (operand->flags & ARC_OPERAND_ALIGNED16)
   2898 	    val >>= 1;
   2899 	}
   2900       insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
   2901     }
   2902   return insn;
   2903 }
   2904 
   2905 /* Apply a fixup to the object code.  At this point all symbol values
   2906    should be fully resolved, and we attempt to completely resolve the
   2907    reloc.  If we can not do that, we determine the correct reloc code
   2908    and put it back in the fixup.  To indicate that a fixup has been
   2909    eliminated, set fixP->fx_done.  */
   2910 
   2911 void
   2912 md_apply_fix (fixS *fixP,
   2913 	      valueT *valP,
   2914 	      segT seg)
   2915 {
   2916   char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
   2917   valueT value = *valP;
   2918   unsigned insn = 0;
   2919   symbolS *fx_addsy, *fx_subsy;
   2920   offsetT fx_offset;
   2921   segT add_symbol_segment = absolute_section;
   2922   segT sub_symbol_segment = absolute_section;
   2923   const struct arc_operand *operand = NULL;
   2924   extended_bfd_reloc_code_real_type reloc;
   2925 
   2926   pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
   2927 	    fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
   2928 	    ((int) fixP->fx_r_type < 0) ? "Internal":
   2929 	    bfd_get_reloc_code_name (fixP->fx_r_type), value,
   2930 	    fixP->fx_offset);
   2931 
   2932   fx_addsy = fixP->fx_addsy;
   2933   fx_subsy = fixP->fx_subsy;
   2934   fx_offset = 0;
   2935 
   2936   if (fx_addsy)
   2937     {
   2938       add_symbol_segment = S_GET_SEGMENT (fx_addsy);
   2939     }
   2940 
   2941   if (fx_subsy
   2942       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
   2943       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
   2944       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
   2945     {
   2946       resolve_symbol_value (fx_subsy);
   2947       sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
   2948 
   2949       if (sub_symbol_segment == absolute_section)
   2950 	{
   2951 	  /* The symbol is really a constant.  */
   2952 	  fx_offset -= S_GET_VALUE (fx_subsy);
   2953 	  fx_subsy = NULL;
   2954 	}
   2955       else
   2956 	{
   2957 	  as_bad_subtract (fixP);
   2958 	  return;
   2959 	}
   2960     }
   2961 
   2962   if (fx_addsy
   2963       && !S_IS_WEAK (fx_addsy))
   2964     {
   2965       if (add_symbol_segment == seg
   2966 	  && fixP->fx_pcrel)
   2967 	{
   2968 	  value += S_GET_VALUE (fx_addsy);
   2969 	  value -= md_pcrel_from_section (fixP, seg);
   2970 	  fx_addsy = NULL;
   2971 	  fixP->fx_pcrel = false;
   2972 	}
   2973       else if (add_symbol_segment == absolute_section)
   2974 	{
   2975 	  value = fixP->fx_offset;
   2976 	  fx_offset += S_GET_VALUE (fixP->fx_addsy);
   2977 	  fx_addsy = NULL;
   2978 	  fixP->fx_pcrel = false;
   2979 	}
   2980     }
   2981 
   2982   if (!fx_addsy)
   2983     fixP->fx_done = true;
   2984 
   2985   if (fixP->fx_pcrel)
   2986     {
   2987       if (fx_addsy
   2988 	  && ((S_IS_DEFINED (fx_addsy)
   2989 	       && S_GET_SEGMENT (fx_addsy) != seg)
   2990 	      || S_IS_WEAK (fx_addsy)))
   2991 	value += md_pcrel_from_section (fixP, seg);
   2992 
   2993       switch (fixP->fx_r_type)
   2994 	{
   2995 	case BFD_RELOC_ARC_32_ME:
   2996 	  /* This is a pc-relative value in a LIMM.  Adjust it to the
   2997 	     address of the instruction not to the address of the
   2998 	     LIMM.  Note: it is not any longer valid this affirmation as
   2999 	     the linker consider ARC_PC32 a fixup to entire 64 bit
   3000 	     insn.  */
   3001 	  fixP->fx_offset += fixP->fx_frag->fr_address;
   3002 	  /* Fall through.  */
   3003 	case BFD_RELOC_32:
   3004 	  fixP->fx_r_type = BFD_RELOC_32_PCREL;
   3005 	  /* Fall through.  */
   3006 	case BFD_RELOC_32_PCREL:
   3007 	  /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
   3008 	  break;
   3009 	default:
   3010 	  if ((int) fixP->fx_r_type < 0)
   3011 	    as_bad_where (fixP->fx_file, fixP->fx_line,
   3012 			  _("PC relative relocation not allowed for (internal)"
   3013 			    " type %d"),
   3014 			  fixP->fx_r_type);
   3015 	  break;
   3016 	}
   3017     }
   3018 
   3019   pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
   3020 	    fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
   3021 	    ((int) fixP->fx_r_type < 0) ? "Internal":
   3022 	    bfd_get_reloc_code_name (fixP->fx_r_type), value,
   3023 	    fixP->fx_offset);
   3024 
   3025 
   3026   /* Now check for TLS relocations.  */
   3027   reloc = fixP->fx_r_type;
   3028   switch (reloc)
   3029     {
   3030     case BFD_RELOC_ARC_TLS_DTPOFF:
   3031     case BFD_RELOC_ARC_TLS_LE_32:
   3032       if (fixP->fx_done)
   3033 	break;
   3034       /* Fall through.  */
   3035     case BFD_RELOC_ARC_TLS_GD_GOT:
   3036     case BFD_RELOC_ARC_TLS_IE_GOT:
   3037       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   3038       break;
   3039 
   3040     case BFD_RELOC_ARC_TLS_GD_LD:
   3041       gas_assert (!fixP->fx_offset);
   3042       if (fixP->fx_subsy)
   3043 	fixP->fx_offset
   3044 	  = (S_GET_VALUE (fixP->fx_subsy)
   3045 	     - fixP->fx_frag->fr_address- fixP->fx_where);
   3046       fixP->fx_subsy = NULL;
   3047       /* Fall through.  */
   3048     case BFD_RELOC_ARC_TLS_GD_CALL:
   3049       /* These two relocs are there just to allow ld to change the tls
   3050 	 model for this symbol, by patching the code.  The offset -
   3051 	 and scale, if any - will be installed by the linker.  */
   3052       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   3053       break;
   3054 
   3055     case BFD_RELOC_ARC_TLS_LE_S9:
   3056     case BFD_RELOC_ARC_TLS_DTPOFF_S9:
   3057       as_bad (_("TLS_*_S9 relocs are not supported yet"));
   3058       break;
   3059 
   3060     default:
   3061       break;
   3062     }
   3063 
   3064   if (!fixP->fx_done)
   3065     {
   3066       return;
   3067     }
   3068 
   3069   /* Adjust the value if we have a constant.  */
   3070   value += fx_offset;
   3071 
   3072   /* For hosts with longs bigger than 32-bits make sure that the top
   3073      bits of a 32-bit negative value read in by the parser are set,
   3074      so that the correct comparisons are made.  */
   3075   if (value & 0x80000000)
   3076     value |= (-1UL << 31);
   3077 
   3078   reloc = fixP->fx_r_type;
   3079   switch (reloc)
   3080     {
   3081     case BFD_RELOC_8:
   3082     case BFD_RELOC_16:
   3083     case BFD_RELOC_24:
   3084     case BFD_RELOC_32:
   3085     case BFD_RELOC_64:
   3086     case BFD_RELOC_ARC_32_PCREL:
   3087       md_number_to_chars (fixpos, value, fixP->fx_size);
   3088       return;
   3089 
   3090     case BFD_RELOC_ARC_GOTPC32:
   3091       /* I cannot fix an GOTPC relocation because I need to relax it
   3092 	 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc.  */
   3093       as_bad (_("Unsupported operation on reloc"));
   3094       return;
   3095 
   3096     case BFD_RELOC_ARC_TLS_DTPOFF:
   3097     case BFD_RELOC_ARC_TLS_LE_32:
   3098       gas_assert (!fixP->fx_addsy);
   3099       gas_assert (!fixP->fx_subsy);
   3100       /* Fall through.  */
   3101 
   3102     case BFD_RELOC_ARC_GOTOFF:
   3103     case BFD_RELOC_ARC_32_ME:
   3104     case BFD_RELOC_32_PCREL:
   3105       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
   3106       return;
   3107 
   3108     case BFD_RELOC_32_PLT_PCREL:
   3109       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
   3110       return;
   3111 
   3112     case BFD_RELOC_ARC_S25H_PCREL_PLT:
   3113       reloc = BFD_RELOC_ARC_S25W_PCREL;
   3114       goto solve_plt;
   3115 
   3116     case BFD_RELOC_ARC_S21H_PCREL_PLT:
   3117       reloc = BFD_RELOC_ARC_S21H_PCREL;
   3118       goto solve_plt;
   3119 
   3120     case BFD_RELOC_ARC_S25W_PCREL_PLT:
   3121       reloc = BFD_RELOC_ARC_S25W_PCREL;
   3122       goto solve_plt;
   3123 
   3124     case BFD_RELOC_ARC_S21W_PCREL_PLT:
   3125       reloc = BFD_RELOC_ARC_S21W_PCREL;
   3126       /* Fall through.  */
   3127 
   3128     case BFD_RELOC_ARC_S25W_PCREL:
   3129     case BFD_RELOC_ARC_S21W_PCREL:
   3130     case BFD_RELOC_ARC_S21H_PCREL:
   3131     case BFD_RELOC_ARC_S25H_PCREL:
   3132     case BFD_RELOC_ARC_S13_PCREL:
   3133     solve_plt:
   3134       operand = find_operand_for_reloc (reloc);
   3135       gas_assert (operand);
   3136       break;
   3137 
   3138     default:
   3139       {
   3140 	if ((int) fixP->fx_r_type >= 0)
   3141 	  as_fatal (_("unhandled relocation type %s"),
   3142 		    bfd_get_reloc_code_name (fixP->fx_r_type));
   3143 
   3144 	/* The rest of these fixups needs to be completely resolved as
   3145 	   constants.  */
   3146 	if (fixP->fx_addsy != 0
   3147 	    && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
   3148 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   3149 			_("non-absolute expression in constant field"));
   3150 
   3151 	gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
   3152 	operand = &arc_operands[-(int) fixP->fx_r_type];
   3153 	break;
   3154       }
   3155     }
   3156 
   3157   if (target_big_endian)
   3158     {
   3159       switch (fixP->fx_size)
   3160 	{
   3161 	case 4:
   3162 	  insn = bfd_getb32 (fixpos);
   3163 	  break;
   3164 	case 2:
   3165 	  insn = bfd_getb16 (fixpos);
   3166 	  break;
   3167 	default:
   3168 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   3169 			_("unknown fixup size"));
   3170 	}
   3171     }
   3172   else
   3173     {
   3174       insn = 0;
   3175       switch (fixP->fx_size)
   3176 	{
   3177 	case 4:
   3178 	  insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
   3179 	  break;
   3180 	case 2:
   3181 	  insn = bfd_getl16 (fixpos);
   3182 	  break;
   3183 	default:
   3184 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   3185 			_("unknown fixup size"));
   3186 	}
   3187     }
   3188 
   3189   insn = insert_operand (insn, operand, (offsetT) value,
   3190 			 fixP->fx_file, fixP->fx_line);
   3191 
   3192   md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
   3193 }
   3194 
   3195 /* Prepare machine-dependent frags for relaxation.
   3196 
   3197    Called just before relaxation starts.  Any symbol that is now undefined
   3198    will not become defined.
   3199 
   3200    Return the correct fr_subtype in the frag.
   3201 
   3202    Return the initial "guess for fr_var" to caller.  The guess for fr_var
   3203    is *actually* the growth beyond fr_fix.  Whatever we do to grow fr_fix
   3204    or fr_var contributes to our returned value.
   3205 
   3206    Although it may not be explicit in the frag, pretend
   3207    fr_var starts with a value.  */
   3208 
   3209 int
   3210 md_estimate_size_before_relax (fragS *fragP,
   3211 			       segT segment)
   3212 {
   3213   int growth;
   3214 
   3215   /* If the symbol is not located within the same section AND it's not
   3216      an absolute section, use the maximum.  OR if the symbol is a
   3217      constant AND the insn is by nature not pc-rel, use the maximum.
   3218      OR if the symbol is being equated against another symbol, use the
   3219      maximum.  OR if the symbol is weak use the maximum.  */
   3220   if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
   3221        && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
   3222       || (symbol_constant_p (fragP->fr_symbol)
   3223 	  && !fragP->tc_frag_data.pcrel)
   3224       || symbol_equated_p (fragP->fr_symbol)
   3225       || S_IS_WEAK (fragP->fr_symbol))
   3226     {
   3227       while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
   3228 	++fragP->fr_subtype;
   3229     }
   3230 
   3231   growth = md_relax_table[fragP->fr_subtype].rlx_length;
   3232   fragP->fr_var = growth;
   3233 
   3234   pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
   3235 	   fragP->fr_file, fragP->fr_line, growth);
   3236 
   3237   return growth;
   3238 }
   3239 
   3240 /* Translate internal representation of relocation info to BFD target
   3241    format.  */
   3242 
   3243 arelent *
   3244 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
   3245 	      fixS *fixP)
   3246 {
   3247   arelent *reloc;
   3248   bfd_reloc_code_real_type code;
   3249 
   3250   reloc = notes_alloc (sizeof (arelent));
   3251   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   3252   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   3253   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   3254 
   3255   /* Make sure none of our internal relocations make it this far.
   3256      They'd better have been fully resolved by this point.  */
   3257   gas_assert ((int) fixP->fx_r_type > 0);
   3258 
   3259   code = fixP->fx_r_type;
   3260 
   3261   /* if we have something like add gp, pcl,
   3262      _GLOBAL_OFFSET_TABLE_@gotpc.  */
   3263   if (code == BFD_RELOC_ARC_GOTPC32
   3264       && GOT_symbol
   3265       && fixP->fx_addsy == GOT_symbol)
   3266     code = BFD_RELOC_ARC_GOTPC;
   3267 
   3268   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   3269   if (reloc->howto == NULL)
   3270     {
   3271       as_bad_where (fixP->fx_file, fixP->fx_line,
   3272 		    _("cannot represent `%s' relocation in object file"),
   3273 		    bfd_get_reloc_code_name (code));
   3274       return NULL;
   3275     }
   3276 
   3277   if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
   3278     as_fatal (_("internal error? cannot generate `%s' relocation"),
   3279 	      bfd_get_reloc_code_name (code));
   3280 
   3281   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
   3282 
   3283   reloc->addend = fixP->fx_offset;
   3284 
   3285   return reloc;
   3286 }
   3287 
   3288 /* Perform post-processing of machine-dependent frags after relaxation.
   3289    Called after relaxation is finished.
   3290    In:	Address of frag.
   3291    fr_type == rs_machine_dependent.
   3292    fr_subtype is what the address relaxed to.
   3293 
   3294    Out: Any fixS:s and constants are set up.  */
   3295 
   3296 void
   3297 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   3298 		 segT segment ATTRIBUTE_UNUSED,
   3299 		 fragS *fragP)
   3300 {
   3301   const relax_typeS *table_entry;
   3302   char *dest;
   3303   const struct arc_opcode *opcode;
   3304   struct arc_insn insn;
   3305   int size, fix;
   3306   struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
   3307 
   3308   fix = fragP->fr_fix;
   3309   dest = fragP->fr_literal + fix;
   3310   table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
   3311 
   3312   pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
   3313 	    "var: %" PRId64 "\n",
   3314 	    fragP->fr_file, fragP->fr_line,
   3315 	    fragP->fr_subtype, fix, (int64_t) fragP->fr_var);
   3316 
   3317   if (fragP->fr_subtype <= 0
   3318       && fragP->fr_subtype >= arc_num_relax_opcodes)
   3319     as_fatal (_("no relaxation found for this instruction."));
   3320 
   3321   opcode = &arc_relax_opcodes[fragP->fr_subtype];
   3322 
   3323   assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
   3324 	relax_arg->nflg, &insn);
   3325 
   3326   apply_fixups (&insn, fragP, fix);
   3327 
   3328   size = insn.len + (insn.has_limm ? 4 : 0);
   3329   gas_assert (table_entry->rlx_length == size);
   3330   emit_insn0 (&insn, dest, true);
   3331 
   3332   fragP->fr_fix += table_entry->rlx_length;
   3333   fragP->fr_var = 0;
   3334 }
   3335 
   3336 /* We have no need to default values of symbols.  We could catch
   3337    register names here, but that is handled by inserting them all in
   3338    the symbol table to begin with.  */
   3339 
   3340 symbolS *
   3341 md_undefined_symbol (char *name)
   3342 {
   3343   /* The arc abi demands that a GOT[0] should be referencible as
   3344      [pc+_DYNAMIC@gotpc].  Hence we convert a _DYNAMIC@gotpc to a
   3345      GOTPC reference to _GLOBAL_OFFSET_TABLE_.  */
   3346   if (((*name == '_')
   3347        && (*(name+1) == 'G')
   3348        && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)))
   3349     {
   3350       if (!GOT_symbol)
   3351 	{
   3352 	  if (symbol_find (name))
   3353 	    as_bad ("GOT already in symbol table");
   3354 
   3355 	  GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
   3356 				   &zero_address_frag, 0);
   3357 	};
   3358       return GOT_symbol;
   3359     }
   3360   return NULL;
   3361 }
   3362 
   3363 /* Turn a string in input_line_pointer into a floating point constant
   3364    of type type, and store the appropriate bytes in *litP.  The number
   3365    of LITTLENUMS emitted is stored in *sizeP.  An error message is
   3366    returned, or NULL on OK.  */
   3367 
   3368 const char *
   3369 md_atof (int type, char *litP, int *sizeP)
   3370 {
   3371   return ieee_md_atof (type, litP, sizeP, target_big_endian);
   3372 }
   3373 
   3374 /* Called for any expression that can not be recognized.  When the
   3375    function is called, `input_line_pointer' will point to the start of
   3376    the expression.  We use it when we have complex operations like
   3377    @label1 - @label2.  */
   3378 
   3379 void
   3380 md_operand (expressionS *expressionP)
   3381 {
   3382   char *p = input_line_pointer;
   3383   if (*p == '@')
   3384     {
   3385       input_line_pointer++;
   3386       expression (expressionP);
   3387       expressionP->X_md = O_absent;
   3388     }
   3389 }
   3390 
   3391 /* This function is called from the function 'expression', it attempts
   3392    to parse special names (in our case register names).  It fills in
   3393    the expression with the identified register.  It returns TRUE if
   3394    it is a register and FALSE otherwise.  */
   3395 
   3396 bool
   3397 arc_parse_name (const char *name,
   3398 		struct expressionS *e)
   3399 {
   3400   struct symbol *sym;
   3401 
   3402   if (!assembling_insn)
   3403     return false;
   3404 
   3405   sym = str_hash_find (arc_reg_hash, name);
   3406   if (sym)
   3407     {
   3408       e->X_op = O_register;
   3409       e->X_add_number = S_GET_VALUE (sym);
   3410       return true;
   3411     }
   3412 
   3413   sym = str_hash_find (arc_addrtype_hash, name);
   3414   if (sym)
   3415     {
   3416       e->X_op = O_addrtype;
   3417       e->X_add_number = S_GET_VALUE (sym);
   3418       return true;
   3419     }
   3420 
   3421   return false;
   3422 }
   3423 
   3424 /* md_parse_option
   3425    Invocation line includes a switch not recognized by the base assembler.
   3426    See if it's a processor-specific option.
   3427 
   3428    New options (supported) are:
   3429 
   3430    -mcpu=<cpu name>		 Assemble for selected processor
   3431    -EB/-mbig-endian		 Big-endian
   3432    -EL/-mlittle-endian		 Little-endian
   3433    -mrelax                       Enable relaxation
   3434 
   3435    The following CPU names are recognized:
   3436    arc600, arc700, arcem, archs, nps400.  */
   3437 
   3438 int
   3439 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
   3440 {
   3441   switch (c)
   3442     {
   3443     case OPTION_ARC600:
   3444     case OPTION_ARC601:
   3445       return md_parse_option (OPTION_MCPU, "arc600");
   3446 
   3447     case OPTION_ARC700:
   3448       return md_parse_option (OPTION_MCPU, "arc700");
   3449 
   3450     case OPTION_ARCEM:
   3451       return md_parse_option (OPTION_MCPU, "arcem");
   3452 
   3453     case OPTION_ARCHS:
   3454       return md_parse_option (OPTION_MCPU, "archs");
   3455 
   3456     case OPTION_MCPU:
   3457       {
   3458         arc_select_cpu (arg, MACH_SELECTION_FROM_COMMAND_LINE);
   3459 	break;
   3460       }
   3461 
   3462     case OPTION_EB:
   3463       arc_target_format = "elf32-bigarc";
   3464       byte_order = BIG_ENDIAN;
   3465       break;
   3466 
   3467     case OPTION_EL:
   3468       arc_target_format = "elf32-littlearc";
   3469       byte_order = LITTLE_ENDIAN;
   3470       break;
   3471 
   3472     case OPTION_CD:
   3473       selected_cpu.features |= CD;
   3474       cl_features |= CD;
   3475       arc_check_feature ();
   3476       break;
   3477 
   3478     case OPTION_RELAX:
   3479       relaxation_state = 1;
   3480       break;
   3481 
   3482     case OPTION_NPS400:
   3483       selected_cpu.features |= NPS400;
   3484       cl_features |= NPS400;
   3485       arc_check_feature ();
   3486       break;
   3487 
   3488     case OPTION_SPFP:
   3489       selected_cpu.features |= SPX;
   3490       cl_features |= SPX;
   3491       arc_check_feature ();
   3492       break;
   3493 
   3494     case OPTION_DPFP:
   3495       selected_cpu.features |= DPX;
   3496       cl_features |= DPX;
   3497       arc_check_feature ();
   3498       break;
   3499 
   3500     case OPTION_FPUDA:
   3501       selected_cpu.features |= DPA;
   3502       cl_features |= DPA;
   3503       arc_check_feature ();
   3504       break;
   3505 
   3506     /* Dummy options are accepted but have no effect.  */
   3507     case OPTION_USER_MODE:
   3508     case OPTION_LD_EXT_MASK:
   3509     case OPTION_SWAP:
   3510     case OPTION_NORM:
   3511     case OPTION_BARREL_SHIFT:
   3512     case OPTION_MIN_MAX:
   3513     case OPTION_NO_MPY:
   3514     case OPTION_EA:
   3515     case OPTION_MUL64:
   3516     case OPTION_SIMD:
   3517     case OPTION_XMAC_D16:
   3518     case OPTION_XMAC_24:
   3519     case OPTION_DSP_PACKA:
   3520     case OPTION_CRC:
   3521     case OPTION_DVBF:
   3522     case OPTION_TELEPHONY:
   3523     case OPTION_XYMEMORY:
   3524     case OPTION_LOCK:
   3525     case OPTION_SWAPE:
   3526     case OPTION_RTSC:
   3527       break;
   3528 
   3529     default:
   3530       return 0;
   3531     }
   3532 
   3533   return 1;
   3534 }
   3535 
   3536 /* Display the list of cpu names for use in the help text.  */
   3537 
   3538 static void
   3539 arc_show_cpu_list (FILE *stream)
   3540 {
   3541   int i, offset;
   3542   static const char *space_buf = "                          ";
   3543 
   3544   fprintf (stream, "%s", space_buf);
   3545   offset = strlen (space_buf);
   3546   for (i = 0; cpu_types[i].name != NULL; ++i)
   3547     {
   3548       bool last = (cpu_types[i + 1].name == NULL);
   3549 
   3550       /* If displaying the new cpu name string, and the ', ' (for all
   3551          but the last one) will take us past a target width of 80
   3552          characters, then it's time for a new line.  */
   3553       if (offset + strlen (cpu_types[i].name) + (last ? 0 : 2) > 80)
   3554         {
   3555           fprintf (stream, "\n%s", space_buf);
   3556           offset = strlen (space_buf);
   3557         }
   3558 
   3559       fprintf (stream, "%s%s", cpu_types[i].name, (last ? "\n" : ", "));
   3560       offset += strlen (cpu_types [i].name) + (last ? 0 : 2);
   3561     }
   3562 }
   3563 
   3564 void
   3565 md_show_usage (FILE *stream)
   3566 {
   3567   fprintf (stream, _("ARC-specific assembler options:\n"));
   3568 
   3569   fprintf (stream, "  -mcpu=<cpu name>\t  (default: %s), assemble for"
   3570            " CPU <cpu name>, one of:\n", TARGET_WITH_CPU);
   3571   arc_show_cpu_list (stream);
   3572   fprintf (stream, "\n");
   3573   fprintf (stream, "  -mA6/-mARC600/-mARC601  same as -mcpu=arc600\n");
   3574   fprintf (stream, "  -mA7/-mARC700\t\t  same as -mcpu=arc700\n");
   3575   fprintf (stream, "  -mEM\t\t\t  same as -mcpu=arcem\n");
   3576   fprintf (stream, "  -mHS\t\t\t  same as -mcpu=archs\n");
   3577 
   3578   fprintf (stream, "  -mnps400\t\t  enable NPS-400 extended instructions\n");
   3579   fprintf (stream, "  -mspfp\t\t  enable single-precision floating point"
   3580 	   " instructions\n");
   3581   fprintf (stream, "  -mdpfp\t\t  enable double-precision floating point"
   3582 	   " instructions\n");
   3583   fprintf (stream, "  -mfpuda\t\t  enable double-precision assist floating "
   3584                    "point\n\t\t\t  instructions for ARC EM\n");
   3585 
   3586   fprintf (stream,
   3587 	   "  -mcode-density\t  enable code density option for ARC EM\n");
   3588 
   3589   fprintf (stream, _("\
   3590   -EB                     assemble code for a big-endian cpu\n"));
   3591   fprintf (stream, _("\
   3592   -EL                     assemble code for a little-endian cpu\n"));
   3593   fprintf (stream, _("\
   3594   -mrelax                 enable relaxation\n"));
   3595 
   3596   fprintf (stream, _("The following ARC-specific assembler options are "
   3597                      "deprecated and are accepted\nfor compatibility only:\n"));
   3598 
   3599   fprintf (stream, _("  -mEA\n"
   3600                      "  -mbarrel-shifter\n"
   3601                      "  -mbarrel_shifter\n"
   3602                      "  -mcrc\n"
   3603                      "  -mdsp-packa\n"
   3604                      "  -mdsp_packa\n"
   3605                      "  -mdvbf\n"
   3606                      "  -mld-extension-reg-mask\n"
   3607                      "  -mlock\n"
   3608                      "  -mmac-24\n"
   3609                      "  -mmac-d16\n"
   3610                      "  -mmac_24\n"
   3611                      "  -mmac_d16\n"
   3612                      "  -mmin-max\n"
   3613                      "  -mmin_max\n"
   3614                      "  -mmul64\n"
   3615                      "  -mno-mpy\n"
   3616                      "  -mnorm\n"
   3617                      "  -mrtsc\n"
   3618                      "  -msimd\n"
   3619                      "  -mswap\n"
   3620                      "  -mswape\n"
   3621                      "  -mtelephony\n"
   3622 		     "  -muser-mode-only\n"
   3623                      "  -mxy\n"));
   3624 }
   3625 
   3626 /* Find the proper relocation for the given opcode.  */
   3627 
   3628 static extended_bfd_reloc_code_real_type
   3629 find_reloc (const char *name,
   3630 	    const char *opcodename,
   3631 	    const struct arc_flags *pflags,
   3632 	    int nflg,
   3633 	    extended_bfd_reloc_code_real_type reloc)
   3634 {
   3635   unsigned int i;
   3636   int j;
   3637   bool found_flag, tmp;
   3638   extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
   3639 
   3640   for (i = 0; i < arc_num_equiv_tab; i++)
   3641     {
   3642       const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
   3643 
   3644       /* Find the entry.  */
   3645       if (strcmp (name, r->name))
   3646 	continue;
   3647       if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
   3648 	continue;
   3649       if (r->flags[0])
   3650 	{
   3651 	  if (!nflg)
   3652 	    continue;
   3653 	  found_flag = false;
   3654 	  const unsigned *psflg = r->flags;
   3655 	  do
   3656 	    {
   3657 	      tmp = false;
   3658 	      for (j = 0; j < nflg; j++)
   3659 		if (!strcmp (pflags[j].name,
   3660 			     arc_flag_operands[*psflg].name))
   3661 		  {
   3662 		    tmp = true;
   3663 		    break;
   3664 		  }
   3665 	      if (!tmp)
   3666 		{
   3667 		  found_flag = false;
   3668 		  break;
   3669 		}
   3670 	      else
   3671 		{
   3672 		  found_flag = true;
   3673 		}
   3674 	      ++ psflg;
   3675 	    } while (*psflg);
   3676 
   3677 	  if (!found_flag)
   3678 	    continue;
   3679 	}
   3680 
   3681       if (reloc != r->oldreloc)
   3682 	continue;
   3683       /* Found it.  */
   3684       ret = r->newreloc;
   3685       break;
   3686     }
   3687 
   3688   if (ret == BFD_RELOC_UNUSED)
   3689     as_bad (_("Unable to find %s relocation for instruction %s"),
   3690 	    name, opcodename);
   3691   return ret;
   3692 }
   3693 
   3694 /* All the symbol types that are allowed to be used for
   3695    relaxation.  */
   3696 
   3697 static bool
   3698 may_relax_expr (expressionS tok)
   3699 {
   3700   /* Check if we have unrelaxable relocs.  */
   3701   switch (tok.X_md)
   3702     {
   3703     default:
   3704       break;
   3705     case O_plt:
   3706       return false;
   3707     }
   3708 
   3709   switch (tok.X_op)
   3710     {
   3711     case O_symbol:
   3712     case O_multiply:
   3713     case O_divide:
   3714     case O_modulus:
   3715     case O_add:
   3716     case O_subtract:
   3717       break;
   3718 
   3719     default:
   3720       return false;
   3721     }
   3722   return true;
   3723 }
   3724 
   3725 /* Checks if flags are in line with relaxable insn.  */
   3726 
   3727 static bool
   3728 relaxable_flag (const struct arc_relaxable_ins *ins,
   3729 		const struct arc_flags *pflags,
   3730 		int nflgs)
   3731 {
   3732   unsigned flag_class,
   3733     flag,
   3734     flag_class_idx = 0,
   3735     flag_idx = 0;
   3736 
   3737   const struct arc_flag_operand *flag_opand;
   3738   int i, counttrue = 0;
   3739 
   3740   /* Iterate through flags classes.  */
   3741   while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
   3742     {
   3743       /* Iterate through flags in flag class.  */
   3744       while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
   3745 	     != 0)
   3746 	{
   3747 	  flag_opand = &arc_flag_operands[flag];
   3748 	  /* Iterate through flags in ins to compare.  */
   3749 	  for (i = 0; i < nflgs; ++i)
   3750 	    {
   3751 	      if (strcmp (flag_opand->name, pflags[i].name) == 0)
   3752 		++counttrue;
   3753 	    }
   3754 
   3755 	  ++flag_idx;
   3756 	}
   3757 
   3758       ++flag_class_idx;
   3759       flag_idx = 0;
   3760     }
   3761 
   3762   /* If counttrue == nflgs, then all flags have been found.  */
   3763   return counttrue == nflgs;
   3764 }
   3765 
   3766 /* Checks if operands are in line with relaxable insn.  */
   3767 
   3768 static bool
   3769 relaxable_operand (const struct arc_relaxable_ins *ins,
   3770 		   const expressionS *tok,
   3771 		   int ntok)
   3772 {
   3773   const enum rlx_operand_type *operand = &ins->operands[0];
   3774   int i = 0;
   3775 
   3776   while (*operand != EMPTY)
   3777     {
   3778       const expressionS *epr = &tok[i];
   3779 
   3780       if (i != 0 && i >= ntok)
   3781 	return false;
   3782 
   3783       switch (*operand)
   3784 	{
   3785 	case IMMEDIATE:
   3786 	  if (!(epr->X_op == O_multiply
   3787 		|| epr->X_op == O_divide
   3788 		|| epr->X_op == O_modulus
   3789 		|| epr->X_op == O_add
   3790 		|| epr->X_op == O_subtract
   3791 		|| epr->X_op == O_symbol))
   3792 	    return false;
   3793 	  break;
   3794 
   3795 	case REGISTER_DUP:
   3796 	  if ((i <= 0)
   3797 	      || (epr->X_add_number != tok[i - 1].X_add_number))
   3798 	    return false;
   3799 	  /* Fall through.  */
   3800 	case REGISTER:
   3801 	  if (epr->X_op != O_register)
   3802 	    return false;
   3803 	  break;
   3804 
   3805 	case REGISTER_S:
   3806 	  if (epr->X_op != O_register)
   3807 	    return false;
   3808 
   3809 	  switch (epr->X_add_number)
   3810 	    {
   3811 	    case 0: case 1: case 2: case 3:
   3812 	    case 12: case 13: case 14: case 15:
   3813 	      break;
   3814 	    default:
   3815 	      return false;
   3816 	    }
   3817 	  break;
   3818 
   3819 	case REGISTER_NO_GP:
   3820 	  if ((epr->X_op != O_register)
   3821 	      || (epr->X_add_number == 26)) /* 26 is the gp register.  */
   3822 	    return false;
   3823 	  break;
   3824 
   3825 	case BRACKET:
   3826 	  if (epr->X_op != O_bracket)
   3827 	    return false;
   3828 	  break;
   3829 
   3830 	default:
   3831 	  /* Don't understand, bail out.  */
   3832 	  return false;
   3833 	  break;
   3834 	}
   3835 
   3836       ++i;
   3837       operand = &ins->operands[i];
   3838     }
   3839 
   3840   return i == ntok;
   3841 }
   3842 
   3843 /* Return TRUE if this OPDCODE is a candidate for relaxation.  */
   3844 
   3845 static bool
   3846 relax_insn_p (const struct arc_opcode *opcode,
   3847 	      const expressionS *tok,
   3848 	      int ntok,
   3849 	      const struct arc_flags *pflags,
   3850 	      int nflg)
   3851 {
   3852   unsigned i;
   3853   bool rv = false;
   3854 
   3855   /* Check the relaxation table.  */
   3856   for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
   3857     {
   3858       const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
   3859 
   3860       if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
   3861 	  && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
   3862 	  && relaxable_operand (arc_rlx_ins, tok, ntok)
   3863 	  && relaxable_flag (arc_rlx_ins, pflags, nflg))
   3864 	{
   3865 	  rv = true;
   3866 	  frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
   3867 	  memcpy (&frag_now->tc_frag_data.tok, tok,
   3868 		sizeof (expressionS) * ntok);
   3869 	  memcpy (&frag_now->tc_frag_data.pflags, pflags,
   3870 		sizeof (struct arc_flags) * nflg);
   3871 	  frag_now->tc_frag_data.nflg = nflg;
   3872 	  frag_now->tc_frag_data.ntok = ntok;
   3873 	  break;
   3874 	}
   3875     }
   3876 
   3877   return rv;
   3878 }
   3879 
   3880 /* Turn an opcode description and a set of arguments into
   3881    an instruction and a fixup.  */
   3882 
   3883 static void
   3884 assemble_insn (const struct arc_opcode *opcode,
   3885 	       const expressionS *tok,
   3886 	       int ntok,
   3887 	       const struct arc_flags *pflags,
   3888 	       int nflg,
   3889 	       struct arc_insn *insn)
   3890 {
   3891   const expressionS *reloc_exp = NULL;
   3892   unsigned long long image;
   3893   const unsigned char *argidx;
   3894   int i;
   3895   int tokidx = 0;
   3896   unsigned char pcrel = 0;
   3897   bool needGOTSymbol;
   3898   bool has_delay_slot = false;
   3899   extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
   3900 
   3901   memset (insn, 0, sizeof (*insn));
   3902   image = opcode->opcode;
   3903 
   3904   pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
   3905 	    frag_now->fr_file, frag_now->fr_line, opcode->name,
   3906 	    opcode->opcode);
   3907 
   3908   /* Handle operands.  */
   3909   for (argidx = opcode->operands; *argidx; ++argidx)
   3910     {
   3911       const struct arc_operand *operand = &arc_operands[*argidx];
   3912       const expressionS *t = NULL;
   3913 
   3914       if (ARC_OPERAND_IS_FAKE (operand))
   3915 	continue;
   3916 
   3917       if (operand->flags & ARC_OPERAND_DUPLICATE)
   3918 	{
   3919 	  /* Duplicate operand, already inserted.  */
   3920 	  tokidx ++;
   3921 	  continue;
   3922 	}
   3923 
   3924       if (tokidx >= ntok)
   3925 	{
   3926 	  abort ();
   3927 	}
   3928       else
   3929 	t = &tok[tokidx++];
   3930 
   3931       /* Regardless if we have a reloc or not mark the instruction
   3932 	 limm if it is the case.  */
   3933       if (operand->flags & ARC_OPERAND_LIMM)
   3934 	insn->has_limm = true;
   3935 
   3936       switch (t->X_op)
   3937 	{
   3938 	case O_register:
   3939 	  image = insert_operand (image, operand, regno (t->X_add_number),
   3940 				  NULL, 0);
   3941 	  break;
   3942 
   3943 	case O_constant:
   3944 	  image = insert_operand (image, operand, t->X_add_number, NULL, 0);
   3945 	  reloc_exp = t;
   3946 	  if (operand->flags & ARC_OPERAND_LIMM)
   3947 	    insn->limm = t->X_add_number;
   3948 	  break;
   3949 
   3950 	case O_bracket:
   3951         case O_colon:
   3952         case O_addrtype:
   3953 	  /* Ignore brackets, colons, and address types.  */
   3954 	  break;
   3955 
   3956 	case O_absent:
   3957 	  gas_assert (operand->flags & ARC_OPERAND_IGNORE);
   3958 	  break;
   3959 
   3960 	case O_subtract:
   3961 	  /* Maybe register range.  */
   3962 	  if ((t->X_add_number == 0)
   3963 	      && contains_register (t->X_add_symbol)
   3964 	      && contains_register (t->X_op_symbol))
   3965 	    {
   3966 	      int regs;
   3967 
   3968 	      regs = get_register (t->X_add_symbol);
   3969 	      regs <<= 16;
   3970 	      regs |= get_register (t->X_op_symbol);
   3971 	      image = insert_operand (image, operand, regs, NULL, 0);
   3972 	      break;
   3973 	    }
   3974 	  /* Fall through.  */
   3975 
   3976 	default:
   3977 	  /* This operand needs a relocation.  */
   3978 	  needGOTSymbol = false;
   3979 
   3980 	  switch (t->X_md)
   3981 	    {
   3982 	    case O_plt:
   3983 	      if (opcode->insn_class == JUMP)
   3984 		as_bad (_("Unable to use @plt relocation for insn %s"),
   3985 			opcode->name);
   3986 	      needGOTSymbol = true;
   3987 	      reloc = find_reloc ("plt", opcode->name,
   3988 				  pflags, nflg,
   3989 				  operand->default_reloc);
   3990 	      break;
   3991 
   3992 	    case O_gotoff:
   3993 	    case O_gotpc:
   3994 	      needGOTSymbol = true;
   3995 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   3996 	      break;
   3997 	    case O_pcl:
   3998 	      if (operand->flags & ARC_OPERAND_LIMM)
   3999 		{
   4000 		  reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   4001 		  if (arc_opcode_len (opcode) == 2
   4002 		      || opcode->insn_class == JUMP)
   4003 		    as_bad (_("Unable to use @pcl relocation for insn %s"),
   4004 			    opcode->name);
   4005 		}
   4006 	      else
   4007 		{
   4008 		  /* This is a relaxed operand which initially was
   4009 		     limm, choose whatever we have defined in the
   4010 		     opcode as reloc.  */
   4011 		  reloc = operand->default_reloc;
   4012 		}
   4013 	      break;
   4014 	    case O_sda:
   4015 	      reloc = find_reloc ("sda", opcode->name,
   4016 				  pflags, nflg,
   4017 				  operand->default_reloc);
   4018 	      break;
   4019 	    case O_tlsgd:
   4020 	    case O_tlsie:
   4021 	      needGOTSymbol = true;
   4022 	      /* Fall-through.  */
   4023 
   4024 	    case O_tpoff:
   4025 	    case O_dtpoff:
   4026 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   4027 	      break;
   4028 
   4029 	    case O_tpoff9: /*FIXME! Check for the conditionality of
   4030 			     the insn.  */
   4031 	    case O_dtpoff9: /*FIXME! Check for the conditionality of
   4032 			      the insn.  */
   4033 	      as_bad (_("TLS_*_S9 relocs are not supported yet"));
   4034 	      break;
   4035 
   4036 	    default:
   4037 	      /* Just consider the default relocation.  */
   4038 	      reloc = operand->default_reloc;
   4039 	      break;
   4040 	    }
   4041 
   4042 	  if (needGOTSymbol && (GOT_symbol == NULL))
   4043 	    GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
   4044 
   4045 	  reloc_exp = t;
   4046 
   4047 #if 0
   4048 	  if (reloc > 0)
   4049 	    {
   4050 	      /* sanity checks.  */
   4051 	      reloc_howto_type *reloc_howto
   4052 		= bfd_reloc_type_lookup (stdoutput, reloc);
   4053 	      unsigned reloc_bitsize = reloc_howto->bitsize;
   4054 	      if (reloc_howto->rightshift)
   4055 		reloc_bitsize -= reloc_howto->rightshift;
   4056 	      if (reloc_bitsize != operand->bits)
   4057 		{
   4058 		  as_bad (_("invalid relocation %s for field"),
   4059 			  bfd_get_reloc_code_name (reloc));
   4060 		  return;
   4061 		}
   4062 	    }
   4063 #endif
   4064 	  if (insn->nfixups >= MAX_INSN_FIXUPS)
   4065 	    as_fatal (_("too many fixups"));
   4066 
   4067 	  struct arc_fixup *fixup;
   4068 	  fixup = &insn->fixups[insn->nfixups++];
   4069 	  fixup->exp = *t;
   4070 	  fixup->reloc = reloc;
   4071 	  if ((int) reloc < 0)
   4072 	    pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
   4073 	  else
   4074 	    {
   4075 	      reloc_howto_type *reloc_howto =
   4076 		bfd_reloc_type_lookup (stdoutput, fixup->reloc);
   4077 	      pcrel = reloc_howto->pc_relative;
   4078 	    }
   4079 	  fixup->pcrel = pcrel;
   4080 	  fixup->islong = (operand->flags & ARC_OPERAND_LIMM) != 0;
   4081 	  break;
   4082 	}
   4083     }
   4084 
   4085   /* Handle flags.  */
   4086   for (i = 0; i < nflg; i++)
   4087     {
   4088       const struct arc_flag_operand *flg_operand = pflags[i].flgp;
   4089 
   4090       /* Check if the instruction has a delay slot.  */
   4091       if (!strcmp (flg_operand->name, "d"))
   4092 	has_delay_slot = true;
   4093 
   4094       /* There is an exceptional case when we cannot insert a flag just as
   4095 	 it is.  On ARCv2 the '.t' and '.nt' flags must be handled in
   4096 	 relation with the relative address.  Unfortunately, some of the
   4097 	 ARC700 extensions (NPS400) also have a '.nt' flag that should be
   4098 	 handled in the normal way.
   4099 
   4100 	 Flag operands don't have an architecture field, so we can't
   4101 	 directly validate that FLAG_OPERAND is valid for the current
   4102 	 architecture, what we do instead is just validate that we're
   4103 	 assembling for an ARCv2 architecture.  */
   4104       if ((selected_cpu.flags & ARC_OPCODE_ARCV2)
   4105 	  && (!strcmp (flg_operand->name, "t")
   4106 	      || !strcmp (flg_operand->name, "nt")))
   4107 	{
   4108 	  unsigned bitYoperand = 0;
   4109 	  /* FIXME! move selection bbit/brcc in arc-opc.c.  */
   4110 	  if (!strcmp (flg_operand->name, "t"))
   4111 	    if (!strcmp (opcode->name, "bbit0")
   4112 		|| !strcmp (opcode->name, "bbit1"))
   4113 	      bitYoperand = arc_NToperand;
   4114 	    else
   4115 	      bitYoperand = arc_Toperand;
   4116 	  else
   4117 	    if (!strcmp (opcode->name, "bbit0")
   4118 		|| !strcmp (opcode->name, "bbit1"))
   4119 	      bitYoperand = arc_Toperand;
   4120 	    else
   4121 	      bitYoperand = arc_NToperand;
   4122 
   4123 	  gas_assert (reloc_exp != NULL);
   4124 	  if (reloc_exp->X_op == O_constant)
   4125 	    {
   4126 	      /* Check if we have a constant and solved it
   4127 		 immediately.  */
   4128 	      offsetT val = reloc_exp->X_add_number;
   4129 	      image |= insert_operand (image, &arc_operands[bitYoperand],
   4130 				       val, NULL, 0);
   4131 	    }
   4132 	  else
   4133 	    {
   4134 	      struct arc_fixup *fixup;
   4135 
   4136 	      if (insn->nfixups >= MAX_INSN_FIXUPS)
   4137 		as_fatal (_("too many fixups"));
   4138 
   4139 	      fixup = &insn->fixups[insn->nfixups++];
   4140 	      fixup->exp = *reloc_exp;
   4141 	      fixup->reloc = -bitYoperand;
   4142 	      fixup->pcrel = pcrel;
   4143 	      fixup->islong = false;
   4144 	    }
   4145 	}
   4146       else
   4147 	image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
   4148 	  << flg_operand->shift;
   4149     }
   4150 
   4151   insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
   4152 
   4153   /* Instruction length.  */
   4154   insn->len = arc_opcode_len (opcode);
   4155 
   4156   insn->insn = image;
   4157 
   4158   /* Update last insn status.  */
   4159   arc_last_insns[1]		   = arc_last_insns[0];
   4160   arc_last_insns[0].opcode	   = opcode;
   4161   arc_last_insns[0].has_limm	   = insn->has_limm;
   4162   arc_last_insns[0].has_delay_slot = has_delay_slot;
   4163 
   4164   /* Check if the current instruction is legally used.  */
   4165   if (arc_last_insns[1].has_delay_slot
   4166       && is_br_jmp_insn_p (arc_last_insns[0].opcode))
   4167     as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."),
   4168 	    arc_last_insns[1].opcode->name,
   4169 	    arc_last_insns[0].opcode->name);
   4170   if (arc_last_insns[1].has_delay_slot
   4171       && arc_last_insns[0].has_limm)
   4172     as_bad (_("Insn %s has an instruction %s with limm in its delay slot."),
   4173 	    arc_last_insns[1].opcode->name,
   4174 	    arc_last_insns[0].opcode->name);
   4175 }
   4176 
   4177 void
   4178 arc_handle_align (fragS* fragP)
   4179 {
   4180   if ((fragP)->fr_type == rs_align_code)
   4181     {
   4182       char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
   4183       valueT count = ((fragP)->fr_next->fr_address
   4184 		      - (fragP)->fr_address - (fragP)->fr_fix);
   4185 
   4186       (fragP)->fr_var = 2;
   4187 
   4188       if (count & 1)/* Padding in the gap till the next 2-byte
   4189 		       boundary with 0s.  */
   4190 	{
   4191 	  (fragP)->fr_fix++;
   4192 	  *dest++ = 0;
   4193 	}
   4194       /* Writing nop_s.  */
   4195       md_number_to_chars (dest, NOP_OPCODE_S, 2);
   4196     }
   4197 }
   4198 
   4199 /* Here we decide which fixups can be adjusted to make them relative
   4200    to the beginning of the section instead of the symbol.  Basically
   4201    we need to make sure that the dynamic relocations are done
   4202    correctly, so in some cases we force the original symbol to be
   4203    used.  */
   4204 
   4205 int
   4206 tc_arc_fix_adjustable (fixS *fixP)
   4207 {
   4208 
   4209   /* Prevent all adjustments to global symbols.  */
   4210   if (S_IS_EXTERNAL (fixP->fx_addsy))
   4211     return 0;
   4212   if (S_IS_WEAK (fixP->fx_addsy))
   4213     return 0;
   4214 
   4215   /* Adjust_reloc_syms doesn't know about the GOT.  */
   4216   switch (fixP->fx_r_type)
   4217     {
   4218     case BFD_RELOC_ARC_GOTPC32:
   4219     case BFD_RELOC_32_PLT_PCREL:
   4220     case BFD_RELOC_ARC_S25H_PCREL_PLT:
   4221     case BFD_RELOC_ARC_S21H_PCREL_PLT:
   4222     case BFD_RELOC_ARC_S25W_PCREL_PLT:
   4223     case BFD_RELOC_ARC_S21W_PCREL_PLT:
   4224       return 0;
   4225 
   4226     default:
   4227       break;
   4228     }
   4229 
   4230   return 1;
   4231 }
   4232 
   4233 /* Compute the reloc type of an expression EXP.  */
   4234 
   4235 static void
   4236 arc_check_reloc (expressionS *exp,
   4237 		 bfd_reloc_code_real_type *r_type_p)
   4238 {
   4239   if (*r_type_p == BFD_RELOC_32
   4240       && exp->X_op == O_subtract
   4241       && exp->X_op_symbol != NULL
   4242       && S_GET_SEGMENT (exp->X_op_symbol) == now_seg)
   4243     *r_type_p = BFD_RELOC_ARC_32_PCREL;
   4244 }
   4245 
   4246 
   4247 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG.  */
   4248 
   4249 void
   4250 arc_cons_fix_new (fragS *frag,
   4251 		  int off,
   4252 		  int size,
   4253 		  expressionS *exp,
   4254 		  bfd_reloc_code_real_type r_type)
   4255 {
   4256   r_type = BFD_RELOC_UNUSED;
   4257 
   4258   switch (size)
   4259     {
   4260     case 1:
   4261       r_type = BFD_RELOC_8;
   4262       break;
   4263 
   4264     case 2:
   4265       r_type = BFD_RELOC_16;
   4266       break;
   4267 
   4268     case 3:
   4269       r_type = BFD_RELOC_24;
   4270       break;
   4271 
   4272     case 4:
   4273       r_type = BFD_RELOC_32;
   4274       arc_check_reloc (exp, &r_type);
   4275       break;
   4276 
   4277     case 8:
   4278       r_type = BFD_RELOC_64;
   4279       break;
   4280 
   4281     default:
   4282       as_bad (_("unsupported BFD relocation size %u"), size);
   4283       r_type = BFD_RELOC_UNUSED;
   4284     }
   4285 
   4286   fix_new_exp (frag, off, size, exp, 0, r_type);
   4287 }
   4288 
   4289 /* The actual routine that checks the ZOL conditions.  */
   4290 
   4291 static void
   4292 check_zol (symbolS *s)
   4293 {
   4294   switch (selected_cpu.mach)
   4295     {
   4296     case bfd_mach_arc_arcv2:
   4297       if (selected_cpu.flags & ARC_OPCODE_ARCv2EM)
   4298 	return;
   4299 
   4300       if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
   4301 	  || arc_last_insns[1].has_delay_slot)
   4302 	as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
   4303 		S_GET_NAME (s));
   4304 
   4305       break;
   4306     case bfd_mach_arc_arc600:
   4307 
   4308       if (is_kernel_insn_p (arc_last_insns[0].opcode))
   4309 	as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
   4310 		S_GET_NAME (s));
   4311 
   4312       if (arc_last_insns[0].has_limm
   4313 	  && is_br_jmp_insn_p (arc_last_insns[0].opcode))
   4314 	as_bad (_("A jump instruction with long immediate detected at the \
   4315 end of the ZOL label @%s"), S_GET_NAME (s));
   4316 
   4317       /* Fall through.  */
   4318     case bfd_mach_arc_arc700:
   4319       if (arc_last_insns[0].has_delay_slot)
   4320 	as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
   4321 		S_GET_NAME (s));
   4322 
   4323       break;
   4324     default:
   4325       break;
   4326     }
   4327 }
   4328 
   4329 /* If ZOL end check the last two instruction for illegals.  */
   4330 void
   4331 arc_frob_label (symbolS * sym)
   4332 {
   4333   if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
   4334     check_zol (sym);
   4335 
   4336   dwarf2_emit_label (sym);
   4337 }
   4338 
   4339 /* Used because generic relaxation assumes a pc-rel value whilst we
   4340    also relax instructions that use an absolute value resolved out of
   4341    relative values (if that makes any sense).  An example: 'add r1,
   4342    r2, @.L2 - .'  The symbols . and @.L2 are relative to the section
   4343    but if they're in the same section we can subtract the section
   4344    offset relocation which ends up in a resolved value.  So if @.L2 is
   4345    .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
   4346    .text + 0x40 = 0x10.  */
   4347 int
   4348 arc_pcrel_adjust (fragS *fragP)
   4349 {
   4350   pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
   4351 	    fragP->fr_address, fragP->fr_fix,
   4352 	    fragP->tc_frag_data.pcrel ? "Y" : "N");
   4353 
   4354   if (!fragP->tc_frag_data.pcrel)
   4355     return fragP->fr_address + fragP->fr_fix;
   4356 
   4357   /* Take into account the PCL rounding.  */
   4358   return (fragP->fr_address + fragP->fr_fix) & 0x03;
   4359 }
   4360 
   4361 /* Initialize the DWARF-2 unwind information for this procedure.  */
   4362 
   4363 void
   4364 tc_arc_frame_initial_instructions (void)
   4365 {
   4366   /* Stack pointer is register 28.  */
   4367   cfi_add_CFA_def_cfa (28, 0);
   4368 }
   4369 
   4370 int
   4371 tc_arc_regname_to_dw2regnum (char *regname)
   4372 {
   4373   struct symbol *sym;
   4374 
   4375   sym = str_hash_find (arc_reg_hash, regname);
   4376   if (sym)
   4377     return S_GET_VALUE (sym);
   4378 
   4379   return -1;
   4380 }
   4381 
   4382 /* Adjust the symbol table.  Delete found AUX register symbols.  */
   4383 
   4384 void
   4385 arc_adjust_symtab (void)
   4386 {
   4387   symbolS * sym;
   4388 
   4389   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
   4390     {
   4391       /* I've created a symbol during parsing process.  Now, remove
   4392 	 the symbol as it is found to be an AUX register.  */
   4393       if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX)
   4394 	symbol_remove (sym, &symbol_rootP, &symbol_lastP);
   4395     }
   4396 
   4397   /* Now do generic ELF adjustments.  */
   4398   elf_adjust_symtab ();
   4399 }
   4400 
   4401 static void
   4402 tokenize_extinsn (extInstruction_t *einsn)
   4403 {
   4404   char *p, c;
   4405   char *insn_name;
   4406   unsigned char major_opcode;
   4407   unsigned char sub_opcode;
   4408   unsigned char syntax_class = 0;
   4409   unsigned char syntax_class_modifiers = 0;
   4410   unsigned char suffix_class = 0;
   4411   unsigned int i;
   4412 
   4413   SKIP_WHITESPACE ();
   4414 
   4415   /* 1st: get instruction name.  */
   4416   p = input_line_pointer;
   4417   c = get_symbol_name (&p);
   4418 
   4419   insn_name = xstrdup (p);
   4420   restore_line_pointer (c);
   4421 
   4422   /* Convert to lower case.  */
   4423   for (p = insn_name; *p; ++p)
   4424     *p = TOLOWER (*p);
   4425 
   4426   /* 2nd: get major opcode.  */
   4427   if (*input_line_pointer != ',')
   4428     {
   4429       as_bad (_("expected comma after instruction name"));
   4430       ignore_rest_of_line ();
   4431       return;
   4432     }
   4433   input_line_pointer++;
   4434   major_opcode = get_absolute_expression ();
   4435 
   4436   /* 3rd: get sub-opcode.  */
   4437   SKIP_WHITESPACE ();
   4438 
   4439   if (*input_line_pointer != ',')
   4440     {
   4441       as_bad (_("expected comma after major opcode"));
   4442       ignore_rest_of_line ();
   4443       return;
   4444     }
   4445   input_line_pointer++;
   4446   sub_opcode = get_absolute_expression ();
   4447 
   4448   /* 4th: get suffix class.  */
   4449   SKIP_WHITESPACE ();
   4450 
   4451   if (*input_line_pointer != ',')
   4452     {
   4453       as_bad ("expected comma after sub opcode");
   4454       ignore_rest_of_line ();
   4455       return;
   4456     }
   4457   input_line_pointer++;
   4458 
   4459   while (1)
   4460     {
   4461       SKIP_WHITESPACE ();
   4462 
   4463       for (i = 0; i < ARRAY_SIZE (suffixclass); i++)
   4464 	{
   4465 	  if (!strncmp (suffixclass[i].name, input_line_pointer,
   4466 			suffixclass[i].len))
   4467 	    {
   4468 	      suffix_class |= suffixclass[i].attr_class;
   4469 	      input_line_pointer += suffixclass[i].len;
   4470 	      break;
   4471 	    }
   4472 	}
   4473 
   4474       if (i == ARRAY_SIZE (suffixclass))
   4475 	{
   4476 	  as_bad ("invalid suffix class");
   4477 	  ignore_rest_of_line ();
   4478 	  return;
   4479 	}
   4480 
   4481       SKIP_WHITESPACE ();
   4482 
   4483       if (*input_line_pointer == '|')
   4484 	input_line_pointer++;
   4485       else
   4486 	break;
   4487     }
   4488 
   4489   /* 5th: get syntax class and syntax class modifiers.  */
   4490   if (*input_line_pointer != ',')
   4491     {
   4492       as_bad ("expected comma after suffix class");
   4493       ignore_rest_of_line ();
   4494       return;
   4495     }
   4496   input_line_pointer++;
   4497 
   4498   while (1)
   4499     {
   4500       SKIP_WHITESPACE ();
   4501 
   4502       for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++)
   4503 	{
   4504 	  if (!strncmp (syntaxclassmod[i].name,
   4505 			input_line_pointer,
   4506 			syntaxclassmod[i].len))
   4507 	    {
   4508 	      syntax_class_modifiers |= syntaxclassmod[i].attr_class;
   4509 	      input_line_pointer += syntaxclassmod[i].len;
   4510 	      break;
   4511 	    }
   4512 	}
   4513 
   4514       if (i == ARRAY_SIZE (syntaxclassmod))
   4515 	{
   4516 	  for (i = 0; i < ARRAY_SIZE (syntaxclass); i++)
   4517 	    {
   4518 	      if (!strncmp (syntaxclass[i].name,
   4519 			    input_line_pointer,
   4520 			    syntaxclass[i].len))
   4521 		{
   4522 		  syntax_class |= syntaxclass[i].attr_class;
   4523 		  input_line_pointer += syntaxclass[i].len;
   4524 		  break;
   4525 		}
   4526 	    }
   4527 
   4528 	  if (i == ARRAY_SIZE (syntaxclass))
   4529 	    {
   4530 	      as_bad ("missing syntax class");
   4531 	      ignore_rest_of_line ();
   4532 	      return;
   4533 	    }
   4534 	}
   4535 
   4536       SKIP_WHITESPACE ();
   4537 
   4538       if (*input_line_pointer == '|')
   4539 	input_line_pointer++;
   4540       else
   4541 	break;
   4542     }
   4543 
   4544   demand_empty_rest_of_line ();
   4545 
   4546   einsn->name   = insn_name;
   4547   einsn->major  = major_opcode;
   4548   einsn->minor  = sub_opcode;
   4549   einsn->syntax = syntax_class;
   4550   einsn->modsyn = syntax_class_modifiers;
   4551   einsn->suffix = suffix_class;
   4552   einsn->flags  = syntax_class
   4553     | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0);
   4554 }
   4555 
   4556 /* Generate an extension section.  */
   4557 
   4558 static int
   4559 arc_set_ext_seg (void)
   4560 {
   4561   if (!arcext_section)
   4562     {
   4563       arcext_section = subseg_new (".arcextmap", 0);
   4564       bfd_set_section_flags (arcext_section, SEC_READONLY | SEC_HAS_CONTENTS);
   4565     }
   4566   else
   4567     subseg_set (arcext_section, 0);
   4568   return 1;
   4569 }
   4570 
   4571 /* Create an extension instruction description in the arc extension
   4572    section of the output file.
   4573    The structure for an instruction is like this:
   4574    [0]: Length of the record.
   4575    [1]: Type of the record.
   4576 
   4577    [2]: Major opcode.
   4578    [3]: Sub-opcode.
   4579    [4]: Syntax (flags).
   4580    [5]+ Name instruction.
   4581 
   4582    The sequence is terminated by an empty entry.  */
   4583 
   4584 static void
   4585 create_extinst_section (extInstruction_t *einsn)
   4586 {
   4587 
   4588   segT old_sec    = now_seg;
   4589   int old_subsec  = now_subseg;
   4590   char *p;
   4591   int name_len    = strlen (einsn->name);
   4592 
   4593   arc_set_ext_seg ();
   4594 
   4595   p = frag_more (1);
   4596   *p = 5 + name_len + 1;
   4597   p = frag_more (1);
   4598   *p = EXT_INSTRUCTION;
   4599   p = frag_more (1);
   4600   *p = einsn->major;
   4601   p = frag_more (1);
   4602   *p = einsn->minor;
   4603   p = frag_more (1);
   4604   *p = einsn->flags;
   4605   p = frag_more (name_len + 1);
   4606   strcpy (p, einsn->name);
   4607 
   4608   subseg_set (old_sec, old_subsec);
   4609 }
   4610 
   4611 /* Handler .extinstruction pseudo-op.  */
   4612 
   4613 static void
   4614 arc_extinsn (int ignore ATTRIBUTE_UNUSED)
   4615 {
   4616   extInstruction_t einsn;
   4617   struct arc_opcode *arc_ext_opcodes;
   4618   const char *errmsg = NULL;
   4619   unsigned char moplow, mophigh;
   4620 
   4621   memset (&einsn, 0, sizeof (einsn));
   4622   tokenize_extinsn (&einsn);
   4623 
   4624   /* Check if the name is already used.  */
   4625   if (arc_find_opcode (einsn.name))
   4626     as_warn (_("Pseudocode already used %s"), einsn.name);
   4627 
   4628   /* Check the opcode ranges.  */
   4629   moplow = 0x05;
   4630   mophigh = (selected_cpu.flags & (ARC_OPCODE_ARCv2EM
   4631                                    | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a;
   4632 
   4633   if ((einsn.major > mophigh) || (einsn.major < moplow))
   4634     as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh);
   4635 
   4636   if ((einsn.minor > 0x3f) && (einsn.major != 0x0a)
   4637       && (einsn.major != 5) && (einsn.major != 9))
   4638     as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
   4639 
   4640   switch (einsn.syntax & ARC_SYNTAX_MASK)
   4641     {
   4642     case ARC_SYNTAX_3OP:
   4643       if (einsn.modsyn & ARC_OP1_IMM_IMPLIED)
   4644 	as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
   4645       break;
   4646     case ARC_SYNTAX_2OP:
   4647     case ARC_SYNTAX_1OP:
   4648     case ARC_SYNTAX_NOP:
   4649       if (einsn.modsyn & ARC_OP1_MUST_BE_IMM)
   4650 	as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
   4651       break;
   4652     default:
   4653       break;
   4654     }
   4655 
   4656   arc_ext_opcodes = arcExtMap_genOpcode (&einsn, selected_cpu.flags, &errmsg);
   4657   if (arc_ext_opcodes == NULL)
   4658     {
   4659       if (errmsg)
   4660 	as_fatal ("%s", errmsg);
   4661       else
   4662 	as_fatal (_("Couldn't generate extension instruction opcodes"));
   4663     }
   4664   else if (errmsg)
   4665     as_warn ("%s", errmsg);
   4666 
   4667   /* Insert the extension instruction.  */
   4668   arc_insert_opcode (arc_ext_opcodes);
   4669 
   4670   create_extinst_section (&einsn);
   4671 }
   4672 
   4673 static bool
   4674 tokenize_extregister (extRegister_t *ereg, int opertype)
   4675 {
   4676   char *name;
   4677   char *mode;
   4678   char c;
   4679   char *p;
   4680   int number, imode = 0;
   4681   bool isCore_p = opertype == EXT_CORE_REGISTER;
   4682   bool isReg_p = opertype == EXT_CORE_REGISTER || opertype == EXT_AUX_REGISTER;
   4683 
   4684   /* 1st: get register name.  */
   4685   SKIP_WHITESPACE ();
   4686   p = input_line_pointer;
   4687   c = get_symbol_name (&p);
   4688 
   4689   name = xstrdup (p);
   4690   restore_line_pointer (c);
   4691 
   4692   /* 2nd: get register number.  */
   4693   SKIP_WHITESPACE ();
   4694 
   4695   if (*input_line_pointer != ',')
   4696     {
   4697       as_bad (_("expected comma after name"));
   4698       ignore_rest_of_line ();
   4699       free (name);
   4700       return false;
   4701     }
   4702   input_line_pointer++;
   4703   number = get_absolute_expression ();
   4704 
   4705   if ((number < 0)
   4706       && (opertype != EXT_AUX_REGISTER))
   4707     {
   4708       as_bad (_("%s second argument cannot be a negative number %d"),
   4709 	      isCore_p ? "extCoreRegister's" : "extCondCode's",
   4710 	      number);
   4711       ignore_rest_of_line ();
   4712       free (name);
   4713       return false;
   4714     }
   4715 
   4716   if (isReg_p)
   4717     {
   4718       /* 3rd: get register mode.  */
   4719       SKIP_WHITESPACE ();
   4720 
   4721       if (*input_line_pointer != ',')
   4722 	{
   4723 	  as_bad (_("expected comma after register number"));
   4724 	  ignore_rest_of_line ();
   4725 	  free (name);
   4726 	  return false;
   4727 	}
   4728 
   4729       input_line_pointer++;
   4730       mode = input_line_pointer;
   4731 
   4732       if (startswith (mode, "r|w"))
   4733 	{
   4734 	  imode = 0;
   4735 	  input_line_pointer += 3;
   4736 	}
   4737       else if (startswith (mode, "r"))
   4738 	{
   4739 	  imode = ARC_REGISTER_READONLY;
   4740 	  input_line_pointer += 1;
   4741 	}
   4742       else if (!startswith (mode, "w"))
   4743 	{
   4744 	  as_bad (_("invalid mode"));
   4745 	  ignore_rest_of_line ();
   4746 	  free (name);
   4747 	  return false;
   4748 	}
   4749       else
   4750 	{
   4751 	  imode = ARC_REGISTER_WRITEONLY;
   4752 	  input_line_pointer += 1;
   4753 	}
   4754     }
   4755 
   4756   if (isCore_p)
   4757     {
   4758       /* 4th: get core register shortcut.  */
   4759       SKIP_WHITESPACE ();
   4760       if (*input_line_pointer != ',')
   4761 	{
   4762 	  as_bad (_("expected comma after register mode"));
   4763 	  ignore_rest_of_line ();
   4764 	  free (name);
   4765 	  return false;
   4766 	}
   4767 
   4768       input_line_pointer++;
   4769 
   4770       if (startswith (input_line_pointer, "cannot_shortcut"))
   4771 	{
   4772 	  imode |= ARC_REGISTER_NOSHORT_CUT;
   4773 	  input_line_pointer += 15;
   4774 	}
   4775       else if (!startswith (input_line_pointer, "can_shortcut"))
   4776 	{
   4777 	  as_bad (_("shortcut designator invalid"));
   4778 	  ignore_rest_of_line ();
   4779 	  free (name);
   4780 	  return false;
   4781 	}
   4782       else
   4783 	{
   4784 	  input_line_pointer += 12;
   4785 	}
   4786     }
   4787   demand_empty_rest_of_line ();
   4788 
   4789   ereg->name = name;
   4790   ereg->number = number;
   4791   ereg->imode  = imode;
   4792   return true;
   4793 }
   4794 
   4795 /* Create an extension register/condition description in the arc
   4796    extension section of the output file.
   4797 
   4798    The structure for an instruction is like this:
   4799    [0]: Length of the record.
   4800    [1]: Type of the record.
   4801 
   4802    For core regs and condition codes:
   4803    [2]: Value.
   4804    [3]+ Name.
   4805 
   4806    For auxiliary registers:
   4807    [2..5]: Value.
   4808    [6]+ Name
   4809 
   4810    The sequence is terminated by an empty entry.  */
   4811 
   4812 static void
   4813 create_extcore_section (extRegister_t *ereg, int opertype)
   4814 {
   4815   segT old_sec   = now_seg;
   4816   int old_subsec = now_subseg;
   4817   char *p;
   4818   int name_len   = strlen (ereg->name);
   4819 
   4820   arc_set_ext_seg ();
   4821 
   4822   switch (opertype)
   4823     {
   4824     case EXT_COND_CODE:
   4825     case EXT_CORE_REGISTER:
   4826       p = frag_more (1);
   4827       *p = 3 + name_len + 1;
   4828       p = frag_more (1);
   4829       *p = opertype;
   4830       p = frag_more (1);
   4831       *p = ereg->number;
   4832       break;
   4833     case EXT_AUX_REGISTER:
   4834       p = frag_more (1);
   4835       *p = 6 + name_len + 1;
   4836       p = frag_more (1);
   4837       *p = EXT_AUX_REGISTER;
   4838       p = frag_more (1);
   4839       *p = (ereg->number >> 24) & 0xff;
   4840       p = frag_more (1);
   4841       *p = (ereg->number >> 16) & 0xff;
   4842       p = frag_more (1);
   4843       *p = (ereg->number >>  8) & 0xff;
   4844       p = frag_more (1);
   4845       *p = (ereg->number)       & 0xff;
   4846       break;
   4847     default:
   4848       break;
   4849     }
   4850 
   4851   p = frag_more (name_len + 1);
   4852   strcpy (p, ereg->name);
   4853 
   4854   subseg_set (old_sec, old_subsec);
   4855 }
   4856 
   4857 /* Handler .extCoreRegister pseudo-op.  */
   4858 
   4859 static void
   4860 arc_extcorereg (int opertype)
   4861 {
   4862   extRegister_t ereg;
   4863   struct arc_aux_reg *auxr;
   4864   struct arc_flag_operand *ccode;
   4865 
   4866   memset (&ereg, 0, sizeof (ereg));
   4867   if (!tokenize_extregister (&ereg, opertype))
   4868     return;
   4869 
   4870   switch (opertype)
   4871     {
   4872     case EXT_CORE_REGISTER:
   4873       /* Core register.  */
   4874       if (ereg.number > 60)
   4875 	as_bad (_("core register %s value (%d) too large"), ereg.name,
   4876 		ereg.number);
   4877       declare_register (ereg.name, ereg.number);
   4878       break;
   4879     case EXT_AUX_REGISTER:
   4880       /* Auxiliary register.  */
   4881       auxr = XNEW (struct arc_aux_reg);
   4882       auxr->name = ereg.name;
   4883       auxr->cpu = selected_cpu.flags;
   4884       auxr->subclass = NONE;
   4885       auxr->address = ereg.number;
   4886       if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != NULL)
   4887 	as_bad (_("duplicate aux register %s"), auxr->name);
   4888       break;
   4889     case EXT_COND_CODE:
   4890       /* Condition code.  */
   4891       if (ereg.number > 31)
   4892 	as_bad (_("condition code %s value (%d) too large"), ereg.name,
   4893 		ereg.number);
   4894       ext_condcode.size ++;
   4895       ext_condcode.arc_ext_condcode =
   4896 	XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode,
   4897 		    ext_condcode.size + 1);
   4898 
   4899       ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1;
   4900       ccode->name   = ereg.name;
   4901       ccode->code   = ereg.number;
   4902       ccode->bits   = 5;
   4903       ccode->shift  = 0;
   4904       ccode->favail = 0; /* not used.  */
   4905       ccode++;
   4906       memset (ccode, 0, sizeof (struct arc_flag_operand));
   4907       break;
   4908     default:
   4909       as_bad (_("Unknown extension"));
   4910       break;
   4911     }
   4912   create_extcore_section (&ereg, opertype);
   4913 }
   4914 
   4915 /* Parse a .arc_attribute directive.  */
   4916 
   4917 static void
   4918 arc_attribute (int ignored ATTRIBUTE_UNUSED)
   4919 {
   4920   obj_attr_tag_t tag = obj_attr_process_attribute (OBJ_ATTR_PROC);
   4921 
   4922   if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
   4923     attributes_set_explicitly[tag] = true;
   4924 }
   4925 
   4926 /* Set an attribute if it has not already been set by the user.  */
   4927 
   4928 static void
   4929 arc_set_attribute_int (obj_attr_tag_t tag, int value)
   4930 {
   4931   if (tag < 1
   4932       || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
   4933       || !attributes_set_explicitly[tag])
   4934     if (!bfd_elf_add_proc_attr_int (stdoutput, tag, value))
   4935       as_fatal (_("error adding attribute: %s"),
   4936 		bfd_errmsg (bfd_get_error ()));
   4937 }
   4938 
   4939 static void
   4940 arc_set_attribute_string (obj_attr_tag_t tag, const char *value)
   4941 {
   4942   if (tag < 1
   4943       || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
   4944       || !attributes_set_explicitly[tag])
   4945     if (!bfd_elf_add_proc_attr_string (stdoutput, tag, value))
   4946       as_fatal (_("error adding attribute: %s"),
   4947 		bfd_errmsg (bfd_get_error ()));
   4948 }
   4949 
   4950 /* Allocate and concatenate two strings.  s1 can be NULL but not
   4951    s2.  s1 pointer is freed at end of this procedure.  */
   4952 
   4953 static char *
   4954 arc_stralloc (char * s1, const char * s2)
   4955 {
   4956   char * p;
   4957   int len = 0;
   4958 
   4959   if (s1)
   4960     len = strlen (s1) + 1;
   4961 
   4962   /* Only s1 can be null.  */
   4963   gas_assert (s2);
   4964   len += strlen (s2) + 1;
   4965 
   4966   p = xmalloc (len);
   4967 
   4968   if (s1)
   4969     {
   4970       strcpy (p, s1);
   4971       strcat (p, ",");
   4972       strcat (p, s2);
   4973       free (s1);
   4974     }
   4975   else
   4976     strcpy (p, s2);
   4977 
   4978   return p;
   4979 }
   4980 
   4981 /* Set the public ARC object attributes.  */
   4982 
   4983 static void
   4984 arc_set_public_attributes (void)
   4985 {
   4986   int base = 0;
   4987   char *s = NULL;
   4988   unsigned int i;
   4989 
   4990   /* Tag_ARC_CPU_name.  */
   4991   arc_set_attribute_string (Tag_ARC_CPU_name, selected_cpu.name);
   4992 
   4993   /* Tag_ARC_CPU_base.  */
   4994   switch (selected_cpu.eflags & EF_ARC_MACH_MSK)
   4995     {
   4996     case E_ARC_MACH_ARC600:
   4997     case E_ARC_MACH_ARC601:
   4998       base = TAG_CPU_ARC6xx;
   4999       break;
   5000     case E_ARC_MACH_ARC700:
   5001       base = TAG_CPU_ARC7xx;
   5002       break;
   5003     case EF_ARC_CPU_ARCV2EM:
   5004       base = TAG_CPU_ARCEM;
   5005       break;
   5006     case EF_ARC_CPU_ARCV2HS:
   5007       base = TAG_CPU_ARCHS;
   5008       break;
   5009     default:
   5010       base = 0;
   5011       break;
   5012     }
   5013   if (attributes_set_explicitly[Tag_ARC_CPU_base]
   5014       && (base != bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
   5015 					    Tag_ARC_CPU_base)))
   5016     as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
   5017   if (!bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_CPU_base, base))
   5018     as_fatal (_("error adding attribute: %s"),
   5019 	      bfd_errmsg (bfd_get_error ()));
   5020 
   5021   /* Tag_ARC_ABI_osver.  */
   5022   if (attributes_set_explicitly[Tag_ARC_ABI_osver])
   5023     {
   5024       int val = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
   5025 					  Tag_ARC_ABI_osver);
   5026 
   5027       selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_OSABI_MSK)
   5028 			     | (val & 0x0f << 8));
   5029     }
   5030   else
   5031     {
   5032       arc_set_attribute_int (Tag_ARC_ABI_osver, E_ARC_OSABI_CURRENT >> 8);
   5033     }
   5034 
   5035   /* Tag_ARC_ISA_config.  */
   5036   arc_check_feature();
   5037 
   5038   for (i = 0; i < ARRAY_SIZE (feature_list); i++)
   5039     if (selected_cpu.features & feature_list[i].feature)
   5040       s = arc_stralloc (s, feature_list[i].attr);
   5041 
   5042   if (s)
   5043     arc_set_attribute_string (Tag_ARC_ISA_config, s);
   5044 
   5045   /* Tag_ARC_ISA_mpy_option.  */
   5046   arc_set_attribute_int (Tag_ARC_ISA_mpy_option, mpy_option);
   5047 
   5048   /* Tag_ARC_ABI_pic.  */
   5049   arc_set_attribute_int (Tag_ARC_ABI_pic, pic_option);
   5050 
   5051   /* Tag_ARC_ABI_sda.  */
   5052   arc_set_attribute_int (Tag_ARC_ABI_sda, sda_option);
   5053 
   5054   /* Tag_ARC_ABI_tls.  */
   5055   arc_set_attribute_int (Tag_ARC_ABI_tls, tls_option);
   5056 
   5057   /* Tag_ARC_ATR_version.  */
   5058   arc_set_attribute_int (Tag_ARC_ATR_version, 1);
   5059 
   5060   /* Tag_ARC_ABI_rf16.  */
   5061   if (attributes_set_explicitly[Tag_ARC_ABI_rf16]
   5062       && bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
   5063 				   Tag_ARC_ABI_rf16)
   5064       && !rf16_only)
   5065     {
   5066       as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full "
   5067 		 "register file"));
   5068       if (!bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_ABI_rf16, 0))
   5069 	as_fatal (_("error adding attribute: %s"),
   5070 		  bfd_errmsg (bfd_get_error ()));
   5071     }
   5072 }
   5073 
   5074 /* Add the default contents for the .ARC.attributes section.  */
   5075 
   5076 void
   5077 arc_md_finish (void)
   5078 {
   5079   arc_set_public_attributes ();
   5080 
   5081   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
   5082     as_fatal (_("could not set architecture and machine"));
   5083 
   5084   bfd_set_private_flags (stdoutput, selected_cpu.eflags);
   5085 }
   5086 
   5087 void arc_copy_symbol_attributes (symbolS *dest, symbolS *src)
   5088 {
   5089   ARC_GET_FLAG (dest) = ARC_GET_FLAG (src);
   5090 }
   5091 
   5092 int arc_convert_symbolic_attribute (const char *name)
   5093 {
   5094   static const struct
   5095   {
   5096     const char * name;
   5097     const int    tag;
   5098   }
   5099   attribute_table[] =
   5100     {
   5101 #define T(tag) {#tag, tag}
   5102   T (Tag_ARC_PCS_config),
   5103   T (Tag_ARC_CPU_base),
   5104   T (Tag_ARC_CPU_variation),
   5105   T (Tag_ARC_CPU_name),
   5106   T (Tag_ARC_ABI_rf16),
   5107   T (Tag_ARC_ABI_osver),
   5108   T (Tag_ARC_ABI_sda),
   5109   T (Tag_ARC_ABI_pic),
   5110   T (Tag_ARC_ABI_tls),
   5111   T (Tag_ARC_ABI_enumsize),
   5112   T (Tag_ARC_ABI_exceptions),
   5113   T (Tag_ARC_ABI_double_size),
   5114   T (Tag_ARC_ISA_config),
   5115   T (Tag_ARC_ISA_apex),
   5116   T (Tag_ARC_ISA_mpy_option),
   5117   T (Tag_ARC_ATR_version)
   5118 #undef T
   5119     };
   5120   unsigned int i;
   5121 
   5122   if (name == NULL)
   5123     return -1;
   5124 
   5125   for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
   5126     if (streq (name, attribute_table[i].name))
   5127       return attribute_table[i].tag;
   5128 
   5129   return -1;
   5130 }
   5131 
   5132 /* Local variables:
   5133    eval: (c-set-style "gnu")
   5134    indent-tabs-mode: t
   5135    End:  */
   5136