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