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