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