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