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