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