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