Copyright update for binutils
[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,        0),
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       fixP->fx_offset = 0;
1305       /* Fall through.  */
1306     case BFD_RELOC_ARC_TLS_GD_GOT:
1307     case BFD_RELOC_ARC_TLS_IE_GOT:
1308       S_SET_THREAD_LOCAL (fixP->fx_addsy);
1309       break;
1310
1311     case BFD_RELOC_ARC_TLS_GD_LD:
1312       gas_assert (!fixP->fx_offset);
1313       if (fixP->fx_subsy)
1314         fixP->fx_offset
1315           = (S_GET_VALUE (fixP->fx_subsy)
1316              - fixP->fx_frag->fr_address- fixP->fx_where);
1317       fixP->fx_subsy = NULL;
1318       /* Fall through.  */
1319     case BFD_RELOC_ARC_TLS_GD_CALL:
1320       /* These two relocs are there just to allow ld to change the tls
1321          model for this symbol, by patching the code.  The offset -
1322          and scale, if any - will be installed by the linker.  */
1323       S_SET_THREAD_LOCAL (fixP->fx_addsy);
1324       break;
1325
1326     case BFD_RELOC_ARC_TLS_LE_S9:
1327     case BFD_RELOC_ARC_TLS_DTPOFF_S9:
1328       as_bad (_("TLS_*_S9 relocs are not supported yet"));
1329       break;
1330
1331     default:
1332       break;
1333     }
1334
1335   if (!fixP->fx_done)
1336     {
1337       return;
1338     }
1339
1340   /* Addjust the value if we have a constant.  */
1341   value += fx_offset;
1342
1343   /* For hosts with longs bigger than 32-bits make sure that the top
1344      bits of a 32-bit negative value read in by the parser are set,
1345      so that the correct comparisons are made.  */
1346   if (value & 0x80000000)
1347     value |= (-1L << 31);
1348
1349   reloc = fixP->fx_r_type;
1350   switch (reloc)
1351     {
1352     case BFD_RELOC_8:
1353     case BFD_RELOC_16:
1354     case BFD_RELOC_24:
1355     case BFD_RELOC_32:
1356     case BFD_RELOC_64:
1357     case BFD_RELOC_ARC_32_PCREL:
1358       md_number_to_chars (fixpos, value, fixP->fx_size);
1359       return;
1360
1361     case BFD_RELOC_ARC_GOTPC32:
1362       /* I cannot fix an GOTPC relocation because I need to relax it
1363          from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc.  */
1364       as_bad (_("Unsupported operation on reloc"));
1365       return;
1366     case BFD_RELOC_ARC_GOTOFF:
1367     case BFD_RELOC_ARC_32_ME:
1368     case BFD_RELOC_ARC_PC32:
1369       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
1370       return;
1371
1372     case BFD_RELOC_ARC_PLT32:
1373       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
1374       return;
1375
1376     case BFD_RELOC_ARC_S25H_PCREL_PLT:
1377       reloc = BFD_RELOC_ARC_S25W_PCREL;
1378       goto solve_plt;
1379
1380     case BFD_RELOC_ARC_S21H_PCREL_PLT:
1381       reloc = BFD_RELOC_ARC_S21H_PCREL;
1382       goto solve_plt;
1383
1384     case BFD_RELOC_ARC_S25W_PCREL_PLT:
1385       reloc = BFD_RELOC_ARC_S25W_PCREL;
1386       goto solve_plt;
1387
1388     case BFD_RELOC_ARC_S21W_PCREL_PLT:
1389       reloc = BFD_RELOC_ARC_S21W_PCREL;
1390
1391     case BFD_RELOC_ARC_S25W_PCREL:
1392     case BFD_RELOC_ARC_S21W_PCREL:
1393     case BFD_RELOC_ARC_S21H_PCREL:
1394     case BFD_RELOC_ARC_S25H_PCREL:
1395     case BFD_RELOC_ARC_S13_PCREL:
1396     solve_plt:
1397       operand = find_operand_for_reloc (reloc);
1398       gas_assert (operand);
1399       break;
1400
1401     default:
1402       {
1403         if ((int) fixP->fx_r_type >= 0)
1404           as_fatal (_("unhandled relocation type %s"),
1405                     bfd_get_reloc_code_name (fixP->fx_r_type));
1406
1407         /* The rest of these fixups needs to be completely resolved as
1408            constants.  */
1409         if (fixP->fx_addsy != 0
1410             && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1411           as_bad_where (fixP->fx_file, fixP->fx_line,
1412                         _("non-absolute expression in constant field"));
1413
1414         gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
1415         operand = &arc_operands[-(int) fixP->fx_r_type];
1416         break;
1417       }
1418     }
1419
1420   if (target_big_endian)
1421     {
1422       switch (fixP->fx_size)
1423         {
1424         case 4:
1425           insn = bfd_getb32 (fixpos);
1426           break;
1427         case 2:
1428           insn = bfd_getb16 (fixpos);
1429           break;
1430         default:
1431           as_bad_where (fixP->fx_file, fixP->fx_line,
1432                         _("unknown fixup size"));
1433         }
1434     }
1435   else
1436     {
1437       insn = 0;
1438       switch (fixP->fx_size)
1439         {
1440         case 4:
1441           insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
1442           break;
1443         case 2:
1444           insn = bfd_getl16 (fixpos);
1445           break;
1446         default:
1447           as_bad_where (fixP->fx_file, fixP->fx_line,
1448                         _("unknown fixup size"));
1449         }
1450     }
1451
1452   insn = insert_operand (insn, operand, (offsetT) value,
1453                          fixP->fx_file, fixP->fx_line);
1454
1455   md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
1456 }
1457
1458 /* Prepare machine-dependent frags for relaxation.
1459
1460    Called just before relaxation starts.  Any symbol that is now undefined
1461    will not become defined.
1462
1463    Return the correct fr_subtype in the frag.
1464
1465    Return the initial "guess for fr_var" to caller.  The guess for fr_var
1466    is *actually* the growth beyond fr_fix.  Whatever we do to grow fr_fix
1467    or fr_var contributes to our returned value.
1468
1469    Although it may not be explicit in the frag, pretend
1470    fr_var starts with a value.  */
1471
1472 int
1473 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1474                                segT segment ATTRIBUTE_UNUSED)
1475 {
1476   int growth = 4;
1477
1478   fragP->fr_var = 4;
1479   pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
1480            fragP->fr_file, fragP->fr_line, growth);
1481
1482   as_fatal (_("md_estimate_size_before_relax\n"));
1483   return growth;
1484 }
1485
1486 /* Translate internal representation of relocation info to BFD target
1487    format.  */
1488
1489 arelent *
1490 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1491               fixS *fixP)
1492 {
1493   arelent *reloc;
1494   bfd_reloc_code_real_type code;
1495
1496   reloc = (arelent *) xmalloc (sizeof (* reloc));
1497   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1498   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1499   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1500
1501   /* Make sure none of our internal relocations make it this far.
1502      They'd better have been fully resolved by this point.  */
1503   gas_assert ((int) fixP->fx_r_type > 0);
1504
1505   code = fixP->fx_r_type;
1506
1507   /* if we have something like add gp, pcl,
1508      _GLOBAL_OFFSET_TABLE_@gotpc.  */
1509   if (code == BFD_RELOC_ARC_GOTPC32
1510       && GOT_symbol
1511       && fixP->fx_addsy == GOT_symbol)
1512     code = BFD_RELOC_ARC_GOTPC;
1513
1514   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1515   if (reloc->howto == NULL)
1516     {
1517       as_bad_where (fixP->fx_file, fixP->fx_line,
1518                     _("cannot represent `%s' relocation in object file"),
1519                     bfd_get_reloc_code_name (code));
1520       return NULL;
1521     }
1522
1523   if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
1524     as_fatal (_("internal error? cannot generate `%s' relocation"),
1525               bfd_get_reloc_code_name (code));
1526
1527   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1528
1529   if (code == BFD_RELOC_ARC_TLS_DTPOFF
1530       || code ==  BFD_RELOC_ARC_TLS_DTPOFF_S9)
1531     {
1532       asymbol *sym
1533         = fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL;
1534       /* We just want to store a 24 bit index, but we have to wait
1535          till after write_contents has been called via
1536          bfd_map_over_sections before we can get the index from
1537          _bfd_elf_symbol_from_bfd_symbol.  Thus, the write_relocs
1538          function is elf32-arc.c has to pick up the slack.
1539          Unfortunately, this leads to problems with hosts that have
1540          pointers wider than long (bfd_vma).  There would be various
1541          ways to handle this, all error-prone :-(  */
1542       reloc->addend = (bfd_vma) sym;
1543       if ((asymbol *) reloc->addend != sym)
1544         {
1545           as_bad ("Can't store pointer\n");
1546           return NULL;
1547         }
1548     }
1549   else
1550     reloc->addend = fixP->fx_offset;
1551
1552   return reloc;
1553 }
1554
1555 /* Perform post-processing of machine-dependent frags after relaxation.
1556    Called after relaxation is finished.
1557    In:  Address of frag.
1558    fr_type == rs_machine_dependent.
1559    fr_subtype is what the address relaxed to.
1560
1561    Out: Any fixS:s and constants are set up.  */
1562
1563 void
1564 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1565                  segT segment ATTRIBUTE_UNUSED,
1566                  fragS *fragP ATTRIBUTE_UNUSED)
1567 {
1568   pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
1569             fragP->fr_file, fragP->fr_line,
1570             fragP->fr_subtype, fragP->fr_fix, fragP->fr_var);
1571   abort ();
1572 }
1573
1574 /* We have no need to default values of symbols.  We could catch
1575    register names here, but that is handled by inserting them all in
1576    the symbol table to begin with.  */
1577
1578 symbolS *
1579 md_undefined_symbol (char *name)
1580 {
1581   /* The arc abi demands that a GOT[0] should be referencible as
1582      [pc+_DYNAMIC@gotpc].  Hence we convert a _DYNAMIC@gotpc to a
1583      GOTPC reference to _GLOBAL_OFFSET_TABLE_.  */
1584   if (((*name == '_')
1585        && (*(name+1) == 'G')
1586        && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))
1587       || ((*name == '_')
1588           && (*(name+1) == 'D')
1589           && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0)))
1590     {
1591       if (!GOT_symbol)
1592         {
1593           if (symbol_find (name))
1594             as_bad ("GOT already in symbol table");
1595
1596           GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
1597                                    (valueT) 0, &zero_address_frag);
1598         };
1599       return GOT_symbol;
1600     }
1601   return NULL;
1602 }
1603
1604 /* Turn a string in input_line_pointer into a floating point constant
1605    of type type, and store the appropriate bytes in *litP.  The number
1606    of LITTLENUMS emitted is stored in *sizeP.  An error message is
1607    returned, or NULL on OK.  */
1608
1609 char *
1610 md_atof (int type, char *litP, int *sizeP)
1611 {
1612   return ieee_md_atof (type, litP, sizeP, target_big_endian);
1613 }
1614
1615 /* Called for any expression that can not be recognized.  When the
1616    function is called, `input_line_pointer' will point to the start of
1617    the expression.  */
1618
1619 void
1620 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1621 {
1622   char *p = input_line_pointer;
1623   if (*p == '@')
1624     {
1625       input_line_pointer++;
1626       expressionP->X_op = O_symbol;
1627       expression (expressionP);
1628     }
1629 }
1630
1631 /* This function is called from the function 'expression', it attempts
1632    to parse special names (in our case register names).  It fills in
1633    the expression with the identified register.  It returns TRUE if
1634    it is a register and FALSE otherwise.  */
1635
1636 bfd_boolean
1637 arc_parse_name (const char *name,
1638                 struct expressionS *e)
1639 {
1640   struct symbol *sym;
1641
1642   if (!assembling_insn)
1643     return FALSE;
1644
1645   /* Handle only registers.  */
1646   if (e->X_op != O_absent)
1647     return FALSE;
1648
1649   sym = hash_find (arc_reg_hash, name);
1650   if (sym)
1651     {
1652       e->X_op = O_register;
1653       e->X_add_number = S_GET_VALUE (sym);
1654       return TRUE;
1655     }
1656   return FALSE;
1657 }
1658
1659 /* md_parse_option
1660    Invocation line includes a switch not recognized by the base assembler.
1661    See if it's a processor-specific option.
1662
1663    New options (supported) are:
1664
1665    -mcpu=<cpu name>              Assemble for selected processor
1666    -EB/-mbig-endian              Big-endian
1667    -EL/-mlittle-endian           Little-endian
1668
1669    The following CPU names are recognized:
1670    arc700, av2em, av2hs.  */
1671
1672 int
1673 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
1674 {
1675   int cpu_flags = EF_ARC_CPU_GENERIC;
1676
1677   switch (c)
1678     {
1679     case OPTION_ARC600:
1680     case OPTION_ARC601:
1681       return md_parse_option (OPTION_MCPU, "arc600");
1682
1683     case OPTION_ARC700:
1684       return md_parse_option (OPTION_MCPU, "arc700");
1685
1686     case OPTION_ARCEM:
1687       return md_parse_option (OPTION_MCPU, "arcem");
1688
1689     case OPTION_ARCHS:
1690       return md_parse_option (OPTION_MCPU, "archs");
1691
1692     case OPTION_MCPU:
1693       {
1694         int i;
1695         char *s = alloca (strlen (arg) + 1);
1696
1697         {
1698           char *t = s;
1699           char *arg1 = arg;
1700
1701           do
1702             *t = TOLOWER (*arg1++);
1703           while (*t++);
1704         }
1705
1706         for (i = 0; cpu_types[i].name; ++i)
1707           {
1708             if (!strcmp (cpu_types[i].name, s))
1709               {
1710                 arc_target      = cpu_types[i].flags;
1711                 arc_target_name = cpu_types[i].name;
1712                 arc_features    = cpu_types[i].features;
1713                 arc_mach_type   = cpu_types[i].mach;
1714                 cpu_flags       = cpu_types[i].eflags;
1715
1716                 mach_type_specified_p = 1;
1717                 break;
1718               }
1719           }
1720
1721         if (!cpu_types[i].name)
1722           {
1723             as_fatal (_("unknown architecture: %s\n"), arg);
1724           }
1725         break;
1726       }
1727
1728     case OPTION_EB:
1729       arc_target_format = "elf32-bigarc";
1730       byte_order = BIG_ENDIAN;
1731       break;
1732
1733     case OPTION_EL:
1734       arc_target_format = "elf32-littlearc";
1735       byte_order = LITTLE_ENDIAN;
1736       break;
1737
1738     case OPTION_CD:
1739       /* This option has an effect only on ARC EM.  */
1740       if (arc_target & ARC_OPCODE_ARCv2EM)
1741         arc_features |= ARC_CD;
1742       break;
1743
1744     case OPTION_USER_MODE:
1745     case OPTION_LD_EXT_MASK:
1746     case OPTION_SWAP:
1747     case OPTION_NORM:
1748     case OPTION_BARREL_SHIFT:
1749     case OPTION_MIN_MAX:
1750     case OPTION_NO_MPY:
1751     case OPTION_EA:
1752     case OPTION_MUL64:
1753     case OPTION_SIMD:
1754     case OPTION_SPFP:
1755     case OPTION_DPFP:
1756     case OPTION_XMAC_D16:
1757     case OPTION_XMAC_24:
1758     case OPTION_DSP_PACKA:
1759     case OPTION_CRC:
1760     case OPTION_DVBF:
1761     case OPTION_TELEPHONY:
1762     case OPTION_XYMEMORY:
1763     case OPTION_LOCK:
1764     case OPTION_SWAPE:
1765     case OPTION_RTSC:
1766     case OPTION_FPUDA:
1767       /* Dummy options are accepted but have no effect.  */
1768       break;
1769
1770     default:
1771       return 0;
1772     }
1773
1774   if (cpu_flags != EF_ARC_CPU_GENERIC)
1775     arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
1776
1777   return 1;
1778 }
1779
1780 void
1781 md_show_usage (FILE *stream)
1782 {
1783   fprintf (stream, _("ARC-specific assembler options:\n"));
1784
1785   fprintf (stream, "  -mcpu=<cpu name>\t  assemble for CPU <cpu name>\n");
1786   fprintf (stream,
1787            "  -mcode-density\t  enable code density option for ARC EM\n");
1788
1789   fprintf (stream, _("\
1790   -EB                     assemble code for a big-endian cpu\n"));
1791   fprintf (stream, _("\
1792   -EL                     assemble code for a little-endian cpu\n"));
1793 }
1794
1795 static void
1796 preprocess_operands (const struct arc_opcode *opcode,
1797                      expressionS *tok,
1798                      int ntok)
1799 {
1800   int i;
1801   size_t len;
1802   const char *p;
1803   unsigned j;
1804   const struct arc_aux_reg *auxr;
1805
1806   for (i = 0; i < ntok; i++)
1807     {
1808       switch (tok[i].X_op)
1809         {
1810         case O_illegal:
1811         case O_absent:
1812           break; /* Throw and error.  */
1813
1814         case O_symbol:
1815           if (opcode->class != AUXREG)
1816             break;
1817           /* Convert the symbol to a constant if possible.  */
1818           p = S_GET_NAME (tok[i].X_add_symbol);
1819           len = strlen (p);
1820
1821           auxr = &arc_aux_regs[0];
1822           for (j = 0; j < arc_num_aux_regs; j++, auxr++)
1823             if (len == auxr->length
1824                 && strcasecmp (auxr->name, p) == 0)
1825               {
1826                 tok[i].X_op = O_constant;
1827                 tok[i].X_add_number = auxr->address;
1828                 break;
1829               }
1830           break;
1831         default:
1832           break;
1833         }
1834     }
1835 }
1836
1837 /* Given an opcode name, pre-tockenized set of argumenst and the
1838    opcode flags, take it all the way through emission.  */
1839
1840 static void
1841 assemble_tokens (const char *opname,
1842                  expressionS *tok,
1843                  int ntok,
1844                  struct arc_flags *pflags,
1845                  int nflgs)
1846 {
1847   bfd_boolean found_something = FALSE;
1848   const struct arc_opcode *opcode;
1849   int cpumatch = 1;
1850
1851   /* Search opcodes.  */
1852   opcode = (const struct arc_opcode *) hash_find (arc_opcode_hash, opname);
1853
1854   /* Couldn't find opcode conventional way, try special cases.  */
1855   if (!opcode)
1856     opcode = find_special_case (opname, &nflgs, pflags, tok, &ntok);
1857
1858   if (opcode)
1859     {
1860       pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
1861                 frag_now->fr_file, frag_now->fr_line, opcode->name,
1862                 opcode->opcode);
1863
1864       preprocess_operands (opcode, tok, ntok);
1865
1866       found_something = TRUE;
1867       opcode = find_opcode_match (opcode, tok, &ntok, pflags, nflgs, &cpumatch);
1868       if (opcode)
1869         {
1870           struct arc_insn insn;
1871           assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
1872           emit_insn (&insn);
1873           return;
1874         }
1875     }
1876
1877   if (found_something)
1878     {
1879       if (cpumatch)
1880         as_bad (_("inappropriate arguments for opcode '%s'"), opname);
1881       else
1882         as_bad (_("opcode '%s' not supported for target %s"), opname,
1883                 arc_target_name);
1884     }
1885   else
1886     as_bad (_("unknown opcode '%s'"), opname);
1887 }
1888
1889 /* Used to find special case opcode.  */
1890
1891 static const struct arc_opcode *
1892 find_special_case (const char *opname,
1893                    int *nflgs,
1894                    struct arc_flags *pflags,
1895                    expressionS *tok,
1896                    int *ntok)
1897 {
1898   const struct arc_opcode *opcode;
1899
1900   opcode = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
1901
1902   if (opcode == NULL)
1903     opcode = find_special_case_flag (opname, nflgs, pflags);
1904
1905   return opcode;
1906 }
1907
1908 /* Swap operand tokens.  */
1909
1910 static void
1911 swap_operand (expressionS *operand_array,
1912               unsigned source,
1913               unsigned destination)
1914 {
1915   expressionS cpy_operand;
1916   expressionS *src_operand;
1917   expressionS *dst_operand;
1918   size_t size;
1919
1920   if (source == destination)
1921     return;
1922
1923   src_operand = &operand_array[source];
1924   dst_operand = &operand_array[destination];
1925   size = sizeof (expressionS);
1926
1927   /* Make copy of operand to swap with and swap.  */
1928   memcpy (&cpy_operand, dst_operand, size);
1929   memcpy (dst_operand, src_operand, size);
1930   memcpy (src_operand, &cpy_operand, size);
1931 }
1932
1933 /* Check if *op matches *tok type.
1934    Returns FALSE if they don't match, TRUE if they match.  */
1935
1936 static bfd_boolean
1937 pseudo_operand_match (const expressionS *tok,
1938                       const struct arc_operand_operation *op)
1939 {
1940   offsetT min, max, val;
1941   bfd_boolean ret;
1942   const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
1943
1944   ret = FALSE;
1945   switch (tok->X_op)
1946     {
1947     case O_constant:
1948       if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
1949         ret = 1;
1950       else if (!(operand_real->flags & ARC_OPERAND_IR))
1951         {
1952           val = tok->X_add_number + op->count;
1953           if (operand_real->flags & ARC_OPERAND_SIGNED)
1954             {
1955               max = (1 << (operand_real->bits - 1)) - 1;
1956               min = -(1 << (operand_real->bits - 1));
1957             }
1958           else
1959             {
1960               max = (1 << operand_real->bits) - 1;
1961               min = 0;
1962             }
1963           if (min <= val && val <= max)
1964             ret = TRUE;
1965         }
1966       break;
1967
1968     case O_symbol:
1969       /* Handle all symbols as long immediates or signed 9.  */
1970       if (operand_real->flags & ARC_OPERAND_LIMM ||
1971           ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
1972         ret = TRUE;
1973       break;
1974
1975     case O_register:
1976       if (operand_real->flags & ARC_OPERAND_IR)
1977         ret = TRUE;
1978       break;
1979
1980     case O_bracket:
1981       if (operand_real->flags & ARC_OPERAND_BRAKET)
1982         ret = TRUE;
1983       break;
1984
1985     default:
1986       /* Unknown.  */
1987       break;
1988     }
1989   return ret;
1990 }
1991
1992 /* Find pseudo instruction in array.  */
1993
1994 static const struct arc_pseudo_insn *
1995 find_pseudo_insn (const char *opname,
1996                   int ntok,
1997                   const expressionS *tok)
1998 {
1999   const struct arc_pseudo_insn *pseudo_insn = NULL;
2000   const struct arc_operand_operation *op;
2001   unsigned int i;
2002   int j;
2003
2004   for (i = 0; i < arc_num_pseudo_insn; ++i)
2005     {
2006       pseudo_insn = &arc_pseudo_insns[i];
2007       if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
2008         {
2009           op = pseudo_insn->operand;
2010           for (j = 0; j < ntok; ++j)
2011             if (!pseudo_operand_match (&tok[j], &op[j]))
2012               break;
2013
2014           /* Found the right instruction.  */
2015           if (j == ntok)
2016             return pseudo_insn;
2017         }
2018     }
2019   return NULL;
2020 }
2021
2022 /* Assumes the expressionS *tok is of sufficient size.  */
2023
2024 static const struct arc_opcode *
2025 find_special_case_pseudo (const char *opname,
2026                           int *ntok,
2027                           expressionS *tok,
2028                           int *nflgs,
2029                           struct arc_flags *pflags)
2030 {
2031   const struct arc_pseudo_insn *pseudo_insn = NULL;
2032   const struct arc_operand_operation *operand_pseudo;
2033   const struct arc_operand *operand_real;
2034   unsigned i;
2035   char construct_operand[MAX_CONSTR_STR];
2036
2037   /* Find whether opname is in pseudo instruction array.  */
2038   pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
2039
2040   if (pseudo_insn == NULL)
2041     return NULL;
2042
2043   /* Handle flag, Limited to one flag at the moment.  */
2044   if (pseudo_insn->flag_r != NULL)
2045     *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
2046                               MAX_INSN_FLGS - *nflgs);
2047
2048   /* Handle operand operations.  */
2049   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2050     {
2051       operand_pseudo = &pseudo_insn->operand[i];
2052       operand_real = &arc_operands[operand_pseudo->operand_idx];
2053
2054       if (operand_real->flags & ARC_OPERAND_BRAKET &&
2055           !operand_pseudo->needs_insert)
2056         continue;
2057
2058       /* Has to be inserted (i.e. this token does not exist yet).  */
2059       if (operand_pseudo->needs_insert)
2060         {
2061           if (operand_real->flags & ARC_OPERAND_BRAKET)
2062             {
2063               tok[i].X_op = O_bracket;
2064               ++(*ntok);
2065               continue;
2066             }
2067
2068           /* Check if operand is a register or constant and handle it
2069              by type.  */
2070           if (operand_real->flags & ARC_OPERAND_IR)
2071             snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
2072                       operand_pseudo->count);
2073           else
2074             snprintf (construct_operand, MAX_CONSTR_STR, "%d",
2075                       operand_pseudo->count);
2076
2077           tokenize_arguments (construct_operand, &tok[i], 1);
2078           ++(*ntok);
2079         }
2080
2081       else if (operand_pseudo->count)
2082         {
2083           /* Operand number has to be adjusted accordingly (by operand
2084              type).  */
2085           switch (tok[i].X_op)
2086             {
2087             case O_constant:
2088               tok[i].X_add_number += operand_pseudo->count;
2089               break;
2090
2091             case O_symbol:
2092               break;
2093
2094             default:
2095               /* Ignored.  */
2096               break;
2097             }
2098         }
2099     }
2100
2101   /* Swap operands if necessary.  Only supports one swap at the
2102      moment.  */
2103   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2104     {
2105       operand_pseudo = &pseudo_insn->operand[i];
2106
2107       if (operand_pseudo->swap_operand_idx == i)
2108         continue;
2109
2110       swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2111
2112       /* Prevent a swap back later by breaking out.  */
2113       break;
2114     }
2115
2116   return (const struct arc_opcode *)
2117     hash_find (arc_opcode_hash, pseudo_insn->mnemonic_r);
2118 }
2119
2120 static const struct arc_opcode *
2121 find_special_case_flag (const char *opname,
2122                         int *nflgs,
2123                         struct arc_flags *pflags)
2124 {
2125   unsigned int i;
2126   const char *flagnm;
2127   unsigned flag_idx, flag_arr_idx;
2128   size_t flaglen, oplen;
2129   const struct arc_flag_special *arc_flag_special_opcode;
2130   const struct arc_opcode *opcode;
2131
2132   /* Search for special case instruction.  */
2133   for (i = 0; i < arc_num_flag_special; i++)
2134     {
2135       arc_flag_special_opcode = &arc_flag_special_cases[i];
2136       oplen = strlen (arc_flag_special_opcode->name);
2137
2138       if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2139         continue;
2140
2141       /* Found a potential special case instruction, now test for
2142          flags.  */
2143       for (flag_arr_idx = 0;; ++flag_arr_idx)
2144         {
2145           flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2146           if (flag_idx == 0)
2147             break;  /* End of array, nothing found.  */
2148
2149           flagnm = arc_flag_operands[flag_idx].name;
2150           flaglen = strlen (flagnm);
2151           if (strcmp (opname + oplen, flagnm) == 0)
2152             {
2153               opcode = (const struct arc_opcode *)
2154                 hash_find (arc_opcode_hash,
2155                            arc_flag_special_opcode->name);
2156
2157               if (*nflgs + 1 > MAX_INSN_FLGS)
2158                 break;
2159               memcpy (pflags[*nflgs].name, flagnm, flaglen);
2160               pflags[*nflgs].name[flaglen] = '\0';
2161               (*nflgs)++;
2162               return opcode;
2163             }
2164         }
2165     }
2166   return NULL;
2167 }
2168
2169 /* Check whether a symbol involves a register.  */
2170
2171 static int
2172 contains_register (symbolS *sym)
2173 {
2174   if (sym)
2175   {
2176     expressionS *ex = symbol_get_value_expression (sym);
2177     return ((O_register == ex->X_op)
2178             && !contains_register (ex->X_add_symbol)
2179             && !contains_register (ex->X_op_symbol));
2180   }
2181   else
2182     return 0;
2183 }
2184
2185 /* Returns the register number within a symbol.  */
2186
2187 static int
2188 get_register (symbolS *sym)
2189 {
2190   if (!contains_register (sym))
2191     return -1;
2192
2193   expressionS *ex = symbol_get_value_expression (sym);
2194   return regno (ex->X_add_number);
2195 }
2196
2197 /* Allocates a tok entry.  */
2198
2199 static int
2200 allocate_tok (expressionS *tok, int ntok, int cidx)
2201 {
2202   if (ntok > MAX_INSN_ARGS - 2)
2203     return 0; /* No space left.  */
2204
2205   if (cidx > ntok)
2206     return 0; /* Incorect args.  */
2207
2208   memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
2209
2210   if (cidx == ntok)
2211     return 1; /* Success.  */
2212   return allocate_tok (tok, ntok - 1, cidx);
2213 }
2214
2215 /* Return true if a RELOC is generic.  A generic reloc is PC-rel of a
2216    simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32.  */
2217
2218 static bfd_boolean
2219 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
2220 {
2221   if (!reloc)
2222     return FALSE;
2223
2224   switch (reloc)
2225     {
2226     case BFD_RELOC_ARC_SDA_LDST:
2227     case BFD_RELOC_ARC_SDA_LDST1:
2228     case BFD_RELOC_ARC_SDA_LDST2:
2229     case BFD_RELOC_ARC_SDA16_LD:
2230     case BFD_RELOC_ARC_SDA16_LD1:
2231     case BFD_RELOC_ARC_SDA16_LD2:
2232     case BFD_RELOC_ARC_SDA16_ST2:
2233     case BFD_RELOC_ARC_SDA32_ME:
2234       return FALSE;
2235     default:
2236       break;
2237     }
2238   return TRUE;
2239 }
2240
2241 /* Search forward through all variants of an opcode looking for a
2242    syntax match.  */
2243
2244 static const struct arc_opcode *
2245 find_opcode_match (const struct arc_opcode *first_opcode,
2246                    expressionS *tok,
2247                    int *pntok,
2248                    struct arc_flags *first_pflag,
2249                    int nflgs,
2250                    int *pcpumatch)
2251 {
2252   const struct arc_opcode *opcode = first_opcode;
2253   int ntok = *pntok;
2254   int got_cpu_match = 0;
2255   expressionS bktok[MAX_INSN_ARGS];
2256   int bkntok;
2257   expressionS emptyE;
2258
2259   memset (&emptyE, 0, sizeof (emptyE));
2260   memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
2261   bkntok = ntok;
2262
2263   do
2264     {
2265       const unsigned char *opidx;
2266       const unsigned char *flgidx;
2267       int tokidx = 0;
2268       const expressionS *t = &emptyE;
2269
2270       pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
2271                 frag_now->fr_file, frag_now->fr_line, opcode->opcode);
2272
2273       /* Don't match opcodes that don't exist on this
2274          architecture.  */
2275       if (!(opcode->cpu & arc_target))
2276         goto match_failed;
2277
2278       if (is_code_density_p (opcode) && !(arc_features & ARC_CD))
2279         goto match_failed;
2280
2281       got_cpu_match = 1;
2282       pr_debug ("cpu ");
2283
2284       /* Check the operands.  */
2285       for (opidx = opcode->operands; *opidx; ++opidx)
2286         {
2287           const struct arc_operand *operand = &arc_operands[*opidx];
2288
2289           /* Only take input from real operands.  */
2290           if ((operand->flags & ARC_OPERAND_FAKE)
2291               && !(operand->flags & ARC_OPERAND_BRAKET))
2292             continue;
2293
2294           /* When we expect input, make sure we have it.  */
2295           if (tokidx >= ntok)
2296             goto match_failed;
2297
2298           /* Match operand type with expression type.  */
2299           switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
2300             {
2301             case ARC_OPERAND_IR:
2302               /* Check to be a register.  */
2303               if ((tok[tokidx].X_op != O_register
2304                    || !is_ir_num (tok[tokidx].X_add_number))
2305                   && !(operand->flags & ARC_OPERAND_IGNORE))
2306                 goto match_failed;
2307
2308               /* If expect duplicate, make sure it is duplicate.  */
2309               if (operand->flags & ARC_OPERAND_DUPLICATE)
2310                 {
2311                   /* Check for duplicate.  */
2312                   if (t->X_op != O_register
2313                       || !is_ir_num (t->X_add_number)
2314                       || (regno (t->X_add_number) !=
2315                           regno (tok[tokidx].X_add_number)))
2316                     goto match_failed;
2317                 }
2318
2319               /* Special handling?  */
2320               if (operand->insert)
2321                 {
2322                   const char *errmsg = NULL;
2323                   (*operand->insert)(0,
2324                                      regno (tok[tokidx].X_add_number),
2325                                      &errmsg);
2326                   if (errmsg)
2327                     {
2328                       if (operand->flags & ARC_OPERAND_IGNORE)
2329                         {
2330                           /* Missing argument, create one.  */
2331                           if (!allocate_tok (tok, ntok - 1, tokidx))
2332                             goto match_failed;
2333
2334                           tok[tokidx].X_op = O_absent;
2335                           ++ntok;
2336                         }
2337                       else
2338                         goto match_failed;
2339                     }
2340                 }
2341
2342               t = &tok[tokidx];
2343               break;
2344
2345             case ARC_OPERAND_BRAKET:
2346               /* Check if bracket is also in opcode table as
2347                  operand.  */
2348               if (tok[tokidx].X_op != O_bracket)
2349                 goto match_failed;
2350               break;
2351
2352             case ARC_OPERAND_LIMM:
2353             case ARC_OPERAND_SIGNED:
2354             case ARC_OPERAND_UNSIGNED:
2355               switch (tok[tokidx].X_op)
2356                 {
2357                 case O_illegal:
2358                 case O_absent:
2359                 case O_register:
2360                   goto match_failed;
2361
2362                 case O_bracket:
2363                   /* Got an (too) early bracket, check if it is an
2364                      ignored operand.  N.B. This procedure works only
2365                      when bracket is the last operand!  */
2366                   if (!(operand->flags & ARC_OPERAND_IGNORE))
2367                     goto match_failed;
2368                   /* Insert the missing operand.  */
2369                   if (!allocate_tok (tok, ntok - 1, tokidx))
2370                     goto match_failed;
2371
2372                   tok[tokidx].X_op = O_absent;
2373                   ++ntok;
2374                   break;
2375
2376                 case O_constant:
2377                   /* Check the range.  */
2378                   if (operand->bits != 32
2379                       && !(operand->flags & ARC_OPERAND_NCHK))
2380                     {
2381                       offsetT min, max, val;
2382                       val = tok[tokidx].X_add_number;
2383
2384                       if (operand->flags & ARC_OPERAND_SIGNED)
2385                         {
2386                           max = (1 << (operand->bits - 1)) - 1;
2387                           min = -(1 << (operand->bits - 1));
2388                         }
2389                       else
2390                         {
2391                           max = (1 << operand->bits) - 1;
2392                           min = 0;
2393                         }
2394
2395                       if (val < min || val > max)
2396                         goto match_failed;
2397
2398                       /* Check alignmets.  */
2399                       if ((operand->flags & ARC_OPERAND_ALIGNED32)
2400                           && (val & 0x03))
2401                         goto match_failed;
2402
2403                       if ((operand->flags & ARC_OPERAND_ALIGNED16)
2404                           && (val & 0x01))
2405                         goto match_failed;
2406                     }
2407                   else if (operand->flags & ARC_OPERAND_NCHK)
2408                     {
2409                       if (operand->insert)
2410                         {
2411                           const char *errmsg = NULL;
2412                           (*operand->insert)(0,
2413                                              tok[tokidx].X_add_number,
2414                                              &errmsg);
2415                           if (errmsg)
2416                             goto match_failed;
2417                         }
2418                       else
2419                         goto match_failed;
2420                     }
2421                   break;
2422
2423                 case O_subtract:
2424                   /* Check if it is register range.  */
2425                   if ((tok[tokidx].X_add_number == 0)
2426                       && contains_register (tok[tokidx].X_add_symbol)
2427                       && contains_register (tok[tokidx].X_op_symbol))
2428                     {
2429                       int regs;
2430
2431                       regs = get_register (tok[tokidx].X_add_symbol);
2432                       regs <<= 16;
2433                       regs |= get_register (tok[tokidx].X_op_symbol);
2434                       if (operand->insert)
2435                         {
2436                           const char *errmsg = NULL;
2437                           (*operand->insert)(0,
2438                                              regs,
2439                                              &errmsg);
2440                           if (errmsg)
2441                             goto match_failed;
2442                         }
2443                       else
2444                         goto match_failed;
2445                       break;
2446                     }
2447                 default:
2448                   if (operand->default_reloc == 0)
2449                     goto match_failed; /* The operand needs relocation.  */
2450
2451                   /* Relocs requiring long immediate.  FIXME! make it
2452                      generic and move it to a function.  */
2453                   switch (tok[tokidx].X_md)
2454                     {
2455                     case O_gotoff:
2456                     case O_gotpc:
2457                     case O_pcl:
2458                     case O_tpoff:
2459                     case O_dtpoff:
2460                     case O_tlsgd:
2461                     case O_tlsie:
2462                       if (!(operand->flags & ARC_OPERAND_LIMM))
2463                         goto match_failed;
2464                     case O_absent:
2465                       if (!generic_reloc_p (operand->default_reloc))
2466                         goto match_failed;
2467                     default:
2468                       break;
2469                     }
2470                   break;
2471                 }
2472               /* If expect duplicate, make sure it is duplicate.  */
2473               if (operand->flags & ARC_OPERAND_DUPLICATE)
2474                 {
2475                   if (t->X_op == O_illegal
2476                       || t->X_op == O_absent
2477                       || t->X_op == O_register
2478                       || (t->X_add_number != tok[tokidx].X_add_number))
2479                     goto match_failed;
2480                 }
2481               t = &tok[tokidx];
2482               break;
2483
2484             default:
2485               /* Everything else should have been fake.  */
2486               abort ();
2487             }
2488
2489           ++tokidx;
2490         }
2491       pr_debug ("opr ");
2492
2493       /* Check the flags.  Iterate over the valid flag classes.  */
2494       int lnflg = nflgs;
2495
2496       for (flgidx = opcode->flags; *flgidx && lnflg; ++flgidx)
2497         {
2498           /* Get a valid flag class.  */
2499           const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
2500           const unsigned *flgopridx;
2501
2502           for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
2503             {
2504               const struct arc_flag_operand *flg_operand;
2505               struct arc_flags *pflag = first_pflag;
2506               int i;
2507
2508               flg_operand = &arc_flag_operands[*flgopridx];
2509               for (i = 0; i < nflgs; i++, pflag++)
2510                 {
2511                   /* Match against the parsed flags.  */
2512                   if (!strcmp (flg_operand->name, pflag->name))
2513                     {
2514                       /*TODO: Check if it is duplicated.  */
2515                       pflag->code = *flgopridx;
2516                       lnflg--;
2517                       break; /* goto next flag class and parsed flag.  */
2518                     }
2519                 }
2520             }
2521         }
2522       /* Did I check all the parsed flags?  */
2523       if (lnflg)
2524         goto match_failed;
2525
2526       pr_debug ("flg");
2527       /* Possible match -- did we use all of our input?  */
2528       if (tokidx == ntok)
2529         {
2530           *pntok = ntok;
2531           pr_debug ("\n");
2532           return opcode;
2533         }
2534
2535     match_failed:;
2536       pr_debug ("\n");
2537       /* Restore the original parameters.  */
2538       memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
2539       ntok = bkntok;
2540     }
2541   while (++opcode - arc_opcodes < (int) arc_num_opcodes
2542          && !strcmp (opcode->name, first_opcode->name));
2543
2544   if (*pcpumatch)
2545     *pcpumatch = got_cpu_match;
2546
2547   return NULL;
2548 }
2549
2550 /* Find the proper relocation for the given opcode.  */
2551
2552 static extended_bfd_reloc_code_real_type
2553 find_reloc (const char *name,
2554             const char *opcodename,
2555             const struct arc_flags *pflags,
2556             int nflg,
2557             extended_bfd_reloc_code_real_type reloc)
2558 {
2559   unsigned int i;
2560   int j;
2561   bfd_boolean found_flag, tmp;
2562   extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
2563
2564   for (i = 0; i < arc_num_equiv_tab; i++)
2565     {
2566       const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
2567
2568       /* Find the entry.  */
2569       if (strcmp (name, r->name))
2570         continue;
2571       if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
2572         continue;
2573       if (r->flags[0])
2574         {
2575           if (!nflg)
2576             continue;
2577           found_flag = FALSE;
2578           unsigned * psflg = (unsigned *)r->flags;
2579           do
2580             {
2581               tmp = FALSE;
2582               for (j = 0; j < nflg; j++)
2583                 if (!strcmp (pflags[j].name,
2584                              arc_flag_operands[*psflg].name))
2585                   {
2586                     tmp = TRUE;
2587                     break;
2588                   }
2589               if (!tmp)
2590                 {
2591                   found_flag = FALSE;
2592                   break;
2593                 }
2594               else
2595                 {
2596                   found_flag = TRUE;
2597                 }
2598               ++ psflg;
2599             } while (*psflg);
2600
2601           if (!found_flag)
2602             continue;
2603         }
2604
2605       if (reloc != r->oldreloc)
2606         continue;
2607       /* Found it.  */
2608       ret = r->newreloc;
2609       break;
2610     }
2611
2612   if (ret == BFD_RELOC_UNUSED)
2613     as_bad (_("Unable to find %s relocation for instruction %s"),
2614             name, opcodename);
2615   return ret;
2616 }
2617
2618 /* Turn an opcode description and a set of arguments into
2619    an instruction and a fixup.  */
2620
2621 static void
2622 assemble_insn (const struct arc_opcode *opcode,
2623                const expressionS *tok,
2624                int ntok,
2625                const struct arc_flags *pflags,
2626                int nflg,
2627                struct arc_insn *insn)
2628 {
2629   const expressionS *reloc_exp = NULL;
2630   unsigned image;
2631   const unsigned char *argidx;
2632   int i;
2633   int tokidx = 0;
2634   unsigned char pcrel = 0;
2635   bfd_boolean needGOTSymbol;
2636   bfd_boolean has_delay_slot = FALSE;
2637   extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2638
2639   memset (insn, 0, sizeof (*insn));
2640   image = opcode->opcode;
2641
2642   pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
2643             frag_now->fr_file, frag_now->fr_line, opcode->name,
2644             opcode->opcode);
2645
2646   /* Handle operands.  */
2647   for (argidx = opcode->operands; *argidx; ++argidx)
2648     {
2649       const struct arc_operand *operand = &arc_operands[*argidx];
2650       const expressionS *t = (const expressionS *) 0;
2651
2652       if ((operand->flags & ARC_OPERAND_FAKE)
2653           && !(operand->flags & ARC_OPERAND_BRAKET))
2654         continue;
2655
2656       if (operand->flags & ARC_OPERAND_DUPLICATE)
2657         {
2658           /* Duplicate operand, already inserted.  */
2659           tokidx ++;
2660           continue;
2661         }
2662
2663       if (tokidx >= ntok)
2664         {
2665           abort ();
2666         }
2667       else
2668         t = &tok[tokidx++];
2669
2670       /* Regardless if we have a reloc or not mark the instruction
2671          limm if it is the case.  */
2672       if (operand->flags & ARC_OPERAND_LIMM)
2673         insn->has_limm = TRUE;
2674
2675       switch (t->X_op)
2676         {
2677         case O_register:
2678           image = insert_operand (image, operand, regno (t->X_add_number),
2679                                   NULL, 0);
2680           break;
2681
2682         case O_constant:
2683           image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2684           reloc_exp = t;
2685           if (operand->flags & ARC_OPERAND_LIMM)
2686             insn->limm = t->X_add_number;
2687           break;
2688
2689         case O_bracket:
2690           /* Ignore brackets.  */
2691           break;
2692
2693         case O_absent:
2694           gas_assert (operand->flags & ARC_OPERAND_IGNORE);
2695           break;
2696
2697         case O_subtract:
2698           /* Maybe register range.  */
2699           if ((t->X_add_number == 0)
2700               && contains_register (t->X_add_symbol)
2701               && contains_register (t->X_op_symbol))
2702             {
2703               int regs;
2704
2705               regs = get_register (t->X_add_symbol);
2706               regs <<= 16;
2707               regs |= get_register (t->X_op_symbol);
2708               image = insert_operand (image, operand, regs, NULL, 0);
2709               break;
2710             }
2711
2712         default:
2713           /* This operand needs a relocation.  */
2714           needGOTSymbol = FALSE;
2715
2716           switch (t->X_md)
2717             {
2718             case O_plt:
2719               needGOTSymbol = TRUE;
2720               reloc = find_reloc ("plt", opcode->name,
2721                                   pflags, nflg,
2722                                   operand->default_reloc);
2723               break;
2724
2725             case O_gotoff:
2726             case O_gotpc:
2727               needGOTSymbol = TRUE;
2728               reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2729               break;
2730             case O_pcl:
2731               reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2732               if (ARC_SHORT (opcode->mask))
2733                 as_bad_where (frag_now->fr_file, frag_now->fr_line,
2734                               _("Unable to use @pcl relocation for insn %s"),
2735                               opcode->name);
2736               break;
2737             case O_sda:
2738               reloc = find_reloc ("sda", opcode->name,
2739                                   pflags, nflg,
2740                                   operand->default_reloc);
2741               break;
2742             case O_tlsgd:
2743             case O_tlsie:
2744               needGOTSymbol = TRUE;
2745               /* Fall-through.  */
2746
2747             case O_tpoff:
2748             case O_dtpoff:
2749               reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2750               break;
2751
2752             case O_tpoff9: /*FIXME! Check for the conditionality of
2753                              the insn.  */
2754             case O_dtpoff9: /*FIXME! Check for the conditionality of
2755                               the insn.  */
2756               as_bad (_("TLS_*_S9 relocs are not supported yet"));
2757               break;
2758
2759             default:
2760               /* Just consider the default relocation.  */
2761               reloc = operand->default_reloc;
2762               break;
2763             }
2764
2765           if (needGOTSymbol && (GOT_symbol == NULL))
2766             GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
2767
2768           reloc_exp = t;
2769
2770 #if 0
2771           if (reloc > 0)
2772             {
2773               /* sanity checks.  */
2774               reloc_howto_type *reloc_howto
2775                 = bfd_reloc_type_lookup (stdoutput,
2776                                          (bfd_reloc_code_real_type) reloc);
2777               unsigned reloc_bitsize = reloc_howto->bitsize;
2778               if (reloc_howto->rightshift)
2779                 reloc_bitsize -= reloc_howto->rightshift;
2780               if (reloc_bitsize != operand->bits)
2781                 {
2782                   as_bad (_("invalid relocation %s for field"),
2783                           bfd_get_reloc_code_name (reloc));
2784                   return;
2785                 }
2786             }
2787 #endif
2788           if (insn->nfixups >= MAX_INSN_FIXUPS)
2789             as_fatal (_("too many fixups"));
2790
2791           struct arc_fixup *fixup;
2792           fixup = &insn->fixups[insn->nfixups++];
2793           fixup->exp = *t;
2794           fixup->reloc = reloc;
2795           pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
2796           fixup->pcrel = pcrel;
2797           fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
2798             TRUE : FALSE;
2799           break;
2800         }
2801     }
2802
2803   /* Handle flags.  */
2804   for (i = 0; i < nflg; i++)
2805     {
2806       const struct arc_flag_operand *flg_operand =
2807         &arc_flag_operands[pflags[i].code];
2808
2809       /* Check if the instruction has a delay slot.  */
2810       if (!strcmp (flg_operand->name, "d"))
2811         has_delay_slot = TRUE;
2812
2813       /* There is an exceptional case when we cannot insert a flag
2814          just as it is.  The .T flag must be handled in relation with
2815          the relative address.  */
2816       if (!strcmp (flg_operand->name, "t")
2817           || !strcmp (flg_operand->name, "nt"))
2818         {
2819           unsigned bitYoperand = 0;
2820           /* FIXME! move selection bbit/brcc in arc-opc.c.  */
2821           if (!strcmp (flg_operand->name, "t"))
2822             if (!strcmp (opcode->name, "bbit0")
2823                 || !strcmp (opcode->name, "bbit1"))
2824               bitYoperand = arc_NToperand;
2825             else
2826               bitYoperand = arc_Toperand;
2827           else
2828             if (!strcmp (opcode->name, "bbit0")
2829                 || !strcmp (opcode->name, "bbit1"))
2830               bitYoperand = arc_Toperand;
2831             else
2832               bitYoperand = arc_NToperand;
2833
2834           gas_assert (reloc_exp != NULL);
2835           if (reloc_exp->X_op == O_constant)
2836             {
2837               /* Check if we have a constant and solved it
2838                  immediately.  */
2839               offsetT val = reloc_exp->X_add_number;
2840               image |= insert_operand (image, &arc_operands[bitYoperand],
2841                                        val, NULL, 0);
2842             }
2843           else
2844             {
2845               struct arc_fixup *fixup;
2846
2847               if (insn->nfixups >= MAX_INSN_FIXUPS)
2848                 as_fatal (_("too many fixups"));
2849
2850               fixup = &insn->fixups[insn->nfixups++];
2851               fixup->exp = *reloc_exp;
2852               fixup->reloc = -bitYoperand;
2853               fixup->pcrel = pcrel;
2854               fixup->islong = FALSE;
2855             }
2856         }
2857       else
2858         image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
2859           << flg_operand->shift;
2860     }
2861
2862   /* Short instruction?  */
2863   insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
2864
2865   insn->insn = image;
2866
2867   /* Update last insn status.  */
2868   arc_last_insns[1]                = arc_last_insns[0];
2869   arc_last_insns[0].opcode         = opcode;
2870   arc_last_insns[0].has_limm       = insn->has_limm;
2871   arc_last_insns[0].has_delay_slot = has_delay_slot;
2872
2873   /* Check if the current instruction is legally used.  */
2874   if (arc_last_insns[1].has_delay_slot
2875       && is_br_jmp_insn_p (arc_last_insns[0].opcode))
2876     as_bad_where (frag_now->fr_file, frag_now->fr_line,
2877                   _("A jump/branch instruction in delay slot."));
2878 }
2879
2880 /* Actually output an instruction with its fixup.  */
2881
2882 static void
2883 emit_insn (struct arc_insn *insn)
2884 {
2885   char *f;
2886   int i;
2887
2888   pr_debug ("Emit insn : 0x%x\n", insn->insn);
2889   pr_debug ("\tShort   : 0x%d\n", insn->short_insn);
2890   pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
2891
2892   /* Write out the instruction.  */
2893   if (insn->short_insn)
2894     {
2895       if (insn->has_limm)
2896         {
2897           f = frag_more (6);
2898           md_number_to_chars (f, insn->insn, 2);
2899           md_number_to_chars_midend (f + 2, insn->limm, 4);
2900           dwarf2_emit_insn (6);
2901         }
2902       else
2903         {
2904           f = frag_more (2);
2905           md_number_to_chars (f, insn->insn, 2);
2906           dwarf2_emit_insn (2);
2907         }
2908     }
2909   else
2910     {
2911       if (insn->has_limm)
2912         {
2913           f = frag_more (8);
2914           md_number_to_chars_midend (f, insn->insn, 4);
2915           md_number_to_chars_midend (f + 4, insn->limm, 4);
2916           dwarf2_emit_insn (8);
2917         }
2918       else
2919         {
2920           f = frag_more (4);
2921           md_number_to_chars_midend (f, insn->insn, 4);
2922           dwarf2_emit_insn (4);
2923         }
2924     }
2925
2926   /* Apply the fixups in order.  */
2927   for (i = 0; i < insn->nfixups; i++)
2928     {
2929       struct arc_fixup *fixup = &insn->fixups[i];
2930       int size, pcrel, offset = 0;
2931
2932       /*FIXME! the reloc size is wrong in the BFD file.  When it will
2933         be fixed please delete me.  */
2934       size = (insn->short_insn && !fixup->islong) ? 2 : 4;
2935
2936       if (fixup->islong)
2937         offset = (insn->short_insn) ? 2 : 4;
2938
2939       /* Some fixups are only used internally, thus no howto.  */
2940       if ((int) fixup->reloc < 0)
2941         {
2942           /*FIXME! the reloc size is wrong in the BFD file.  When it
2943             will be fixed please enable me.
2944             size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
2945           pcrel = fixup->pcrel;
2946         }
2947       else
2948         {
2949           reloc_howto_type *reloc_howto =
2950             bfd_reloc_type_lookup (stdoutput,
2951                                    (bfd_reloc_code_real_type) fixup->reloc);
2952           gas_assert (reloc_howto);
2953           /*FIXME! the reloc size is wrong in the BFD file.  When it
2954             will be fixed please enable me.
2955             size = bfd_get_reloc_size (reloc_howto); */
2956           pcrel = reloc_howto->pc_relative;
2957         }
2958
2959       pr_debug ("%s:%d: emit_insn: new %s fixup (PCrel:%s) of size %d @ offset %d\n",
2960                 frag_now->fr_file, frag_now->fr_line,
2961                 (fixup->reloc < 0) ? "Internal" :
2962                 bfd_get_reloc_code_name (fixup->reloc),
2963                 pcrel ? "Y" : "N",
2964                 size, offset);
2965       fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
2966                    size, &fixup->exp, pcrel, fixup->reloc);
2967
2968       /* Check for ZOLs, and update symbol info if any.  */
2969       if (LP_INSN (insn->insn))
2970         {
2971           gas_assert (fixup->exp.X_add_symbol);
2972           ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
2973         }
2974     }
2975 }
2976
2977 /* Insert an operand value into an instruction.  */
2978
2979 static unsigned
2980 insert_operand (unsigned insn,
2981                 const struct arc_operand *operand,
2982                 offsetT val,
2983                 char *file,
2984                 unsigned line)
2985 {
2986   offsetT min = 0, max = 0;
2987
2988   if (operand->bits != 32
2989       && !(operand->flags & ARC_OPERAND_NCHK)
2990       && !(operand->flags & ARC_OPERAND_FAKE))
2991     {
2992       if (operand->flags & ARC_OPERAND_SIGNED)
2993         {
2994           max = (1 << (operand->bits - 1)) - 1;
2995           min = -(1 << (operand->bits - 1));
2996         }
2997       else
2998         {
2999           max = (1 << operand->bits) - 1;
3000           min = 0;
3001         }
3002
3003       if (val < min || val > max)
3004         as_bad_value_out_of_range (_("operand"),
3005                                    val, min, max, file, line);
3006     }
3007
3008   pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
3009             min, val, max, insn);
3010
3011   if ((operand->flags & ARC_OPERAND_ALIGNED32)
3012       && (val & 0x03))
3013     as_bad_where (file, line,
3014                   _("Unaligned operand. Needs to be 32bit aligned"));
3015
3016   if ((operand->flags & ARC_OPERAND_ALIGNED16)
3017       && (val & 0x01))
3018     as_bad_where (file, line,
3019                   _("Unaligned operand. Needs to be 16bit aligned"));
3020
3021   if (operand->insert)
3022     {
3023       const char *errmsg = NULL;
3024
3025       insn = (*operand->insert) (insn, val, &errmsg);
3026       if (errmsg)
3027         as_warn_where (file, line, "%s", errmsg);
3028     }
3029   else
3030     {
3031       if (operand->flags & ARC_OPERAND_TRUNCATE)
3032         {
3033           if (operand->flags & ARC_OPERAND_ALIGNED32)
3034             val >>= 2;
3035           if (operand->flags & ARC_OPERAND_ALIGNED16)
3036             val >>= 1;
3037         }
3038       insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
3039     }
3040   return insn;
3041 }
3042
3043 void
3044 arc_handle_align (fragS* fragP)
3045 {
3046   if ((fragP)->fr_type == rs_align_code)
3047     {
3048       char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
3049       valueT count = ((fragP)->fr_next->fr_address
3050                       - (fragP)->fr_address - (fragP)->fr_fix);
3051
3052       (fragP)->fr_var = 2;
3053
3054       if (count & 1)/* Padding in the gap till the next 2-byte
3055                        boundary with 0s.  */
3056         {
3057           (fragP)->fr_fix++;
3058           *dest++ = 0;
3059         }
3060       /* Writing nop_s.  */
3061       md_number_to_chars (dest, NOP_OPCODE_S, 2);
3062     }
3063 }
3064
3065 /* Here we decide which fixups can be adjusted to make them relative
3066    to the beginning of the section instead of the symbol.  Basically
3067    we need to make sure that the dynamic relocations are done
3068    correctly, so in some cases we force the original symbol to be
3069    used.  */
3070
3071 int
3072 tc_arc_fix_adjustable (fixS *fixP)
3073 {
3074
3075   /* Prevent all adjustments to global symbols.  */
3076   if (S_IS_EXTERNAL (fixP->fx_addsy))
3077     return 0;
3078   if (S_IS_WEAK (fixP->fx_addsy))
3079     return 0;
3080
3081   /* Adjust_reloc_syms doesn't know about the GOT.  */
3082   switch (fixP->fx_r_type)
3083     {
3084     case BFD_RELOC_ARC_GOTPC32:
3085     case BFD_RELOC_ARC_PLT32:
3086     case BFD_RELOC_ARC_S25H_PCREL_PLT:
3087     case BFD_RELOC_ARC_S21H_PCREL_PLT:
3088     case BFD_RELOC_ARC_S25W_PCREL_PLT:
3089     case BFD_RELOC_ARC_S21W_PCREL_PLT:
3090       return 0;
3091
3092     default:
3093       break;
3094     }
3095
3096   return 0; /* FIXME! return 1, fix it in the linker.  */
3097 }
3098
3099 /* Compute the reloc type of an expression EXP.  */
3100
3101 static void
3102 arc_check_reloc (expressionS *exp,
3103                  bfd_reloc_code_real_type *r_type_p)
3104 {
3105   if (*r_type_p == BFD_RELOC_32
3106       && exp->X_op == O_subtract
3107       && exp->X_op_symbol != NULL
3108       && exp->X_op_symbol->bsym->section == now_seg)
3109     *r_type_p = BFD_RELOC_ARC_32_PCREL;
3110 }
3111
3112
3113 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG.  */
3114
3115 void
3116 arc_cons_fix_new (fragS *frag,
3117                   int off,
3118                   int size,
3119                   expressionS *exp,
3120                   bfd_reloc_code_real_type r_type)
3121 {
3122   r_type = BFD_RELOC_UNUSED;
3123
3124   switch (size)
3125     {
3126     case 1:
3127       r_type = BFD_RELOC_8;
3128       break;
3129
3130     case 2:
3131       r_type = BFD_RELOC_16;
3132       break;
3133
3134     case 3:
3135       r_type = BFD_RELOC_24;
3136       break;
3137
3138     case 4:
3139       r_type = BFD_RELOC_32;
3140       arc_check_reloc (exp, &r_type);
3141       break;
3142
3143     case 8:
3144       r_type = BFD_RELOC_64;
3145       break;
3146
3147     default:
3148       as_bad (_("unsupported BFD relocation size %u"), size);
3149       r_type = BFD_RELOC_UNUSED;
3150     }
3151
3152   fix_new_exp (frag, off, size, exp, 0, r_type);
3153 }
3154
3155 /* The actual routine that checks the ZOL conditions.  */
3156
3157 static void
3158 check_zol (symbolS *s)
3159 {
3160   switch (arc_mach_type)
3161     {
3162     case bfd_mach_arc_arcv2:
3163       if (arc_target & ARC_OPCODE_ARCv2EM)
3164         return;
3165
3166       if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
3167           || arc_last_insns[1].has_delay_slot)
3168         as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3169                 S_GET_NAME (s));
3170
3171       break;
3172     case bfd_mach_arc_arc600:
3173
3174       if (is_kernel_insn_p (arc_last_insns[0].opcode))
3175         as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3176                 S_GET_NAME (s));
3177
3178       if (arc_last_insns[0].has_limm
3179           && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3180         as_bad (_("A jump instruction with long immediate detected at the \
3181 end of the ZOL label @%s"), S_GET_NAME (s));
3182
3183       /* Fall through.  */
3184     case bfd_mach_arc_arc700:
3185       if (arc_last_insns[0].has_delay_slot)
3186         as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3187                 S_GET_NAME (s));
3188
3189       break;
3190     default:
3191       break;
3192     }
3193 }
3194
3195 /* If ZOL end check the last two instruction for illegals.  */
3196 void
3197 arc_frob_label (symbolS * sym)
3198 {
3199   if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
3200     check_zol (sym);
3201
3202   dwarf2_emit_label (sym);
3203 }