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