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