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