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