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