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