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