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