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