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