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 struct hash_control *arc_opcode_hash;
432
433/* The hash table of register symbols.  */
434static struct hash_control *arc_reg_hash;
435
436/* The hash table of aux register symbols.  */
437static struct hash_control *arc_aux_hash;
438
439/* The hash table of address types.  */
440static struct hash_control *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 = 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, *retval;
758  struct arc_opcode_hash_entry *entry;
759  name = opcode->name;
760
761  entry = 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      retval = hash_insert (arc_opcode_hash, name, (void *) entry);
769      if (retval)
770	as_fatal (_("internal error: can't hash opcode '%s': %s"),
771		  name, retval);
772    }
773
774  entry->opcode = XRESIZEVEC (const struct arc_opcode *, entry->opcode,
775			      entry->count + 1);
776
777  if (entry->opcode == NULL)
778    as_fatal (_("Virtual memory exhausted"));
779
780  entry->opcode[entry->count] = opcode;
781  entry->count++;
782}
783
784
785/* Like md_number_to_chars but for middle-endian values.  The 4-byte limm
786   value, is encoded as 'middle-endian' for a little-endian target.  This
787   function is used for regular 4, 6, and 8 byte instructions as well.  */
788
789static void
790md_number_to_chars_midend (char *buf, unsigned long long val, int n)
791{
792  switch (n)
793    {
794    case 2:
795      md_number_to_chars (buf, val, n);
796      break;
797    case 6:
798      md_number_to_chars (buf, (val & 0xffff00000000ull) >> 32, 2);
799      md_number_to_chars_midend (buf + 2, (val & 0xffffffff), 4);
800      break;
801    case 4:
802      md_number_to_chars (buf,     (val & 0xffff0000) >> 16, 2);
803      md_number_to_chars (buf + 2, (val & 0xffff), 2);
804      break;
805    case 8:
806      md_number_to_chars_midend (buf, (val & 0xffffffff00000000ull) >> 32, 4);
807      md_number_to_chars_midend (buf + 4, (val & 0xffffffff), 4);
808      break;
809    default:
810      abort ();
811    }
812}
813
814/* Check if a feature is allowed for a specific CPU.  */
815
816static void
817arc_check_feature (void)
818{
819  unsigned i;
820
821  if (!selected_cpu.features
822      || !selected_cpu.name)
823    return;
824
825  for (i = 0; i < ARRAY_SIZE (feature_list); i++)
826    if ((selected_cpu.features & feature_list[i].feature)
827	&& !(selected_cpu.flags & feature_list[i].cpus))
828      as_bad (_("invalid %s option for %s cpu"), feature_list[i].name,
829	      selected_cpu.name);
830
831  for (i = 0; i < ARRAY_SIZE (conflict_list); i++)
832    if ((selected_cpu.features & conflict_list[i]) == conflict_list[i])
833      as_bad(_("conflicting ISA extension attributes."));
834}
835
836/* Select an appropriate entry from CPU_TYPES based on ARG and initialise
837   the relevant static global variables.  Parameter SEL describes where
838   this selection originated from.  */
839
840static void
841arc_select_cpu (const char *arg, enum mach_selection_type sel)
842{
843  int i;
844  static struct cpu_type old_cpu = { 0, 0, 0, E_ARC_OSABI_CURRENT, 0 };
845
846  /* We should only set a default if we've not made a selection from some
847     other source.  */
848  gas_assert (sel != MACH_SELECTION_FROM_DEFAULT
849              || mach_selection_mode == MACH_SELECTION_NONE);
850
851  if ((mach_selection_mode == MACH_SELECTION_FROM_CPU_DIRECTIVE)
852      && (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE))
853    as_bad (_("Multiple .cpu directives found"));
854
855  /* Look for a matching entry in CPU_TYPES array.  */
856  for (i = 0; cpu_types[i].name; ++i)
857    {
858      if (!strcasecmp (cpu_types[i].name, arg))
859        {
860          /* If a previous selection was made on the command line, then we
861             allow later selections on the command line to override earlier
862             ones.  However, a selection from a '.cpu NAME' directive must
863             match the command line selection, or we give a warning.  */
864          if (mach_selection_mode == MACH_SELECTION_FROM_COMMAND_LINE)
865            {
866              gas_assert (sel == MACH_SELECTION_FROM_COMMAND_LINE
867                          || sel == MACH_SELECTION_FROM_CPU_DIRECTIVE);
868              if (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE
869                  && selected_cpu.mach != cpu_types[i].mach)
870                {
871                  as_warn (_("Command-line value overrides \".cpu\" directive"));
872                }
873	      return;
874            }
875	  /* Initialise static global data about selected machine type.  */
876	  selected_cpu.flags = cpu_types[i].flags;
877	  selected_cpu.name = cpu_types[i].name;
878	  selected_cpu.features = cpu_types[i].features | cl_features;
879	  selected_cpu.mach = cpu_types[i].mach;
880	  selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_MACH_MSK)
881				 | cpu_types[i].eflags);
882          break;
883        }
884    }
885
886  if (!cpu_types[i].name)
887    as_fatal (_("unknown architecture: %s\n"), arg);
888
889  /* Check if set features are compatible with the chosen CPU.  */
890  arc_check_feature ();
891
892  /* If we change the CPU, we need to re-init the bfd.  */
893  if (mach_selection_mode != MACH_SELECTION_NONE
894      && (old_cpu.mach != selected_cpu.mach))
895    {
896      bfd_find_target (arc_target_format, stdoutput);
897      if (! bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
898	as_warn (_("Could not set architecture and machine"));
899    }
900
901  mach_selection_mode = sel;
902  old_cpu = selected_cpu;
903}
904
905/* Here ends all the ARCompact extension instruction assembling
906   stuff.  */
907
908static void
909arc_extra_reloc (int r_type)
910{
911  char *sym_name, c;
912  symbolS *sym, *lab = NULL;
913
914  if (*input_line_pointer == '@')
915    input_line_pointer++;
916  c = get_symbol_name (&sym_name);
917  sym = symbol_find_or_make (sym_name);
918  restore_line_pointer (c);
919  if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
920    {
921      ++input_line_pointer;
922      char *lab_name;
923      c = get_symbol_name (&lab_name);
924      lab = symbol_find_or_make (lab_name);
925      restore_line_pointer (c);
926    }
927
928  /* These relocations exist as a mechanism for the compiler to tell the
929     linker how to patch the code if the tls model is optimised.  However,
930     the relocation itself does not require any space within the assembler
931     fragment, and so we pass a size of 0.
932
933     The lines that generate these relocations look like this:
934
935         .tls_gd_ld @.tdata`bl __tls_get_addr@plt
936
937     The '.tls_gd_ld @.tdata' is processed first and generates the
938     additional relocation, while the 'bl __tls_get_addr@plt' is processed
939     second and generates the additional branch.
940
941     It is possible that the additional relocation generated by the
942     '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
943     while the 'bl __tls_get_addr@plt' will be generated as the first thing
944     in the next fragment.  This will be fine; both relocations will still
945     appear to be at the same address in the generated object file.
946     However, this only works as the additional relocation is generated
947     with size of 0 bytes.  */
948  fixS *fixP
949    = fix_new (frag_now,	/* Which frag?  */
950	       frag_now_fix (),	/* Where in that frag?  */
951	       0,		/* size: 1, 2, or 4 usually.  */
952	       sym,		/* X_add_symbol.  */
953	       0,		/* X_add_number.  */
954	       FALSE,		/* TRUE if PC-relative relocation.  */
955	       r_type		/* Relocation type.  */);
956  fixP->fx_subsy = lab;
957}
958
959static symbolS *
960arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
961		    symbolS *symbolP, addressT size)
962{
963  addressT align = 0;
964  SKIP_WHITESPACE ();
965
966  if (*input_line_pointer == ',')
967    {
968      align = parse_align (1);
969
970      if (align == (addressT) -1)
971	return NULL;
972    }
973  else
974    {
975      if (size >= 8)
976	align = 3;
977      else if (size >= 4)
978	align = 2;
979      else if (size >= 2)
980	align = 1;
981      else
982	align = 0;
983    }
984
985  bss_alloc (symbolP, size, align);
986  S_CLEAR_EXTERNAL (symbolP);
987
988  return symbolP;
989}
990
991static void
992arc_lcomm (int ignore)
993{
994  symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
995
996  if (symbolP)
997    symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
998}
999
1000/* Select the cpu we're assembling for.  */
1001
1002static void
1003arc_option (int ignore ATTRIBUTE_UNUSED)
1004{
1005  char c;
1006  char *cpu;
1007  const char *cpu_name;
1008
1009  c = get_symbol_name (&cpu);
1010
1011  cpu_name = cpu;
1012  if ((!strcmp ("ARC600", cpu))
1013      || (!strcmp ("ARC601", cpu))
1014      || (!strcmp ("A6", cpu)))
1015    cpu_name = "arc600";
1016  else if ((!strcmp ("ARC700", cpu))
1017           || (!strcmp ("A7", cpu)))
1018    cpu_name = "arc700";
1019  else if (!strcmp ("EM", cpu))
1020    cpu_name = "arcem";
1021  else if (!strcmp ("HS", cpu))
1022    cpu_name = "archs";
1023  else if (!strcmp ("NPS400", cpu))
1024    cpu_name = "nps400";
1025
1026  arc_select_cpu (cpu_name, MACH_SELECTION_FROM_CPU_DIRECTIVE);
1027
1028  restore_line_pointer (c);
1029  demand_empty_rest_of_line ();
1030}
1031
1032/* Smartly print an expression.  */
1033
1034static void
1035debug_exp (expressionS *t)
1036{
1037  const char *name ATTRIBUTE_UNUSED;
1038  const char *namemd ATTRIBUTE_UNUSED;
1039
1040  pr_debug ("debug_exp: ");
1041
1042  switch (t->X_op)
1043    {
1044    default:			name = "unknown";		break;
1045    case O_illegal:		name = "O_illegal";		break;
1046    case O_absent:		name = "O_absent";		break;
1047    case O_constant:		name = "O_constant";		break;
1048    case O_symbol:		name = "O_symbol";		break;
1049    case O_symbol_rva:		name = "O_symbol_rva";		break;
1050    case O_register:		name = "O_register";		break;
1051    case O_big:			name = "O_big";			break;
1052    case O_uminus:		name = "O_uminus";		break;
1053    case O_bit_not:		name = "O_bit_not";		break;
1054    case O_logical_not:		name = "O_logical_not";		break;
1055    case O_multiply:		name = "O_multiply";		break;
1056    case O_divide:		name = "O_divide";		break;
1057    case O_modulus:		name = "O_modulus";		break;
1058    case O_left_shift:		name = "O_left_shift";		break;
1059    case O_right_shift:		name = "O_right_shift";		break;
1060    case O_bit_inclusive_or:	name = "O_bit_inclusive_or";	break;
1061    case O_bit_or_not:		name = "O_bit_or_not";		break;
1062    case O_bit_exclusive_or:	name = "O_bit_exclusive_or";	break;
1063    case O_bit_and:		name = "O_bit_and";		break;
1064    case O_add:			name = "O_add";			break;
1065    case O_subtract:		name = "O_subtract";		break;
1066    case O_eq:			name = "O_eq";			break;
1067    case O_ne:			name = "O_ne";			break;
1068    case O_lt:			name = "O_lt";			break;
1069    case O_le:			name = "O_le";			break;
1070    case O_ge:			name = "O_ge";			break;
1071    case O_gt:			name = "O_gt";			break;
1072    case O_logical_and:		name = "O_logical_and";		break;
1073    case O_logical_or:		name = "O_logical_or";		break;
1074    case O_index:		name = "O_index";		break;
1075    case O_bracket:		name = "O_bracket";		break;
1076    case O_colon:		name = "O_colon";               break;
1077    case O_addrtype:		name = "O_addrtype";            break;
1078    }
1079
1080  switch (t->X_md)
1081    {
1082    default:			namemd = "unknown";		break;
1083    case O_gotoff:		namemd = "O_gotoff";		break;
1084    case O_gotpc:		namemd = "O_gotpc";		break;
1085    case O_plt:			namemd = "O_plt";		break;
1086    case O_sda:			namemd = "O_sda";		break;
1087    case O_pcl:			namemd = "O_pcl";		break;
1088    case O_tlsgd:		namemd = "O_tlsgd";		break;
1089    case O_tlsie:		namemd = "O_tlsie";		break;
1090    case O_tpoff9:		namemd = "O_tpoff9";		break;
1091    case O_tpoff:		namemd = "O_tpoff";		break;
1092    case O_dtpoff9:		namemd = "O_dtpoff9";		break;
1093    case O_dtpoff:		namemd = "O_dtpoff";		break;
1094    }
1095
1096  pr_debug ("%s (%s, %s, %d, %s)", name,
1097	    (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1098	    (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1099	    (int) t->X_add_number,
1100	    (t->X_md) ? namemd : "--");
1101  pr_debug ("\n");
1102  fflush (stderr);
1103}
1104
1105/* Helper for parsing an argument, used for sorting out the relocation
1106   type.  */
1107
1108static void
1109parse_reloc_symbol (expressionS *resultP)
1110{
1111  char *reloc_name, c, *sym_name;
1112  size_t len;
1113  int i;
1114  const struct arc_reloc_op_tag *r;
1115  expressionS right;
1116  symbolS *base;
1117
1118  /* A relocation operand has the following form
1119     @identifier@relocation_type.  The identifier is already in
1120     tok!  */
1121  if (resultP->X_op != O_symbol)
1122    {
1123      as_bad (_("No valid label relocation operand"));
1124      resultP->X_op = O_illegal;
1125      return;
1126    }
1127
1128  /* Parse @relocation_type.  */
1129  input_line_pointer++;
1130  c = get_symbol_name (&reloc_name);
1131  len = input_line_pointer - reloc_name;
1132  if (len == 0)
1133    {
1134      as_bad (_("No relocation operand"));
1135      resultP->X_op = O_illegal;
1136      return;
1137    }
1138
1139  /* Go through known relocation and try to find a match.  */
1140  r = &arc_reloc_op[0];
1141  for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
1142    if (len == r->length
1143	&& memcmp (reloc_name, r->name, len) == 0)
1144      break;
1145  if (i < 0)
1146    {
1147      as_bad (_("Unknown relocation operand: @%s"), reloc_name);
1148      resultP->X_op = O_illegal;
1149      return;
1150    }
1151
1152  *input_line_pointer = c;
1153  SKIP_WHITESPACE_AFTER_NAME ();
1154  /* Extra check for TLS: base.  */
1155  if (*input_line_pointer == '@')
1156    {
1157      if (resultP->X_op_symbol != NULL
1158	  || resultP->X_op != O_symbol)
1159	{
1160	  as_bad (_("Unable to parse TLS base: %s"),
1161		  input_line_pointer);
1162	  resultP->X_op = O_illegal;
1163	  return;
1164	}
1165      input_line_pointer++;
1166      c = get_symbol_name (&sym_name);
1167      base = symbol_find_or_make (sym_name);
1168      resultP->X_op = O_subtract;
1169      resultP->X_op_symbol = base;
1170      restore_line_pointer (c);
1171      right.X_add_number = 0;
1172    }
1173
1174  if ((*input_line_pointer != '+')
1175      && (*input_line_pointer != '-'))
1176    right.X_add_number = 0;
1177  else
1178    {
1179      /* Parse the constant of a complex relocation expression
1180	 like @identifier@reloc +/- const.  */
1181      if (! r->complex_expr)
1182	{
1183	  as_bad (_("@%s is not a complex relocation."), r->name);
1184	  resultP->X_op = O_illegal;
1185	  return;
1186	}
1187      expression (&right);
1188      if (right.X_op != O_constant)
1189	{
1190	  as_bad (_("Bad expression: @%s + %s."),
1191		  r->name, input_line_pointer);
1192	  resultP->X_op = O_illegal;
1193	  return;
1194	}
1195    }
1196
1197  resultP->X_md = r->op;
1198  resultP->X_add_number = right.X_add_number;
1199}
1200
1201/* Parse the arguments to an opcode.  */
1202
1203static int
1204tokenize_arguments (char *str,
1205		    expressionS *tok,
1206		    int ntok)
1207{
1208  char *old_input_line_pointer;
1209  bfd_boolean saw_comma = FALSE;
1210  bfd_boolean saw_arg = FALSE;
1211  int brk_lvl = 0;
1212  int num_args = 0;
1213
1214  memset (tok, 0, sizeof (*tok) * ntok);
1215
1216  /* Save and restore input_line_pointer around this function.  */
1217  old_input_line_pointer = input_line_pointer;
1218  input_line_pointer = str;
1219
1220  while (*input_line_pointer)
1221    {
1222      SKIP_WHITESPACE ();
1223      switch (*input_line_pointer)
1224	{
1225	case '\0':
1226	  goto fini;
1227
1228	case ',':
1229	  input_line_pointer++;
1230	  if (saw_comma || !saw_arg)
1231	    goto err;
1232	  saw_comma = TRUE;
1233	  break;
1234
1235	case '}':
1236	case ']':
1237	  ++input_line_pointer;
1238	  --brk_lvl;
1239	  if (!saw_arg || num_args == ntok)
1240	    goto err;
1241	  tok->X_op = O_bracket;
1242	  ++tok;
1243	  ++num_args;
1244	  break;
1245
1246	case '{':
1247	case '[':
1248	  input_line_pointer++;
1249	  if (brk_lvl || num_args == ntok)
1250	    goto err;
1251	  ++brk_lvl;
1252	  tok->X_op = O_bracket;
1253	  ++tok;
1254	  ++num_args;
1255	  break;
1256
1257        case ':':
1258          input_line_pointer++;
1259          if (!saw_arg || num_args == ntok)
1260            goto err;
1261          tok->X_op = O_colon;
1262          saw_arg = FALSE;
1263          ++tok;
1264          ++num_args;
1265          break;
1266
1267	case '@':
1268	  /* We have labels, function names and relocations, all
1269	     starting with @ symbol.  Sort them out.  */
1270	  if ((saw_arg && !saw_comma) || num_args == ntok)
1271	    goto err;
1272
1273	  /* Parse @label.  */
1274	  input_line_pointer++;
1275	  tok->X_op = O_symbol;
1276	  tok->X_md = O_absent;
1277	  expression (tok);
1278
1279	  if (*input_line_pointer == '@')
1280	    parse_reloc_symbol (tok);
1281
1282	  debug_exp (tok);
1283
1284	  if (tok->X_op == O_illegal
1285              || tok->X_op == O_absent
1286              || num_args == ntok)
1287	    goto err;
1288
1289	  saw_comma = FALSE;
1290	  saw_arg = TRUE;
1291	  tok++;
1292	  num_args++;
1293	  break;
1294
1295	case '%':
1296	  /* Can be a register.  */
1297	  ++input_line_pointer;
1298	  /* Fall through.  */
1299	default:
1300
1301	  if ((saw_arg && !saw_comma) || num_args == ntok)
1302	    goto err;
1303
1304	  tok->X_op = O_absent;
1305	  tok->X_md = O_absent;
1306	  expression (tok);
1307
1308	  /* Legacy: There are cases when we have
1309	     identifier@relocation_type, if it is the case parse the
1310	     relocation type as well.  */
1311	  if (*input_line_pointer == '@')
1312	    parse_reloc_symbol (tok);
1313
1314	  debug_exp (tok);
1315
1316	  if (tok->X_op == O_illegal
1317              || tok->X_op == O_absent
1318              || num_args == ntok)
1319	    goto err;
1320
1321	  saw_comma = FALSE;
1322	  saw_arg = TRUE;
1323	  tok++;
1324	  num_args++;
1325	  break;
1326	}
1327    }
1328
1329 fini:
1330  if (saw_comma || brk_lvl)
1331    goto err;
1332  input_line_pointer = old_input_line_pointer;
1333
1334  return num_args;
1335
1336 err:
1337  if (brk_lvl)
1338    as_bad (_("Brackets in operand field incorrect"));
1339  else if (saw_comma)
1340    as_bad (_("extra comma"));
1341  else if (!saw_arg)
1342    as_bad (_("missing argument"));
1343  else
1344    as_bad (_("missing comma or colon"));
1345  input_line_pointer = old_input_line_pointer;
1346  return -1;
1347}
1348
1349/* Parse the flags to a structure.  */
1350
1351static int
1352tokenize_flags (const char *str,
1353		struct arc_flags flags[],
1354		int nflg)
1355{
1356  char *old_input_line_pointer;
1357  bfd_boolean saw_flg = FALSE;
1358  bfd_boolean saw_dot = FALSE;
1359  int num_flags  = 0;
1360  size_t flgnamelen;
1361
1362  memset (flags, 0, sizeof (*flags) * nflg);
1363
1364  /* Save and restore input_line_pointer around this function.  */
1365  old_input_line_pointer = input_line_pointer;
1366  input_line_pointer = (char *) str;
1367
1368  while (*input_line_pointer)
1369    {
1370      switch (*input_line_pointer)
1371	{
1372	case ' ':
1373	case '\0':
1374	  goto fini;
1375
1376	case '.':
1377	  input_line_pointer++;
1378	  if (saw_dot)
1379	    goto err;
1380	  saw_dot = TRUE;
1381	  saw_flg = FALSE;
1382	  break;
1383
1384	default:
1385	  if (saw_flg && !saw_dot)
1386	    goto err;
1387
1388	  if (num_flags >= nflg)
1389	    goto err;
1390
1391	  flgnamelen = strspn (input_line_pointer,
1392			       "abcdefghijklmnopqrstuvwxyz0123456789");
1393	  if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1394	    goto err;
1395
1396	  memcpy (flags->name, input_line_pointer, flgnamelen);
1397
1398	  input_line_pointer += flgnamelen;
1399	  flags++;
1400	  saw_dot = FALSE;
1401	  saw_flg = TRUE;
1402	  num_flags++;
1403	  break;
1404	}
1405    }
1406
1407 fini:
1408  input_line_pointer = old_input_line_pointer;
1409  return num_flags;
1410
1411 err:
1412  if (saw_dot)
1413    as_bad (_("extra dot"));
1414  else if (!saw_flg)
1415    as_bad (_("unrecognized flag"));
1416  else
1417    as_bad (_("failed to parse flags"));
1418  input_line_pointer = old_input_line_pointer;
1419  return -1;
1420}
1421
1422/* Apply the fixups in order.  */
1423
1424static void
1425apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1426{
1427  int i;
1428
1429  for (i = 0; i < insn->nfixups; i++)
1430    {
1431      struct arc_fixup *fixup = &insn->fixups[i];
1432      int size, pcrel, offset = 0;
1433
1434      /* FIXME! the reloc size is wrong in the BFD file.
1435	 When it is fixed please delete me.  */
1436      size = ((insn->len == 2) && !fixup->islong) ? 2 : 4;
1437
1438      if (fixup->islong)
1439	offset = insn->len;
1440
1441      /* Some fixups are only used internally, thus no howto.  */
1442      if ((int) fixup->reloc == 0)
1443	as_fatal (_("Unhandled reloc type"));
1444
1445      if ((int) fixup->reloc < 0)
1446	{
1447	  /* FIXME! the reloc size is wrong in the BFD file.
1448	     When it is fixed please enable me.
1449	     size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
1450	  pcrel = fixup->pcrel;
1451	}
1452      else
1453	{
1454	  reloc_howto_type *reloc_howto =
1455	    bfd_reloc_type_lookup (stdoutput,
1456				   (bfd_reloc_code_real_type) fixup->reloc);
1457	  gas_assert (reloc_howto);
1458
1459	  /* FIXME! the reloc size is wrong in the BFD file.
1460	     When it is fixed please enable me.
1461	     size = bfd_get_reloc_size (reloc_howto); */
1462	  pcrel = reloc_howto->pc_relative;
1463	}
1464
1465      pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1466offset %d + %d\n",
1467		fragP->fr_file, fragP->fr_line,
1468		(fixup->reloc < 0) ? "Internal" :
1469		bfd_get_reloc_code_name (fixup->reloc),
1470		pcrel ? "Y" : "N",
1471		size, fix, offset);
1472      fix_new_exp (fragP, fix + offset,
1473		   size, &fixup->exp, pcrel, fixup->reloc);
1474
1475      /* Check for ZOLs, and update symbol info if any.  */
1476      if (LP_INSN (insn->insn))
1477	{
1478	  gas_assert (fixup->exp.X_add_symbol);
1479	  ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
1480	}
1481    }
1482}
1483
1484/* Actually output an instruction with its fixup.  */
1485
1486static void
1487emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax)
1488{
1489  char *f = where;
1490  size_t total_len;
1491
1492  pr_debug ("Emit insn : 0x%llx\n", insn->insn);
1493  pr_debug ("\tLength  : 0x%d\n", insn->len);
1494  pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
1495
1496  /* Write out the instruction.  */
1497  total_len = insn->len + (insn->has_limm ? 4 : 0);
1498  if (!relax)
1499    f = frag_more (total_len);
1500
1501  md_number_to_chars_midend(f, insn->insn, insn->len);
1502
1503  if (insn->has_limm)
1504    md_number_to_chars_midend (f + insn->len, insn->limm, 4);
1505  dwarf2_emit_insn (total_len);
1506
1507  if (!relax)
1508    apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
1509}
1510
1511static void
1512emit_insn1 (struct arc_insn *insn)
1513{
1514  /* How frag_var's args are currently configured:
1515     - rs_machine_dependent, to dictate it's a relaxation frag.
1516     - FRAG_MAX_GROWTH, maximum size of instruction
1517     - 0, variable size that might grow...unused by generic relaxation.
1518     - frag_now->fr_subtype, fr_subtype starting value, set previously.
1519     - s, opand expression.
1520     - 0, offset but it's unused.
1521     - 0, opcode but it's unused.  */
1522  symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
1523  frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
1524
1525  if (frag_room () < FRAG_MAX_GROWTH)
1526    {
1527      /* Handle differently when frag literal memory is exhausted.
1528	 This is used because when there's not enough memory left in
1529	 the current frag, a new frag is created and the information
1530	 we put into frag_now->tc_frag_data is disregarded.  */
1531
1532      struct arc_relax_type relax_info_copy;
1533      relax_substateT subtype = frag_now->fr_subtype;
1534
1535      memcpy (&relax_info_copy, &frag_now->tc_frag_data,
1536	      sizeof (struct arc_relax_type));
1537
1538      frag_wane (frag_now);
1539      frag_grow (FRAG_MAX_GROWTH);
1540
1541      memcpy (&frag_now->tc_frag_data, &relax_info_copy,
1542	      sizeof (struct arc_relax_type));
1543
1544      frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1545		subtype, s, 0, 0);
1546    }
1547  else
1548    frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1549	      frag_now->fr_subtype, s, 0, 0);
1550}
1551
1552static void
1553emit_insn (struct arc_insn *insn)
1554{
1555  if (insn->relax)
1556    emit_insn1 (insn);
1557  else
1558    emit_insn0 (insn, NULL, FALSE);
1559}
1560
1561/* Check whether a symbol involves a register.  */
1562
1563static bfd_boolean
1564contains_register (symbolS *sym)
1565{
1566  if (sym)
1567    {
1568      expressionS *ex = symbol_get_value_expression (sym);
1569
1570      return ((O_register == ex->X_op)
1571	      && !contains_register (ex->X_add_symbol)
1572	      && !contains_register (ex->X_op_symbol));
1573    }
1574
1575  return FALSE;
1576}
1577
1578/* Returns the register number within a symbol.  */
1579
1580static int
1581get_register (symbolS *sym)
1582{
1583  if (!contains_register (sym))
1584    return -1;
1585
1586  expressionS *ex = symbol_get_value_expression (sym);
1587  return regno (ex->X_add_number);
1588}
1589
1590/* Return true if a RELOC is generic.  A generic reloc is PC-rel of a
1591   simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32.  */
1592
1593static bfd_boolean
1594generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
1595{
1596  if (!reloc)
1597    return FALSE;
1598
1599  switch (reloc)
1600    {
1601    case BFD_RELOC_ARC_SDA_LDST:
1602    case BFD_RELOC_ARC_SDA_LDST1:
1603    case BFD_RELOC_ARC_SDA_LDST2:
1604    case BFD_RELOC_ARC_SDA16_LD:
1605    case BFD_RELOC_ARC_SDA16_LD1:
1606    case BFD_RELOC_ARC_SDA16_LD2:
1607    case BFD_RELOC_ARC_SDA16_ST2:
1608    case BFD_RELOC_ARC_SDA32_ME:
1609      return FALSE;
1610    default:
1611      return TRUE;
1612    }
1613}
1614
1615/* Allocates a tok entry.  */
1616
1617static int
1618allocate_tok (expressionS *tok, int ntok, int cidx)
1619{
1620  if (ntok > MAX_INSN_ARGS - 2)
1621    return 0; /* No space left.  */
1622
1623  if (cidx > ntok)
1624    return 0; /* Incorrect args.  */
1625
1626  memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
1627
1628  if (cidx == ntok)
1629    return 1; /* Success.  */
1630  return allocate_tok (tok, ntok - 1, cidx);
1631}
1632
1633/* Check if an particular ARC feature is enabled.  */
1634
1635static bfd_boolean
1636check_cpu_feature (insn_subclass_t sc)
1637{
1638  if (is_code_density_p (sc) && !(selected_cpu.features & CD))
1639    return FALSE;
1640
1641  if (is_spfp_p (sc) && !(selected_cpu.features & SPX))
1642    return FALSE;
1643
1644  if (is_dpfp_p (sc) && !(selected_cpu.features & DPX))
1645    return FALSE;
1646
1647  if (is_fpuda_p (sc) && !(selected_cpu.features & DPA))
1648    return FALSE;
1649
1650  if (is_nps400_p (sc) && !(selected_cpu.features & NPS400))
1651    return FALSE;
1652
1653  return TRUE;
1654}
1655
1656/* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1657   operands in OPCODE.  Stores the matching OPCODES into the FIRST_PFLAG
1658   array and returns TRUE if the flag operands all match, otherwise,
1659   returns FALSE, in which case the FIRST_PFLAG array may have been
1660   modified.  */
1661
1662static bfd_boolean
1663parse_opcode_flags (const struct arc_opcode *opcode,
1664                    int nflgs,
1665                    struct arc_flags *first_pflag)
1666{
1667  int lnflg, i;
1668  const unsigned char *flgidx;
1669
1670  lnflg = nflgs;
1671  for (i = 0; i < nflgs; i++)
1672    first_pflag[i].flgp = NULL;
1673
1674  /* Check the flags.  Iterate over the valid flag classes.  */
1675  for (flgidx = opcode->flags; *flgidx; ++flgidx)
1676    {
1677      /* Get a valid flag class.  */
1678      const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
1679      const unsigned *flgopridx;
1680      int cl_matches = 0;
1681      struct arc_flags *pflag = NULL;
1682
1683      /* Check if opcode has implicit flag classes.  */
1684      if (cl_flags->flag_class & F_CLASS_IMPLICIT)
1685	continue;
1686
1687      /* Check for extension conditional codes.  */
1688      if (ext_condcode.arc_ext_condcode
1689          && cl_flags->flag_class & F_CLASS_EXTEND)
1690        {
1691          struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode;
1692          while (pf->name)
1693            {
1694              pflag = first_pflag;
1695              for (i = 0; i < nflgs; i++, pflag++)
1696                {
1697                  if (!strcmp (pf->name, pflag->name))
1698                    {
1699                      if (pflag->flgp != NULL)
1700                        return FALSE;
1701                      /* Found it.  */
1702                      cl_matches++;
1703                      pflag->flgp = pf;
1704                      lnflg--;
1705                      break;
1706                    }
1707                }
1708              pf++;
1709            }
1710        }
1711
1712      for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
1713        {
1714          const struct arc_flag_operand *flg_operand;
1715
1716          pflag = first_pflag;
1717          flg_operand = &arc_flag_operands[*flgopridx];
1718          for (i = 0; i < nflgs; i++, pflag++)
1719            {
1720              /* Match against the parsed flags.  */
1721              if (!strcmp (flg_operand->name, pflag->name))
1722                {
1723                  if (pflag->flgp != NULL)
1724                    return FALSE;
1725                  cl_matches++;
1726                  pflag->flgp = flg_operand;
1727                  lnflg--;
1728                  break; /* goto next flag class and parsed flag.  */
1729                }
1730            }
1731        }
1732
1733      if ((cl_flags->flag_class & F_CLASS_REQUIRED) && cl_matches == 0)
1734        return FALSE;
1735      if ((cl_flags->flag_class & F_CLASS_OPTIONAL) && cl_matches > 1)
1736        return FALSE;
1737    }
1738
1739  /* Did I check all the parsed flags?  */
1740  return lnflg ? FALSE : TRUE;
1741}
1742
1743
1744/* Search forward through all variants of an opcode looking for a
1745   syntax match.  */
1746
1747static const struct arc_opcode *
1748find_opcode_match (const struct arc_opcode_hash_entry *entry,
1749		   expressionS *tok,
1750		   int *pntok,
1751		   struct arc_flags *first_pflag,
1752		   int nflgs,
1753		   int *pcpumatch,
1754		   const char **errmsg)
1755{
1756  const struct arc_opcode *opcode;
1757  struct arc_opcode_hash_entry_iterator iter;
1758  int ntok = *pntok;
1759  int got_cpu_match = 0;
1760  expressionS bktok[MAX_INSN_ARGS];
1761  int bkntok;
1762  expressionS emptyE;
1763
1764  arc_opcode_hash_entry_iterator_init (&iter);
1765  memset (&emptyE, 0, sizeof (emptyE));
1766  memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
1767  bkntok = ntok;
1768
1769  for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter);
1770       opcode != NULL;
1771       opcode = arc_opcode_hash_entry_iterator_next (entry, &iter))
1772    {
1773      const unsigned char *opidx;
1774      int tokidx = 0;
1775      const expressionS *t = &emptyE;
1776
1777      pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
1778		frag_now->fr_file, frag_now->fr_line, opcode->opcode);
1779
1780      /* Don't match opcodes that don't exist on this
1781	 architecture.  */
1782      if (!(opcode->cpu & selected_cpu.flags))
1783	goto match_failed;
1784
1785      if (!check_cpu_feature (opcode->subclass))
1786	goto match_failed;
1787
1788      got_cpu_match = 1;
1789      pr_debug ("cpu ");
1790
1791      /* Check the operands.  */
1792      for (opidx = opcode->operands; *opidx; ++opidx)
1793	{
1794	  const struct arc_operand *operand = &arc_operands[*opidx];
1795
1796	  /* Only take input from real operands.  */
1797	  if (ARC_OPERAND_IS_FAKE (operand))
1798	    continue;
1799
1800	  /* When we expect input, make sure we have it.  */
1801	  if (tokidx >= ntok)
1802	    goto match_failed;
1803
1804	  /* Match operand type with expression type.  */
1805	  switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
1806	    {
1807            case ARC_OPERAND_ADDRTYPE:
1808	      {
1809		*errmsg = NULL;
1810
1811		/* Check to be an address type.  */
1812		if (tok[tokidx].X_op != O_addrtype)
1813		  goto match_failed;
1814
1815		/* All address type operands need to have an insert
1816		   method in order to check that we have the correct
1817		   address type.  */
1818		gas_assert (operand->insert != NULL);
1819		(*operand->insert) (0, tok[tokidx].X_add_number,
1820				    errmsg);
1821		if (*errmsg != NULL)
1822		  goto match_failed;
1823	      }
1824              break;
1825
1826	    case ARC_OPERAND_IR:
1827	      /* Check to be a register.  */
1828	      if ((tok[tokidx].X_op != O_register
1829		   || !is_ir_num (tok[tokidx].X_add_number))
1830		  && !(operand->flags & ARC_OPERAND_IGNORE))
1831		goto match_failed;
1832
1833	      /* If expect duplicate, make sure it is duplicate.  */
1834	      if (operand->flags & ARC_OPERAND_DUPLICATE)
1835		{
1836		  /* Check for duplicate.  */
1837		  if (t->X_op != O_register
1838		      || !is_ir_num (t->X_add_number)
1839		      || (regno (t->X_add_number) !=
1840			  regno (tok[tokidx].X_add_number)))
1841		    goto match_failed;
1842		}
1843
1844	      /* Special handling?  */
1845	      if (operand->insert)
1846		{
1847		  *errmsg = NULL;
1848		  (*operand->insert)(0,
1849				     regno (tok[tokidx].X_add_number),
1850				     errmsg);
1851		  if (*errmsg)
1852		    {
1853		      if (operand->flags & ARC_OPERAND_IGNORE)
1854			{
1855			  /* Missing argument, create one.  */
1856			  if (!allocate_tok (tok, ntok - 1, tokidx))
1857			    goto match_failed;
1858
1859			  tok[tokidx].X_op = O_absent;
1860			  ++ntok;
1861			}
1862		      else
1863			goto match_failed;
1864		    }
1865		}
1866
1867	      t = &tok[tokidx];
1868	      break;
1869
1870	    case ARC_OPERAND_BRAKET:
1871	      /* Check if bracket is also in opcode table as
1872		 operand.  */
1873	      if (tok[tokidx].X_op != O_bracket)
1874		goto match_failed;
1875	      break;
1876
1877            case ARC_OPERAND_COLON:
1878              /* Check if colon is also in opcode table as operand.  */
1879              if (tok[tokidx].X_op != O_colon)
1880                goto match_failed;
1881              break;
1882
1883	    case ARC_OPERAND_LIMM:
1884	    case ARC_OPERAND_SIGNED:
1885	    case ARC_OPERAND_UNSIGNED:
1886	      switch (tok[tokidx].X_op)
1887		{
1888		case O_illegal:
1889		case O_absent:
1890		case O_register:
1891		  goto match_failed;
1892
1893		case O_bracket:
1894		  /* Got an (too) early bracket, check if it is an
1895		     ignored operand.  N.B. This procedure works only
1896		     when bracket is the last operand!  */
1897		  if (!(operand->flags & ARC_OPERAND_IGNORE))
1898		    goto match_failed;
1899		  /* Insert the missing operand.  */
1900		  if (!allocate_tok (tok, ntok - 1, tokidx))
1901		    goto match_failed;
1902
1903		  tok[tokidx].X_op = O_absent;
1904		  ++ntok;
1905		  break;
1906
1907		case O_symbol:
1908		  {
1909		    const char *p;
1910		    char *tmpp, *pp;
1911		    const struct arc_aux_reg *auxr;
1912
1913		    if (opcode->insn_class != AUXREG)
1914		      goto de_fault;
1915		    p = S_GET_NAME (tok[tokidx].X_add_symbol);
1916
1917		    /* For compatibility reasons, an aux register can
1918		       be spelled with upper or lower case
1919		       letters.  */
1920		    tmpp = strdup (p);
1921		    for (pp = tmpp; *pp; ++pp) *pp = TOLOWER (*pp);
1922
1923		    auxr = hash_find (arc_aux_hash, tmpp);
1924		    if (auxr)
1925		      {
1926			/* We modify the token array here, safe in the
1927			   knowledge, that if this was the wrong
1928			   choice then the original contents will be
1929			   restored from BKTOK.  */
1930			tok[tokidx].X_op = O_constant;
1931			tok[tokidx].X_add_number = auxr->address;
1932			ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX);
1933		      }
1934		    free (tmpp);
1935
1936		    if (tok[tokidx].X_op != O_constant)
1937		      goto de_fault;
1938		  }
1939		  /* Fall through.  */
1940		case O_constant:
1941		  /* Check the range.  */
1942		  if (operand->bits != 32
1943		      && !(operand->flags & ARC_OPERAND_NCHK))
1944		    {
1945		      offsetT min, max, val;
1946		      val = tok[tokidx].X_add_number;
1947
1948		      if (operand->flags & ARC_OPERAND_SIGNED)
1949			{
1950			  max = (1 << (operand->bits - 1)) - 1;
1951			  min = -(1 << (operand->bits - 1));
1952			}
1953		      else
1954			{
1955			  max = (1 << operand->bits) - 1;
1956			  min = 0;
1957			}
1958
1959		      if (val < min || val > max)
1960			goto match_failed;
1961
1962		      /* Check alignments.  */
1963		      if ((operand->flags & ARC_OPERAND_ALIGNED32)
1964			  && (val & 0x03))
1965			goto match_failed;
1966
1967		      if ((operand->flags & ARC_OPERAND_ALIGNED16)
1968			  && (val & 0x01))
1969			goto match_failed;
1970		    }
1971		  else if (operand->flags & ARC_OPERAND_NCHK)
1972		    {
1973		      if (operand->insert)
1974			{
1975			  *errmsg = NULL;
1976			  (*operand->insert)(0,
1977					     tok[tokidx].X_add_number,
1978					     errmsg);
1979			  if (*errmsg)
1980			    goto match_failed;
1981			}
1982		      else if (!(operand->flags & ARC_OPERAND_IGNORE))
1983			goto match_failed;
1984		    }
1985		  break;
1986
1987		case O_subtract:
1988		  /* Check if it is register range.  */
1989		  if ((tok[tokidx].X_add_number == 0)
1990		      && contains_register (tok[tokidx].X_add_symbol)
1991		      && contains_register (tok[tokidx].X_op_symbol))
1992		    {
1993		      int regs;
1994
1995		      regs = get_register (tok[tokidx].X_add_symbol);
1996		      regs <<= 16;
1997		      regs |= get_register (tok[tokidx].X_op_symbol);
1998		      if (operand->insert)
1999			{
2000			  *errmsg = NULL;
2001			  (*operand->insert)(0,
2002					     regs,
2003					     errmsg);
2004			  if (*errmsg)
2005			    goto match_failed;
2006			}
2007		      else
2008			goto match_failed;
2009		      break;
2010		    }
2011		  /* Fall through.  */
2012		default:
2013		de_fault:
2014		  if (operand->default_reloc == 0)
2015		    goto match_failed; /* The operand needs relocation.  */
2016
2017		  /* Relocs requiring long immediate.  FIXME! make it
2018		     generic and move it to a function.  */
2019		  switch (tok[tokidx].X_md)
2020		    {
2021		    case O_gotoff:
2022		    case O_gotpc:
2023		    case O_pcl:
2024		    case O_tpoff:
2025		    case O_dtpoff:
2026		    case O_tlsgd:
2027		    case O_tlsie:
2028		      if (!(operand->flags & ARC_OPERAND_LIMM))
2029			goto match_failed;
2030		      /* Fall through.  */
2031		    case O_absent:
2032		      if (!generic_reloc_p (operand->default_reloc))
2033			goto match_failed;
2034		      break;
2035		    default:
2036		      break;
2037		    }
2038		  break;
2039		}
2040	      /* If expect duplicate, make sure it is duplicate.  */
2041	      if (operand->flags & ARC_OPERAND_DUPLICATE)
2042		{
2043		  if (t->X_op == O_illegal
2044		      || t->X_op == O_absent
2045		      || t->X_op == O_register
2046		      || (t->X_add_number != tok[tokidx].X_add_number))
2047		    goto match_failed;
2048		}
2049	      t = &tok[tokidx];
2050	      break;
2051
2052	    default:
2053	      /* Everything else should have been fake.  */
2054	      abort ();
2055	    }
2056
2057	  ++tokidx;
2058	}
2059      pr_debug ("opr ");
2060
2061      /* Setup ready for flag parsing.  */
2062      if (!parse_opcode_flags (opcode, nflgs, first_pflag))
2063	goto match_failed;
2064
2065      pr_debug ("flg");
2066      /* Possible match -- did we use all of our input?  */
2067      if (tokidx == ntok)
2068	{
2069	  *pntok = ntok;
2070	  pr_debug ("\n");
2071	  return opcode;
2072	}
2073
2074    match_failed:;
2075      pr_debug ("\n");
2076      /* Restore the original parameters.  */
2077      memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
2078      ntok = bkntok;
2079    }
2080
2081  if (*pcpumatch)
2082    *pcpumatch = got_cpu_match;
2083
2084  return NULL;
2085}
2086
2087/* Swap operand tokens.  */
2088
2089static void
2090swap_operand (expressionS *operand_array,
2091	      unsigned source,
2092	      unsigned destination)
2093{
2094  expressionS cpy_operand;
2095  expressionS *src_operand;
2096  expressionS *dst_operand;
2097  size_t size;
2098
2099  if (source == destination)
2100    return;
2101
2102  src_operand = &operand_array[source];
2103  dst_operand = &operand_array[destination];
2104  size = sizeof (expressionS);
2105
2106  /* Make copy of operand to swap with and swap.  */
2107  memcpy (&cpy_operand, dst_operand, size);
2108  memcpy (dst_operand, src_operand, size);
2109  memcpy (src_operand, &cpy_operand, size);
2110}
2111
2112/* Check if *op matches *tok type.
2113   Returns FALSE if they don't match, TRUE if they match.  */
2114
2115static bfd_boolean
2116pseudo_operand_match (const expressionS *tok,
2117		      const struct arc_operand_operation *op)
2118{
2119  offsetT min, max, val;
2120  bfd_boolean ret;
2121  const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
2122
2123  ret = FALSE;
2124  switch (tok->X_op)
2125    {
2126    case O_constant:
2127      if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
2128	ret = 1;
2129      else if (!(operand_real->flags & ARC_OPERAND_IR))
2130	{
2131	  val = tok->X_add_number + op->count;
2132	  if (operand_real->flags & ARC_OPERAND_SIGNED)
2133	    {
2134	      max = (1 << (operand_real->bits - 1)) - 1;
2135	      min = -(1 << (operand_real->bits - 1));
2136	    }
2137	  else
2138	    {
2139	      max = (1 << operand_real->bits) - 1;
2140	      min = 0;
2141	    }
2142	  if (min <= val && val <= max)
2143	    ret = TRUE;
2144	}
2145      break;
2146
2147    case O_symbol:
2148      /* Handle all symbols as long immediates or signed 9.  */
2149      if (operand_real->flags & ARC_OPERAND_LIMM
2150	  || ((operand_real->flags & ARC_OPERAND_SIGNED)
2151	      && operand_real->bits == 9))
2152	ret = TRUE;
2153      break;
2154
2155    case O_register:
2156      if (operand_real->flags & ARC_OPERAND_IR)
2157	ret = TRUE;
2158      break;
2159
2160    case O_bracket:
2161      if (operand_real->flags & ARC_OPERAND_BRAKET)
2162	ret = TRUE;
2163      break;
2164
2165    default:
2166      /* Unknown.  */
2167      break;
2168    }
2169  return ret;
2170}
2171
2172/* Find pseudo instruction in array.  */
2173
2174static const struct arc_pseudo_insn *
2175find_pseudo_insn (const char *opname,
2176		  int ntok,
2177		  const expressionS *tok)
2178{
2179  const struct arc_pseudo_insn *pseudo_insn = NULL;
2180  const struct arc_operand_operation *op;
2181  unsigned int i;
2182  int j;
2183
2184  for (i = 0; i < arc_num_pseudo_insn; ++i)
2185    {
2186      pseudo_insn = &arc_pseudo_insns[i];
2187      if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
2188	{
2189	  op = pseudo_insn->operand;
2190	  for (j = 0; j < ntok; ++j)
2191	    if (!pseudo_operand_match (&tok[j], &op[j]))
2192	      break;
2193
2194	  /* Found the right instruction.  */
2195	  if (j == ntok)
2196	    return pseudo_insn;
2197	}
2198    }
2199  return NULL;
2200}
2201
2202/* Assumes the expressionS *tok is of sufficient size.  */
2203
2204static const struct arc_opcode_hash_entry *
2205find_special_case_pseudo (const char *opname,
2206			  int *ntok,
2207			  expressionS *tok,
2208			  int *nflgs,
2209			  struct arc_flags *pflags)
2210{
2211  const struct arc_pseudo_insn *pseudo_insn = NULL;
2212  const struct arc_operand_operation *operand_pseudo;
2213  const struct arc_operand *operand_real;
2214  unsigned i;
2215  char construct_operand[MAX_CONSTR_STR];
2216
2217  /* Find whether opname is in pseudo instruction array.  */
2218  pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
2219
2220  if (pseudo_insn == NULL)
2221    return NULL;
2222
2223  /* Handle flag, Limited to one flag at the moment.  */
2224  if (pseudo_insn->flag_r != NULL)
2225    *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
2226			      MAX_INSN_FLGS - *nflgs);
2227
2228  /* Handle operand operations.  */
2229  for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2230    {
2231      operand_pseudo = &pseudo_insn->operand[i];
2232      operand_real = &arc_operands[operand_pseudo->operand_idx];
2233
2234      if (operand_real->flags & ARC_OPERAND_BRAKET
2235	  && !operand_pseudo->needs_insert)
2236	continue;
2237
2238      /* Has to be inserted (i.e. this token does not exist yet).  */
2239      if (operand_pseudo->needs_insert)
2240	{
2241	  if (operand_real->flags & ARC_OPERAND_BRAKET)
2242	    {
2243	      tok[i].X_op = O_bracket;
2244	      ++(*ntok);
2245	      continue;
2246	    }
2247
2248	  /* Check if operand is a register or constant and handle it
2249	     by type.  */
2250	  if (operand_real->flags & ARC_OPERAND_IR)
2251	    snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
2252		      operand_pseudo->count);
2253	  else
2254	    snprintf (construct_operand, MAX_CONSTR_STR, "%d",
2255		      operand_pseudo->count);
2256
2257	  tokenize_arguments (construct_operand, &tok[i], 1);
2258	  ++(*ntok);
2259	}
2260
2261      else if (operand_pseudo->count)
2262	{
2263	  /* Operand number has to be adjusted accordingly (by operand
2264	     type).  */
2265	  switch (tok[i].X_op)
2266	    {
2267	    case O_constant:
2268	      tok[i].X_add_number += operand_pseudo->count;
2269	      break;
2270
2271	    case O_symbol:
2272	      break;
2273
2274	    default:
2275	      /* Ignored.  */
2276	      break;
2277	    }
2278	}
2279    }
2280
2281  /* Swap operands if necessary.  Only supports one swap at the
2282     moment.  */
2283  for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2284    {
2285      operand_pseudo = &pseudo_insn->operand[i];
2286
2287      if (operand_pseudo->swap_operand_idx == i)
2288	continue;
2289
2290      swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2291
2292      /* Prevent a swap back later by breaking out.  */
2293      break;
2294    }
2295
2296  return arc_find_opcode (pseudo_insn->mnemonic_r);
2297}
2298
2299static const struct arc_opcode_hash_entry *
2300find_special_case_flag (const char *opname,
2301			int *nflgs,
2302			struct arc_flags *pflags)
2303{
2304  unsigned int i;
2305  const char *flagnm;
2306  unsigned flag_idx, flag_arr_idx;
2307  size_t flaglen, oplen;
2308  const struct arc_flag_special *arc_flag_special_opcode;
2309  const struct arc_opcode_hash_entry *entry;
2310
2311  /* Search for special case instruction.  */
2312  for (i = 0; i < arc_num_flag_special; i++)
2313    {
2314      arc_flag_special_opcode = &arc_flag_special_cases[i];
2315      oplen = strlen (arc_flag_special_opcode->name);
2316
2317      if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2318	continue;
2319
2320      /* Found a potential special case instruction, now test for
2321	 flags.  */
2322      for (flag_arr_idx = 0;; ++flag_arr_idx)
2323	{
2324	  flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2325	  if (flag_idx == 0)
2326	    break;  /* End of array, nothing found.  */
2327
2328	  flagnm = arc_flag_operands[flag_idx].name;
2329	  flaglen = strlen (flagnm);
2330	  if (strcmp (opname + oplen, flagnm) == 0)
2331	    {
2332              entry = arc_find_opcode (arc_flag_special_opcode->name);
2333
2334	      if (*nflgs + 1 > MAX_INSN_FLGS)
2335		break;
2336	      memcpy (pflags[*nflgs].name, flagnm, flaglen);
2337	      pflags[*nflgs].name[flaglen] = '\0';
2338	      (*nflgs)++;
2339	      return entry;
2340	    }
2341	}
2342    }
2343  return NULL;
2344}
2345
2346/* Used to find special case opcode.  */
2347
2348static const struct arc_opcode_hash_entry *
2349find_special_case (const char *opname,
2350		   int *nflgs,
2351		   struct arc_flags *pflags,
2352		   expressionS *tok,
2353		   int *ntok)
2354{
2355  const struct arc_opcode_hash_entry *entry;
2356
2357  entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
2358
2359  if (entry == NULL)
2360    entry = find_special_case_flag (opname, nflgs, pflags);
2361
2362  return entry;
2363}
2364
2365/* Autodetect cpu attribute list.  */
2366
2367static void
2368autodetect_attributes (const struct arc_opcode *opcode,
2369			 const expressionS *tok,
2370			 int ntok)
2371{
2372  unsigned i;
2373  struct mpy_type
2374  {
2375    unsigned feature;
2376    unsigned encoding;
2377  } mpy_list[] = {{ MPY1E, 1 }, { MPY6E, 6 }, { MPY7E, 7 }, { MPY8E, 8 },
2378		 { MPY9E, 9 }};
2379
2380  for (i = 0; i < ARRAY_SIZE (feature_list); i++)
2381    if (opcode->subclass == feature_list[i].feature)
2382      selected_cpu.features |= feature_list[i].feature;
2383
2384  for (i = 0; i < ARRAY_SIZE (mpy_list); i++)
2385    if (opcode->subclass == mpy_list[i].feature)
2386      mpy_option = mpy_list[i].encoding;
2387
2388  for (i = 0; i < (unsigned) ntok; i++)
2389    {
2390      switch (tok[i].X_md)
2391	{
2392	case O_gotoff:
2393	case O_gotpc:
2394	case O_plt:
2395	  pic_option = 2;
2396	  break;
2397	case O_sda:
2398	  sda_option = 2;
2399	  break;
2400	case O_tlsgd:
2401	case O_tlsie:
2402	case O_tpoff9:
2403	case O_tpoff:
2404	case O_dtpoff9:
2405	case O_dtpoff:
2406	  tls_option = 1;
2407	  break;
2408	default:
2409	  break;
2410	}
2411
2412      switch (tok[i].X_op)
2413	{
2414	case O_register:
2415	  if ((tok[i].X_add_number >= 4 && tok[i].X_add_number <= 9)
2416	      || (tok[i].X_add_number >= 16 && tok[i].X_add_number <= 25))
2417	    rf16_only = FALSE;
2418	  break;
2419	default:
2420	  break;
2421	}
2422    }
2423}
2424
2425/* Given an opcode name, pre-tockenized set of argumenst and the
2426   opcode flags, take it all the way through emission.  */
2427
2428static void
2429assemble_tokens (const char *opname,
2430		 expressionS *tok,
2431		 int ntok,
2432		 struct arc_flags *pflags,
2433		 int nflgs)
2434{
2435  bfd_boolean found_something = FALSE;
2436  const struct arc_opcode_hash_entry *entry;
2437  int cpumatch = 1;
2438  const char *errmsg = NULL;
2439
2440  /* Search opcodes.  */
2441  entry = arc_find_opcode (opname);
2442
2443  /* Couldn't find opcode conventional way, try special cases.  */
2444  if (entry == NULL)
2445    entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
2446
2447  if (entry != NULL)
2448    {
2449      const struct arc_opcode *opcode;
2450
2451      pr_debug ("%s:%d: assemble_tokens: %s\n",
2452		frag_now->fr_file, frag_now->fr_line, opname);
2453      found_something = TRUE;
2454      opcode = find_opcode_match (entry, tok, &ntok, pflags,
2455				  nflgs, &cpumatch, &errmsg);
2456      if (opcode != NULL)
2457	{
2458	  struct arc_insn insn;
2459
2460	  autodetect_attributes (opcode,  tok, ntok);
2461	  assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
2462	  emit_insn (&insn);
2463	  return;
2464	}
2465    }
2466
2467  if (found_something)
2468    {
2469      if (cpumatch)
2470	if (errmsg)
2471	  as_bad (_("%s for instruction '%s'"), errmsg, opname);
2472	else
2473	  as_bad (_("inappropriate arguments for opcode '%s'"), opname);
2474      else
2475	as_bad (_("opcode '%s' not supported for target %s"), opname,
2476		selected_cpu.name);
2477    }
2478  else
2479    as_bad (_("unknown opcode '%s'"), opname);
2480}
2481
2482/* The public interface to the instruction assembler.  */
2483
2484void
2485md_assemble (char *str)
2486{
2487  char *opname;
2488  expressionS tok[MAX_INSN_ARGS];
2489  int ntok, nflg;
2490  size_t opnamelen;
2491  struct arc_flags flags[MAX_INSN_FLGS];
2492
2493  /* Split off the opcode.  */
2494  opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
2495  opname = xmemdup0 (str, opnamelen);
2496
2497  /* Signalize we are assembling the instructions.  */
2498  assembling_insn = TRUE;
2499
2500  /* Tokenize the flags.  */
2501  if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2502    {
2503      as_bad (_("syntax error"));
2504      return;
2505    }
2506
2507  /* Scan up to the end of the mnemonic which must end in space or end
2508     of string.  */
2509  str += opnamelen;
2510  for (; *str != '\0'; str++)
2511    if (*str == ' ')
2512      break;
2513
2514  /* Tokenize the rest of the line.  */
2515  if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2516    {
2517      as_bad (_("syntax error"));
2518      return;
2519    }
2520
2521  /* Finish it off.  */
2522  assemble_tokens (opname, tok, ntok, flags, nflg);
2523  assembling_insn = FALSE;
2524}
2525
2526/* Callback to insert a register into the hash table.  */
2527
2528static void
2529declare_register (const char *name, int number)
2530{
2531  const char *err;
2532  symbolS *regS = symbol_create (name, reg_section,
2533				 number, &zero_address_frag);
2534
2535  err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
2536  if (err)
2537    as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2538	      name, err);
2539}
2540
2541/* Construct symbols for each of the general registers.  */
2542
2543static void
2544declare_register_set (void)
2545{
2546  int i;
2547  for (i = 0; i < 64; ++i)
2548    {
2549      char name[7];
2550
2551      sprintf (name, "r%d", i);
2552      declare_register (name, i);
2553      if ((i & 0x01) == 0)
2554	{
2555	  sprintf (name, "r%dr%d", i, i+1);
2556	  declare_register (name, i);
2557	}
2558    }
2559}
2560
2561/* Construct a symbol for an address type.  */
2562
2563static void
2564declare_addrtype (const char *name, int number)
2565{
2566  const char *err;
2567  symbolS *addrtypeS = symbol_create (name, undefined_section,
2568                                      number, &zero_address_frag);
2569
2570  err = hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS),
2571                     (void *) addrtypeS);
2572  if (err)
2573    as_fatal (_("Inserting \"%s\" into address type table failed: %s"),
2574              name, err);
2575}
2576
2577/* Port-specific assembler initialization.  This function is called
2578   once, at assembler startup time.  */
2579
2580void
2581md_begin (void)
2582{
2583  const struct arc_opcode *opcode = arc_opcodes;
2584
2585  if (mach_selection_mode == MACH_SELECTION_NONE)
2586    arc_select_cpu (TARGET_WITH_CPU, MACH_SELECTION_FROM_DEFAULT);
2587
2588  /* The endianness can be chosen "at the factory".  */
2589  target_big_endian = byte_order == BIG_ENDIAN;
2590
2591  if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
2592    as_warn (_("could not set architecture and machine"));
2593
2594  /* Set elf header flags.  */
2595  bfd_set_private_flags (stdoutput, selected_cpu.eflags);
2596
2597  /* Set up a hash table for the instructions.  */
2598  arc_opcode_hash = hash_new ();
2599  if (arc_opcode_hash == NULL)
2600    as_fatal (_("Virtual memory exhausted"));
2601
2602  /* Initialize the hash table with the insns.  */
2603  do
2604    {
2605      const char *name = opcode->name;
2606
2607      arc_insert_opcode (opcode);
2608
2609      while (++opcode && opcode->name
2610	     && (opcode->name == name
2611		 || !strcmp (opcode->name, name)))
2612	continue;
2613    }while (opcode->name);
2614
2615  /* Register declaration.  */
2616  arc_reg_hash = hash_new ();
2617  if (arc_reg_hash == NULL)
2618    as_fatal (_("Virtual memory exhausted"));
2619
2620  declare_register_set ();
2621  declare_register ("gp", 26);
2622  declare_register ("fp", 27);
2623  declare_register ("sp", 28);
2624  declare_register ("ilink", 29);
2625  declare_register ("ilink1", 29);
2626  declare_register ("ilink2", 30);
2627  declare_register ("blink", 31);
2628
2629  /* XY memory registers.  */
2630  declare_register ("x0_u0", 32);
2631  declare_register ("x0_u1", 33);
2632  declare_register ("x1_u0", 34);
2633  declare_register ("x1_u1", 35);
2634  declare_register ("x2_u0", 36);
2635  declare_register ("x2_u1", 37);
2636  declare_register ("x3_u0", 38);
2637  declare_register ("x3_u1", 39);
2638  declare_register ("y0_u0", 40);
2639  declare_register ("y0_u1", 41);
2640  declare_register ("y1_u0", 42);
2641  declare_register ("y1_u1", 43);
2642  declare_register ("y2_u0", 44);
2643  declare_register ("y2_u1", 45);
2644  declare_register ("y3_u0", 46);
2645  declare_register ("y3_u1", 47);
2646  declare_register ("x0_nu", 48);
2647  declare_register ("x1_nu", 49);
2648  declare_register ("x2_nu", 50);
2649  declare_register ("x3_nu", 51);
2650  declare_register ("y0_nu", 52);
2651  declare_register ("y1_nu", 53);
2652  declare_register ("y2_nu", 54);
2653  declare_register ("y3_nu", 55);
2654
2655  declare_register ("mlo", 57);
2656  declare_register ("mmid", 58);
2657  declare_register ("mhi", 59);
2658
2659  declare_register ("acc1", 56);
2660  declare_register ("acc2", 57);
2661
2662  declare_register ("lp_count", 60);
2663  declare_register ("pcl", 63);
2664
2665  /* Initialize the last instructions.  */
2666  memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2667
2668  /* Aux register declaration.  */
2669  arc_aux_hash = hash_new ();
2670  if (arc_aux_hash == NULL)
2671    as_fatal (_("Virtual memory exhausted"));
2672
2673  const struct arc_aux_reg *auxr = &arc_aux_regs[0];
2674  unsigned int i;
2675  for (i = 0; i < arc_num_aux_regs; i++, auxr++)
2676    {
2677      const char *retval;
2678
2679      if (!(auxr->cpu & selected_cpu.flags))
2680	continue;
2681
2682      if ((auxr->subclass != NONE)
2683	  && !check_cpu_feature (auxr->subclass))
2684	continue;
2685
2686      retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr);
2687      if (retval)
2688	as_fatal (_("internal error: can't hash aux register '%s': %s"),
2689		  auxr->name, retval);
2690    }
2691
2692  /* Address type declaration.  */
2693  arc_addrtype_hash = hash_new ();
2694  if (arc_addrtype_hash == NULL)
2695    as_fatal (_("Virtual memory exhausted"));
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				   (valueT) 0, &zero_address_frag);
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 = 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 = 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 = 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  const char *retval;
4863  struct arc_flag_operand *ccode;
4864
4865  memset (&ereg, 0, sizeof (ereg));
4866  if (!tokenize_extregister (&ereg, opertype))
4867    return;
4868
4869  switch (opertype)
4870    {
4871    case EXT_CORE_REGISTER:
4872      /* Core register.  */
4873      if (ereg.number > 60)
4874	as_bad (_("core register %s value (%d) too large"), ereg.name,
4875		ereg.number);
4876      declare_register (ereg.name, ereg.number);
4877      break;
4878    case EXT_AUX_REGISTER:
4879      /* Auxiliary register.  */
4880      auxr = XNEW (struct arc_aux_reg);
4881      auxr->name = ereg.name;
4882      auxr->cpu = selected_cpu.flags;
4883      auxr->subclass = NONE;
4884      auxr->address = ereg.number;
4885      retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr);
4886      if (retval)
4887	as_fatal (_("internal error: can't hash aux register '%s': %s"),
4888		  auxr->name, retval);
4889      break;
4890    case EXT_COND_CODE:
4891      /* Condition code.  */
4892      if (ereg.number > 31)
4893	as_bad (_("condition code %s value (%d) too large"), ereg.name,
4894		ereg.number);
4895      ext_condcode.size ++;
4896      ext_condcode.arc_ext_condcode =
4897	XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode,
4898		    ext_condcode.size + 1);
4899      if (ext_condcode.arc_ext_condcode == NULL)
4900	as_fatal (_("Virtual memory exhausted"));
4901
4902      ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1;
4903      ccode->name   = ereg.name;
4904      ccode->code   = ereg.number;
4905      ccode->bits   = 5;
4906      ccode->shift  = 0;
4907      ccode->favail = 0; /* not used.  */
4908      ccode++;
4909      memset (ccode, 0, sizeof (struct arc_flag_operand));
4910      break;
4911    default:
4912      as_bad (_("Unknown extension"));
4913      break;
4914    }
4915  create_extcore_section (&ereg, opertype);
4916}
4917
4918/* Parse a .arc_attribute directive.  */
4919
4920static void
4921arc_attribute (int ignored ATTRIBUTE_UNUSED)
4922{
4923  int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
4924
4925  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
4926    attributes_set_explicitly[tag] = TRUE;
4927}
4928
4929/* Set an attribute if it has not already been set by the user.  */
4930
4931static void
4932arc_set_attribute_int (int tag, int value)
4933{
4934  if (tag < 1
4935      || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
4936      || !attributes_set_explicitly[tag])
4937    bfd_elf_add_proc_attr_int (stdoutput, tag, value);
4938}
4939
4940static void
4941arc_set_attribute_string (int tag, const char *value)
4942{
4943  if (tag < 1
4944      || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
4945      || !attributes_set_explicitly[tag])
4946    bfd_elf_add_proc_attr_string (stdoutput, tag, value);
4947}
4948
4949/* Allocate and concatenate two strings.  s1 can be NULL but not
4950   s2.  s1 pointer is freed at end of this procedure.  */
4951
4952static char *
4953arc_stralloc (char * s1, const char * s2)
4954{
4955  char * p;
4956  int len = 0;
4957
4958  if (s1)
4959    len = strlen (s1) + 1;
4960
4961  /* Only s1 can be null.  */
4962  gas_assert (s2);
4963  len += strlen (s2) + 1;
4964
4965  p = (char *) xmalloc (len);
4966  if (p == NULL)
4967    as_fatal (_("Virtual memory exhausted"));
4968
4969  if (s1)
4970    {
4971      strcpy (p, s1);
4972      strcat (p, ",");
4973      strcat (p, s2);
4974      free (s1);
4975    }
4976  else
4977    strcpy (p, s2);
4978
4979  return p;
4980}
4981
4982/* Set the public ARC object attributes.  */
4983
4984static void
4985arc_set_public_attributes (void)
4986{
4987  int base = 0;
4988  char *s = NULL;
4989  unsigned int i;
4990
4991  /* Tag_ARC_CPU_name.  */
4992  arc_set_attribute_string (Tag_ARC_CPU_name, selected_cpu.name);
4993
4994  /* Tag_ARC_CPU_base.  */
4995  switch (selected_cpu.eflags & EF_ARC_MACH_MSK)
4996    {
4997    case E_ARC_MACH_ARC600:
4998    case E_ARC_MACH_ARC601:
4999      base = TAG_CPU_ARC6xx;
5000      break;
5001    case E_ARC_MACH_ARC700:
5002      base = TAG_CPU_ARC7xx;
5003      break;
5004    case EF_ARC_CPU_ARCV2EM:
5005      base = TAG_CPU_ARCEM;
5006      break;
5007    case EF_ARC_CPU_ARCV2HS:
5008      base = TAG_CPU_ARCHS;
5009      break;
5010    default:
5011      base = 0;
5012      break;
5013    }
5014  if (attributes_set_explicitly[Tag_ARC_CPU_base]
5015      && (base != bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5016					    Tag_ARC_CPU_base)))
5017    as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
5018  bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_CPU_base, base);
5019
5020  /* Tag_ARC_ABI_osver.  */
5021  if (attributes_set_explicitly[Tag_ARC_ABI_osver])
5022    {
5023      int val = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5024					  Tag_ARC_ABI_osver);
5025
5026      selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_OSABI_MSK)
5027			     | (val & 0x0f << 8));
5028    }
5029  else
5030    {
5031      arc_set_attribute_int (Tag_ARC_ABI_osver, E_ARC_OSABI_CURRENT >> 8);
5032    }
5033
5034  /* Tag_ARC_ISA_config.  */
5035  arc_check_feature();
5036
5037  for (i = 0; i < ARRAY_SIZE (feature_list); i++)
5038    if (selected_cpu.features & feature_list[i].feature)
5039      s = arc_stralloc (s, feature_list[i].attr);
5040
5041  if (s)
5042    arc_set_attribute_string (Tag_ARC_ISA_config, s);
5043
5044  /* Tag_ARC_ISA_mpy_option.  */
5045  arc_set_attribute_int (Tag_ARC_ISA_mpy_option, mpy_option);
5046
5047  /* Tag_ARC_ABI_pic.  */
5048  arc_set_attribute_int (Tag_ARC_ABI_pic, pic_option);
5049
5050  /* Tag_ARC_ABI_sda.  */
5051  arc_set_attribute_int (Tag_ARC_ABI_sda, sda_option);
5052
5053  /* Tag_ARC_ABI_tls.  */
5054  arc_set_attribute_int (Tag_ARC_ABI_tls, tls_option);
5055
5056  /* Tag_ARC_ATR_version.  */
5057  arc_set_attribute_int (Tag_ARC_ATR_version, 1);
5058
5059  /* Tag_ARC_ABI_rf16.  */
5060  if (attributes_set_explicitly[Tag_ARC_ABI_rf16]
5061      && bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5062				   Tag_ARC_ABI_rf16)
5063      && !rf16_only)
5064    {
5065      as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full "
5066		 "register file"));
5067      bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_ABI_rf16, 0);
5068    }
5069}
5070
5071/* Add the default contents for the .ARC.attributes section.  */
5072
5073void
5074arc_md_end (void)
5075{
5076  arc_set_public_attributes ();
5077
5078  if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
5079    as_fatal (_("could not set architecture and machine"));
5080
5081  bfd_set_private_flags (stdoutput, selected_cpu.eflags);
5082}
5083
5084void arc_copy_symbol_attributes (symbolS *dest, symbolS *src)
5085{
5086  ARC_GET_FLAG (dest) = ARC_GET_FLAG (src);
5087}
5088
5089int arc_convert_symbolic_attribute (const char *name)
5090{
5091  static const struct
5092  {
5093    const char * name;
5094    const int    tag;
5095  }
5096  attribute_table[] =
5097    {
5098#define T(tag) {#tag, tag}
5099  T (Tag_ARC_PCS_config),
5100  T (Tag_ARC_CPU_base),
5101  T (Tag_ARC_CPU_variation),
5102  T (Tag_ARC_CPU_name),
5103  T (Tag_ARC_ABI_rf16),
5104  T (Tag_ARC_ABI_osver),
5105  T (Tag_ARC_ABI_sda),
5106  T (Tag_ARC_ABI_pic),
5107  T (Tag_ARC_ABI_tls),
5108  T (Tag_ARC_ABI_enumsize),
5109  T (Tag_ARC_ABI_exceptions),
5110  T (Tag_ARC_ABI_double_size),
5111  T (Tag_ARC_ISA_config),
5112  T (Tag_ARC_ISA_apex),
5113  T (Tag_ARC_ISA_mpy_option),
5114  T (Tag_ARC_ATR_version)
5115#undef T
5116    };
5117  unsigned int i;
5118
5119  if (name == NULL)
5120    return -1;
5121
5122  for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
5123    if (streq (name, attribute_table[i].name))
5124      return attribute_table[i].tag;
5125
5126  return -1;
5127}
5128
5129/* Local variables:
5130   eval: (c-set-style "gnu")
5131   indent-tabs-mode: t
5132   End:  */
5133