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