1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
6 This file is part of GAS, the GNU Assembler.
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)
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.
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
25 #include "struc-symbol.h"
26 #include "dwarf2dbg.h"
27 #include "dw2gencfi.h"
28 #include "safe-ctype.h"
30 #include "opcode/arc.h"
33 /* Defines section. */
35 #define MAX_INSN_FIXUPS 2
36 #define MAX_CONSTR_STR 20
37 #define FRAG_MAX_GROWTH 8
40 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
42 # define pr_debug(fmt, args...)
45 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
46 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
47 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \
48 (SUB_OPCODE (x) == 0x28))
50 /* Equal to MAX_PRECISION in atof-ieee.c. */
51 #define MAX_LITTLENUMS 6
53 /* Enum used to enumerate the relaxable ins operands. */
58 REGISTER_S, /* Register for short instruction(s). */
59 REGISTER_NO_GP, /* Is a register but not gp register specifically. */
60 REGISTER_DUP, /* Duplication of previous operand of type register. */
94 #define regno(x) ((x) & 0x3F)
95 #define is_ir_num(x) (((x) & ~0x3F) == 0)
96 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
97 #define is_spfp_p(op) (((sc) == SPX))
98 #define is_dpfp_p(op) (((sc) == DPX))
99 #define is_fpuda_p(op) (((sc) == DPA))
100 #define is_br_jmp_insn_p(op) (((op)->class == BRANCH || (op)->class == JUMP))
101 #define is_kernel_insn_p(op) (((op)->class == KERNEL))
103 /* Generic assembler global variables which must be defined by all
106 /* Characters which always start a comment. */
107 const char comment_chars[] = "#;";
109 /* Characters which start a comment at the beginning of a line. */
110 const char line_comment_chars[] = "#";
112 /* Characters which may be used to separate multiple commands on a
114 const char line_separator_chars[] = "`";
116 /* Characters which are used to indicate an exponent in a floating
118 const char EXP_CHARS[] = "eE";
120 /* Chars that mean this number is a floating point constant
121 As in 0f12.456 or 0d1.2345e12. */
122 const char FLT_CHARS[] = "rRsSfFdD";
125 extern int target_big_endian;
126 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
127 static int byte_order = DEFAULT_BYTE_ORDER;
129 /* By default relaxation is disabled. */
130 static int relaxation_state = 0;
132 extern int arc_get_mach (char *);
134 /* Forward declarations. */
135 static void arc_lcomm (int);
136 static void arc_option (int);
137 static void arc_extra_reloc (int);
140 const pseudo_typeS md_pseudo_table[] =
142 /* Make sure that .word is 32 bits. */
145 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
146 { "lcomm", arc_lcomm, 0 },
147 { "lcommon", arc_lcomm, 0 },
148 { "cpu", arc_option, 0 },
150 { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
151 { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
156 const char *md_shortopts = "";
160 OPTION_EB = OPTION_MD_BASE,
173 /* The following options are deprecated and provided here only for
174 compatibility reasons. */
200 struct option md_longopts[] =
202 { "EB", no_argument, NULL, OPTION_EB },
203 { "EL", no_argument, NULL, OPTION_EL },
204 { "mcpu", required_argument, NULL, OPTION_MCPU },
205 { "mA6", no_argument, NULL, OPTION_ARC600 },
206 { "mARC600", no_argument, NULL, OPTION_ARC600 },
207 { "mARC601", no_argument, NULL, OPTION_ARC601 },
208 { "mARC700", no_argument, NULL, OPTION_ARC700 },
209 { "mA7", no_argument, NULL, OPTION_ARC700 },
210 { "mEM", no_argument, NULL, OPTION_ARCEM },
211 { "mHS", no_argument, NULL, OPTION_ARCHS },
212 { "mcode-density", no_argument, NULL, OPTION_CD },
213 { "mrelax", no_argument, NULL, OPTION_RELAX },
215 /* The following options are deprecated and provided here only for
216 compatibility reasons. */
217 { "mav2em", no_argument, NULL, OPTION_ARCEM },
218 { "mav2hs", no_argument, NULL, OPTION_ARCHS },
219 { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
220 { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
221 { "mswap", no_argument, NULL, OPTION_SWAP },
222 { "mnorm", no_argument, NULL, OPTION_NORM },
223 { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
224 { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
225 { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
226 { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
227 { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
228 { "mea", no_argument, NULL, OPTION_EA },
229 { "mEA", no_argument, NULL, OPTION_EA },
230 { "mmul64", no_argument, NULL, OPTION_MUL64 },
231 { "msimd", no_argument, NULL, OPTION_SIMD},
232 { "mspfp", no_argument, NULL, OPTION_SPFP},
233 { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
234 { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
235 { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
236 { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
237 { "mdpfp", no_argument, NULL, OPTION_DPFP},
238 { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
239 { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
240 { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
241 { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
242 { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
243 { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
244 { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
245 { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
246 { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
247 { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
248 { "mcrc", no_argument, NULL, OPTION_CRC},
249 { "mdvbf", no_argument, NULL, OPTION_DVBF},
250 { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
251 { "mxy", no_argument, NULL, OPTION_XYMEMORY},
252 { "mlock", no_argument, NULL, OPTION_LOCK},
253 { "mswape", no_argument, NULL, OPTION_SWAPE},
254 { "mrtsc", no_argument, NULL, OPTION_RTSC},
255 { "mfpuda", no_argument, NULL, OPTION_FPUDA},
257 { NULL, no_argument, NULL, 0 }
260 size_t md_longopts_size = sizeof (md_longopts);
262 /* Local data and data types. */
264 /* Used since new relocation types are introduced in this
265 file (DUMMY_RELOC_LITUSE_*). */
266 typedef int extended_bfd_reloc_code_real_type;
272 extended_bfd_reloc_code_real_type reloc;
274 /* index into arc_operands. */
275 unsigned int opindex;
277 /* PC-relative, used by internals fixups. */
280 /* TRUE if this fixup is for LIMM operand. */
288 struct arc_fixup fixups[MAX_INSN_FIXUPS];
290 bfd_boolean short_insn; /* Boolean value: TRUE if current insn is
292 bfd_boolean has_limm; /* Boolean value: TRUE if limm field is
294 bfd_boolean relax; /* Boolean value: TRUE if needs
298 /* Structure to hold any last two instructions. */
299 static struct arc_last_insn
301 /* Saved instruction opcode. */
302 const struct arc_opcode *opcode;
304 /* Boolean value: TRUE if current insn is short. */
305 bfd_boolean has_limm;
307 /* Boolean value: TRUE if current insn has delay slot. */
308 bfd_boolean has_delay_slot;
311 /* Forward declaration. */
312 static void assemble_insn
313 (const struct arc_opcode *, const expressionS *, int,
314 const struct arc_flags *, int, struct arc_insn *);
316 /* The cpu for which we are generating code. */
317 static unsigned arc_target;
318 static const char *arc_target_name;
319 static unsigned arc_features;
321 /* The default architecture. */
322 static int arc_mach_type;
324 /* Non-zero if the cpu type has been explicitly specified. */
325 static int mach_type_specified_p = 0;
327 /* The hash table of instruction opcodes. */
328 static struct hash_control *arc_opcode_hash;
330 /* The hash table of register symbols. */
331 static struct hash_control *arc_reg_hash;
333 /* A table of CPU names and opcode sets. */
334 static const struct cpu_type
344 { "arc600", ARC_OPCODE_ARC600, bfd_mach_arc_arc600,
345 E_ARC_MACH_ARC600, 0x00},
346 { "arc700", ARC_OPCODE_ARC700, bfd_mach_arc_arc700,
347 E_ARC_MACH_ARC700, 0x00},
348 { "nps400", ARC_OPCODE_ARC700 | ARC_OPCODE_NPS400, bfd_mach_arc_nps400,
349 E_ARC_MACH_NPS400, 0x00},
350 { "arcem", ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
351 EF_ARC_CPU_ARCV2EM, ARC_CD},
352 { "archs", ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
353 EF_ARC_CPU_ARCV2HS, ARC_CD},
357 /* Used by the arc_reloc_op table. Order is important. */
358 #define O_gotoff O_md1 /* @gotoff relocation. */
359 #define O_gotpc O_md2 /* @gotpc relocation. */
360 #define O_plt O_md3 /* @plt relocation. */
361 #define O_sda O_md4 /* @sda relocation. */
362 #define O_pcl O_md5 /* @pcl relocation. */
363 #define O_tlsgd O_md6 /* @tlsgd relocation. */
364 #define O_tlsie O_md7 /* @tlsie relocation. */
365 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
366 #define O_tpoff O_md9 /* @tpoff relocation. */
367 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
368 #define O_dtpoff O_md11 /* @dtpoff relocation. */
369 #define O_last O_dtpoff
371 /* Used to define a bracket as operand in tokens. */
372 #define O_bracket O_md32
374 /* Dummy relocation, to be sorted out. */
375 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
377 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
379 /* A table to map the spelling of a relocation operand into an appropriate
380 bfd_reloc_code_real_type type. The table is assumed to be ordered such
381 that op-O_literal indexes into it. */
382 #define ARC_RELOC_TABLE(op) \
383 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
385 : (int) (op) - (int) O_gotoff) ])
387 #define DEF(NAME, RELOC, REQ) \
388 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
390 static const struct arc_reloc_op_tag
392 /* String to lookup. */
394 /* Size of the string. */
396 /* Which operator to use. */
398 extended_bfd_reloc_code_real_type reloc;
399 /* Allows complex relocation expression like identifier@reloc +
401 unsigned int complex_expr : 1;
405 DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
406 DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
407 DEF (plt, BFD_RELOC_ARC_PLT32, 0),
408 DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
409 DEF (pcl, BFD_RELOC_ARC_PC32, 1),
410 DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0),
411 DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0),
412 DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0),
413 DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 1),
414 DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0),
415 DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0),
418 static const int arc_num_reloc_op
419 = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
421 /* Structure for relaxable instruction that have to be swapped with a
422 smaller alternative instruction. */
423 struct arc_relaxable_ins
425 /* Mnemonic that should be checked. */
426 const char *mnemonic_r;
428 /* Operands that should be checked.
429 Indexes of operands from operand array. */
430 enum rlx_operand_type operands[6];
432 /* Flags that should be checked. */
433 unsigned flag_classes[5];
435 /* Mnemonic (smaller) alternative to be used later for relaxation. */
436 const char *mnemonic_alt;
438 /* Index of operand that generic relaxation has to check. */
441 /* Base subtype index used. */
442 enum arc_rlx_types subtype;
445 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
446 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
447 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
451 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
452 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
453 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
458 /* ARC relaxation table. */
459 const relax_typeS md_relax_table[] =
466 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL),
467 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
471 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B),
472 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
477 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6),
478 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM),
479 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
481 /* LD_S a, [b, u7] ->
482 LD<zz><.x><.aa><.di> a, [b, s9] ->
483 LD<zz><.x><.aa><.di> a, [b, limm] */
484 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9),
485 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM),
486 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE),
491 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12),
492 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM),
493 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
497 SUB<.f> a, b, limm. */
498 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6),
499 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM),
500 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
502 /* MPY<.f> a, b, u6 ->
503 MPY<.f> a, b, limm. */
504 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM),
505 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
507 /* MOV<.f><.cc> b, u6 ->
508 MOV<.f><.cc> b, limm. */
509 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM),
510 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
512 /* ADD<.f><.cc> b, b, u6 ->
513 ADD<.f><.cc> b, b, limm. */
514 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM),
515 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
518 /* Order of this table's entries matters! */
519 const struct arc_relaxable_ins arc_relaxable_insns[] =
521 { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S },
522 { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S },
523 { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add",
524 2, ARC_RLX_ADD_RRU6},
525 { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2,
527 { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2,
529 { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET },
530 { 0 }, "ld_s", 3, ARC_RLX_LD_U7 },
531 { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET },
532 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 },
533 { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 },
534 { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 },
535 { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 },
536 { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2,
538 { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2,
540 { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2,
544 const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns);
546 /* Flags to set in the elf header. */
547 static flagword arc_eflag = 0x00;
549 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
550 symbolS * GOT_symbol = 0;
552 /* Set to TRUE when we assemble instructions. */
553 static bfd_boolean assembling_insn = FALSE;
555 /* Functions implementation. */
557 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
558 is encoded as 'middle-endian' for a little-endian target. FIXME!
559 this function is used for regular 4 byte instructions as well. */
562 md_number_to_chars_midend (char *buf, valueT val, int n)
566 md_number_to_chars (buf, (val & 0xffff0000) >> 16, 2);
567 md_number_to_chars (buf + 2, (val & 0xffff), 2);
571 md_number_to_chars (buf, val, n);
575 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
576 the relevant static global variables. */
579 arc_select_cpu (const char *arg)
584 for (i = 0; cpu_types[i].name; ++i)
586 if (!strcasecmp (cpu_types[i].name, arg))
588 arc_target = cpu_types[i].flags;
589 arc_target_name = cpu_types[i].name;
590 arc_features = cpu_types[i].features;
591 arc_mach_type = cpu_types[i].mach;
592 cpu_flags = cpu_types[i].eflags;
597 if (!cpu_types[i].name)
598 as_fatal (_("unknown architecture: %s\n"), arg);
599 gas_assert (cpu_flags != 0);
600 arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
603 /* Here ends all the ARCompact extension instruction assembling
607 arc_extra_reloc (int r_type)
610 symbolS *sym, *lab = NULL;
612 if (*input_line_pointer == '@')
613 input_line_pointer++;
614 c = get_symbol_name (&sym_name);
615 sym = symbol_find_or_make (sym_name);
616 restore_line_pointer (c);
617 if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
619 ++input_line_pointer;
621 c = get_symbol_name (&lab_name);
622 lab = symbol_find_or_make (lab_name);
623 restore_line_pointer (c);
626 /* These relocations exist as a mechanism for the compiler to tell the
627 linker how to patch the code if the tls model is optimised. However,
628 the relocation itself does not require any space within the assembler
629 fragment, and so we pass a size of 0.
631 The lines that generate these relocations look like this:
633 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
635 The '.tls_gd_ld @.tdata' is processed first and generates the
636 additional relocation, while the 'bl __tls_get_addr@plt' is processed
637 second and generates the additional branch.
639 It is possible that the additional relocation generated by the
640 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
641 while the 'bl __tls_get_addr@plt' will be generated as the first thing
642 in the next fragment. This will be fine; both relocations will still
643 appear to be at the same address in the generated object file.
644 However, this only works as the additional relocation is generated
645 with size of 0 bytes. */
647 = fix_new (frag_now, /* Which frag? */
648 frag_now_fix (), /* Where in that frag? */
649 0, /* size: 1, 2, or 4 usually. */
650 sym, /* X_add_symbol. */
651 0, /* X_add_number. */
652 FALSE, /* TRUE if PC-relative relocation. */
653 r_type /* Relocation type. */);
654 fixP->fx_subsy = lab;
658 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
659 symbolS *symbolP, addressT size)
664 if (*input_line_pointer == ',')
666 align = parse_align (1);
668 if (align == (addressT) -1)
683 bss_alloc (symbolP, size, align);
684 S_CLEAR_EXTERNAL (symbolP);
690 arc_lcomm (int ignore)
692 symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
695 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
698 /* Select the cpu we're assembling for. */
701 arc_option (int ignore ATTRIBUTE_UNUSED)
707 c = get_symbol_name (&cpu);
708 mach = arc_get_mach (cpu);
713 if (!mach_type_specified_p)
715 if ((!strcmp ("ARC600", cpu))
716 || (!strcmp ("ARC601", cpu))
717 || (!strcmp ("A6", cpu)))
719 md_parse_option (OPTION_MCPU, "arc600");
721 else if ((!strcmp ("ARC700", cpu))
722 || (!strcmp ("A7", cpu)))
724 md_parse_option (OPTION_MCPU, "arc700");
726 else if (!strcmp ("EM", cpu))
728 md_parse_option (OPTION_MCPU, "arcem");
730 else if (!strcmp ("HS", cpu))
732 md_parse_option (OPTION_MCPU, "archs");
735 as_fatal (_("could not find the architecture"));
737 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
738 as_fatal (_("could not set architecture and machine"));
741 if (arc_mach_type != mach)
742 as_warn (_("Command-line value overrides \".cpu\" directive"));
744 restore_line_pointer (c);
745 demand_empty_rest_of_line ();
749 restore_line_pointer (c);
750 as_bad (_("invalid identifier for \".cpu\""));
751 ignore_rest_of_line ();
754 /* Smartly print an expression. */
757 debug_exp (expressionS *t)
759 const char *name ATTRIBUTE_UNUSED;
760 const char *namemd ATTRIBUTE_UNUSED;
762 pr_debug ("debug_exp: ");
766 default: name = "unknown"; break;
767 case O_illegal: name = "O_illegal"; break;
768 case O_absent: name = "O_absent"; break;
769 case O_constant: name = "O_constant"; break;
770 case O_symbol: name = "O_symbol"; break;
771 case O_symbol_rva: name = "O_symbol_rva"; break;
772 case O_register: name = "O_register"; break;
773 case O_big: name = "O_big"; break;
774 case O_uminus: name = "O_uminus"; break;
775 case O_bit_not: name = "O_bit_not"; break;
776 case O_logical_not: name = "O_logical_not"; break;
777 case O_multiply: name = "O_multiply"; break;
778 case O_divide: name = "O_divide"; break;
779 case O_modulus: name = "O_modulus"; break;
780 case O_left_shift: name = "O_left_shift"; break;
781 case O_right_shift: name = "O_right_shift"; break;
782 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
783 case O_bit_or_not: name = "O_bit_or_not"; break;
784 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
785 case O_bit_and: name = "O_bit_and"; break;
786 case O_add: name = "O_add"; break;
787 case O_subtract: name = "O_subtract"; break;
788 case O_eq: name = "O_eq"; break;
789 case O_ne: name = "O_ne"; break;
790 case O_lt: name = "O_lt"; break;
791 case O_le: name = "O_le"; break;
792 case O_ge: name = "O_ge"; break;
793 case O_gt: name = "O_gt"; break;
794 case O_logical_and: name = "O_logical_and"; break;
795 case O_logical_or: name = "O_logical_or"; break;
796 case O_index: name = "O_index"; break;
797 case O_bracket: name = "O_bracket"; break;
802 default: namemd = "unknown"; break;
803 case O_gotoff: namemd = "O_gotoff"; break;
804 case O_gotpc: namemd = "O_gotpc"; break;
805 case O_plt: namemd = "O_plt"; break;
806 case O_sda: namemd = "O_sda"; break;
807 case O_pcl: namemd = "O_pcl"; break;
808 case O_tlsgd: namemd = "O_tlsgd"; break;
809 case O_tlsie: namemd = "O_tlsie"; break;
810 case O_tpoff9: namemd = "O_tpoff9"; break;
811 case O_tpoff: namemd = "O_tpoff"; break;
812 case O_dtpoff9: namemd = "O_dtpoff9"; break;
813 case O_dtpoff: namemd = "O_dtpoff"; break;
816 pr_debug ("%s (%s, %s, %d, %s)", name,
817 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
818 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
819 (int) t->X_add_number,
820 (t->X_md) ? namemd : "--");
825 /* Parse the arguments to an opcode. */
828 tokenize_arguments (char *str,
832 char *old_input_line_pointer;
833 bfd_boolean saw_comma = FALSE;
834 bfd_boolean saw_arg = FALSE;
839 const struct arc_reloc_op_tag *r;
843 memset (tok, 0, sizeof (*tok) * ntok);
845 /* Save and restore input_line_pointer around this function. */
846 old_input_line_pointer = input_line_pointer;
847 input_line_pointer = str;
849 while (*input_line_pointer)
852 switch (*input_line_pointer)
858 input_line_pointer++;
859 if (saw_comma || !saw_arg)
866 ++input_line_pointer;
870 tok->X_op = O_bracket;
877 input_line_pointer++;
881 tok->X_op = O_bracket;
887 /* We have labels, function names and relocations, all
888 starting with @ symbol. Sort them out. */
889 if (saw_arg && !saw_comma)
893 tok->X_op = O_symbol;
894 tok->X_md = O_absent;
896 if (*input_line_pointer != '@')
897 goto normalsymbol; /* This is not a relocation. */
901 /* A relocation opernad has the following form
902 @identifier@relocation_type. The identifier is already
904 if (tok->X_op != O_symbol)
906 as_bad (_("No valid label relocation operand"));
910 /* Parse @relocation_type. */
911 input_line_pointer++;
912 c = get_symbol_name (&reloc_name);
913 len = input_line_pointer - reloc_name;
916 as_bad (_("No relocation operand"));
920 /* Go through known relocation and try to find a match. */
921 r = &arc_reloc_op[0];
922 for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
924 && memcmp (reloc_name, r->name, len) == 0)
928 as_bad (_("Unknown relocation operand: @%s"), reloc_name);
932 *input_line_pointer = c;
933 SKIP_WHITESPACE_AFTER_NAME ();
934 /* Extra check for TLS: base. */
935 if (*input_line_pointer == '@')
938 if (tok->X_op_symbol != NULL
939 || tok->X_op != O_symbol)
941 as_bad (_("Unable to parse TLS base: %s"),
945 input_line_pointer++;
947 c = get_symbol_name (&sym_name);
948 base = symbol_find_or_make (sym_name);
949 tok->X_op = O_subtract;
950 tok->X_op_symbol = base;
951 restore_line_pointer (c);
952 tmpE.X_add_number = 0;
954 else if ((*input_line_pointer != '+')
955 && (*input_line_pointer != '-'))
957 tmpE.X_add_number = 0;
961 /* Parse the constant of a complex relocation expression
962 like @identifier@reloc +/- const. */
963 if (! r->complex_expr)
965 as_bad (_("@%s is not a complex relocation."), r->name);
969 if (tmpE.X_op != O_constant)
971 as_bad (_("Bad expression: @%s + %s."),
972 r->name, input_line_pointer);
978 tok->X_add_number = tmpE.X_add_number;
989 /* Can be a register. */
990 ++input_line_pointer;
994 if (saw_arg && !saw_comma)
997 tok->X_op = O_absent;
998 tok->X_md = O_absent;
1001 /* Legacy: There are cases when we have
1002 identifier@relocation_type, if it is the case parse the
1003 relocation type as well. */
1004 if (*input_line_pointer == '@')
1010 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1022 if (saw_comma || brk_lvl)
1024 input_line_pointer = old_input_line_pointer;
1030 as_bad (_("Brackets in operand field incorrect"));
1032 as_bad (_("extra comma"));
1034 as_bad (_("missing argument"));
1036 as_bad (_("missing comma or colon"));
1037 input_line_pointer = old_input_line_pointer;
1041 /* Parse the flags to a structure. */
1044 tokenize_flags (const char *str,
1045 struct arc_flags flags[],
1048 char *old_input_line_pointer;
1049 bfd_boolean saw_flg = FALSE;
1050 bfd_boolean saw_dot = FALSE;
1054 memset (flags, 0, sizeof (*flags) * nflg);
1056 /* Save and restore input_line_pointer around this function. */
1057 old_input_line_pointer = input_line_pointer;
1058 input_line_pointer = (char *) str;
1060 while (*input_line_pointer)
1062 switch (*input_line_pointer)
1069 input_line_pointer++;
1077 if (saw_flg && !saw_dot)
1080 if (num_flags >= nflg)
1083 flgnamelen = strspn (input_line_pointer,
1084 "abcdefghijklmnopqrstuvwxyz0123456789");
1085 if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1088 memcpy (flags->name, input_line_pointer, flgnamelen);
1090 input_line_pointer += flgnamelen;
1100 input_line_pointer = old_input_line_pointer;
1105 as_bad (_("extra dot"));
1107 as_bad (_("unrecognized flag"));
1109 as_bad (_("failed to parse flags"));
1110 input_line_pointer = old_input_line_pointer;
1114 /* Apply the fixups in order. */
1117 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1121 for (i = 0; i < insn->nfixups; i++)
1123 struct arc_fixup *fixup = &insn->fixups[i];
1124 int size, pcrel, offset = 0;
1126 /* FIXME! the reloc size is wrong in the BFD file.
1127 When it is fixed please delete me. */
1128 size = (insn->short_insn && !fixup->islong) ? 2 : 4;
1131 offset = (insn->short_insn) ? 2 : 4;
1133 /* Some fixups are only used internally, thus no howto. */
1134 if ((int) fixup->reloc == 0)
1135 as_fatal (_("Unhandled reloc type"));
1137 if ((int) fixup->reloc < 0)
1139 /* FIXME! the reloc size is wrong in the BFD file.
1140 When it is fixed please enable me.
1141 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1142 pcrel = fixup->pcrel;
1146 reloc_howto_type *reloc_howto =
1147 bfd_reloc_type_lookup (stdoutput,
1148 (bfd_reloc_code_real_type) fixup->reloc);
1149 gas_assert (reloc_howto);
1151 /* FIXME! the reloc size is wrong in the BFD file.
1152 When it is fixed please enable me.
1153 size = bfd_get_reloc_size (reloc_howto); */
1154 pcrel = reloc_howto->pc_relative;
1157 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1159 fragP->fr_file, fragP->fr_line,
1160 (fixup->reloc < 0) ? "Internal" :
1161 bfd_get_reloc_code_name (fixup->reloc),
1164 fix_new_exp (fragP, fix + offset,
1165 size, &fixup->exp, pcrel, fixup->reloc);
1167 /* Check for ZOLs, and update symbol info if any. */
1168 if (LP_INSN (insn->insn))
1170 gas_assert (fixup->exp.X_add_symbol);
1171 ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
1176 /* Actually output an instruction with its fixup. */
1179 emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax)
1183 pr_debug ("Emit insn : 0x%x\n", insn->insn);
1184 pr_debug ("\tShort : 0x%d\n", insn->short_insn);
1185 pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
1187 /* Write out the instruction. */
1188 if (insn->short_insn)
1194 md_number_to_chars (f, insn->insn, 2);
1195 md_number_to_chars_midend (f + 2, insn->limm, 4);
1196 dwarf2_emit_insn (6);
1202 md_number_to_chars (f, insn->insn, 2);
1203 dwarf2_emit_insn (2);
1212 md_number_to_chars_midend (f, insn->insn, 4);
1213 md_number_to_chars_midend (f + 4, insn->limm, 4);
1214 dwarf2_emit_insn (8);
1220 md_number_to_chars_midend (f, insn->insn, 4);
1221 dwarf2_emit_insn (4);
1226 apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
1230 emit_insn1 (struct arc_insn *insn)
1232 /* How frag_var's args are currently configured:
1233 - rs_machine_dependent, to dictate it's a relaxation frag.
1234 - FRAG_MAX_GROWTH, maximum size of instruction
1235 - 0, variable size that might grow...unused by generic relaxation.
1236 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1237 - s, opand expression.
1238 - 0, offset but it's unused.
1239 - 0, opcode but it's unused. */
1240 symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
1241 frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
1243 if (frag_room () < FRAG_MAX_GROWTH)
1245 /* Handle differently when frag literal memory is exhausted.
1246 This is used because when there's not enough memory left in
1247 the current frag, a new frag is created and the information
1248 we put into frag_now->tc_frag_data is disregarded. */
1250 struct arc_relax_type relax_info_copy;
1251 relax_substateT subtype = frag_now->fr_subtype;
1253 memcpy (&relax_info_copy, &frag_now->tc_frag_data,
1254 sizeof (struct arc_relax_type));
1256 frag_wane (frag_now);
1257 frag_grow (FRAG_MAX_GROWTH);
1259 memcpy (&frag_now->tc_frag_data, &relax_info_copy,
1260 sizeof (struct arc_relax_type));
1262 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1266 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1267 frag_now->fr_subtype, s, 0, 0);
1271 emit_insn (struct arc_insn *insn)
1276 emit_insn0 (insn, NULL, FALSE);
1279 /* Check whether a symbol involves a register. */
1282 contains_register (symbolS *sym)
1286 expressionS *ex = symbol_get_value_expression (sym);
1288 return ((O_register == ex->X_op)
1289 && !contains_register (ex->X_add_symbol)
1290 && !contains_register (ex->X_op_symbol));
1296 /* Returns the register number within a symbol. */
1299 get_register (symbolS *sym)
1301 if (!contains_register (sym))
1304 expressionS *ex = symbol_get_value_expression (sym);
1305 return regno (ex->X_add_number);
1308 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1309 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1312 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
1319 case BFD_RELOC_ARC_SDA_LDST:
1320 case BFD_RELOC_ARC_SDA_LDST1:
1321 case BFD_RELOC_ARC_SDA_LDST2:
1322 case BFD_RELOC_ARC_SDA16_LD:
1323 case BFD_RELOC_ARC_SDA16_LD1:
1324 case BFD_RELOC_ARC_SDA16_LD2:
1325 case BFD_RELOC_ARC_SDA16_ST2:
1326 case BFD_RELOC_ARC_SDA32_ME:
1333 /* Allocates a tok entry. */
1336 allocate_tok (expressionS *tok, int ntok, int cidx)
1338 if (ntok > MAX_INSN_ARGS - 2)
1339 return 0; /* No space left. */
1342 return 0; /* Incorect args. */
1344 memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
1347 return 1; /* Success. */
1348 return allocate_tok (tok, ntok - 1, cidx);
1351 /* Check if an particular ARC feature is enabled. */
1354 check_cpu_feature (insn_subclass_t sc)
1356 if (!(arc_features & ARC_CD)
1357 && is_code_density_p (sc))
1360 if (!(arc_features & ARC_SPFP)
1364 if (!(arc_features & ARC_DPFP)
1368 if (!(arc_features & ARC_FPUDA)
1375 /* Search forward through all variants of an opcode looking for a
1378 static const struct arc_opcode *
1379 find_opcode_match (const struct arc_opcode *first_opcode,
1382 struct arc_flags *first_pflag,
1386 const struct arc_opcode *opcode = first_opcode;
1388 int got_cpu_match = 0;
1389 expressionS bktok[MAX_INSN_ARGS];
1393 memset (&emptyE, 0, sizeof (emptyE));
1394 memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
1399 const unsigned char *opidx;
1400 const unsigned char *flgidx;
1401 int tokidx = 0, lnflg, i;
1402 const expressionS *t = &emptyE;
1404 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1405 frag_now->fr_file, frag_now->fr_line, opcode->opcode);
1407 /* Don't match opcodes that don't exist on this
1409 if (!(opcode->cpu & arc_target))
1412 if (!check_cpu_feature (opcode->subclass))
1418 /* Check the operands. */
1419 for (opidx = opcode->operands; *opidx; ++opidx)
1421 const struct arc_operand *operand = &arc_operands[*opidx];
1423 /* Only take input from real operands. */
1424 if ((operand->flags & ARC_OPERAND_FAKE)
1425 && !(operand->flags & ARC_OPERAND_BRAKET))
1428 /* When we expect input, make sure we have it. */
1432 /* Match operand type with expression type. */
1433 switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
1435 case ARC_OPERAND_IR:
1436 /* Check to be a register. */
1437 if ((tok[tokidx].X_op != O_register
1438 || !is_ir_num (tok[tokidx].X_add_number))
1439 && !(operand->flags & ARC_OPERAND_IGNORE))
1442 /* If expect duplicate, make sure it is duplicate. */
1443 if (operand->flags & ARC_OPERAND_DUPLICATE)
1445 /* Check for duplicate. */
1446 if (t->X_op != O_register
1447 || !is_ir_num (t->X_add_number)
1448 || (regno (t->X_add_number) !=
1449 regno (tok[tokidx].X_add_number)))
1453 /* Special handling? */
1454 if (operand->insert)
1456 const char *errmsg = NULL;
1457 (*operand->insert)(0,
1458 regno (tok[tokidx].X_add_number),
1462 if (operand->flags & ARC_OPERAND_IGNORE)
1464 /* Missing argument, create one. */
1465 if (!allocate_tok (tok, ntok - 1, tokidx))
1468 tok[tokidx].X_op = O_absent;
1479 case ARC_OPERAND_BRAKET:
1480 /* Check if bracket is also in opcode table as
1482 if (tok[tokidx].X_op != O_bracket)
1486 case ARC_OPERAND_LIMM:
1487 case ARC_OPERAND_SIGNED:
1488 case ARC_OPERAND_UNSIGNED:
1489 switch (tok[tokidx].X_op)
1497 /* Got an (too) early bracket, check if it is an
1498 ignored operand. N.B. This procedure works only
1499 when bracket is the last operand! */
1500 if (!(operand->flags & ARC_OPERAND_IGNORE))
1502 /* Insert the missing operand. */
1503 if (!allocate_tok (tok, ntok - 1, tokidx))
1506 tok[tokidx].X_op = O_absent;
1514 const struct arc_aux_reg *auxr;
1517 if (opcode->class != AUXREG)
1519 p = S_GET_NAME (tok[tokidx].X_add_symbol);
1522 auxr = &arc_aux_regs[0];
1523 for (j = 0; j < arc_num_aux_regs; j++, auxr++)
1524 if (len == auxr->length
1525 && strcasecmp (auxr->name, p) == 0
1526 && ((auxr->subclass == NONE)
1527 || check_cpu_feature (auxr->subclass)))
1529 /* We modify the token array here, safe in the
1530 knowledge, that if this was the wrong choice
1531 then the original contents will be restored
1533 tok[tokidx].X_op = O_constant;
1534 tok[tokidx].X_add_number = auxr->address;
1538 if (tok[tokidx].X_op != O_constant)
1543 /* Check the range. */
1544 if (operand->bits != 32
1545 && !(operand->flags & ARC_OPERAND_NCHK))
1547 offsetT min, max, val;
1548 val = tok[tokidx].X_add_number;
1550 if (operand->flags & ARC_OPERAND_SIGNED)
1552 max = (1 << (operand->bits - 1)) - 1;
1553 min = -(1 << (operand->bits - 1));
1557 max = (1 << operand->bits) - 1;
1561 if (val < min || val > max)
1564 /* Check alignmets. */
1565 if ((operand->flags & ARC_OPERAND_ALIGNED32)
1569 if ((operand->flags & ARC_OPERAND_ALIGNED16)
1573 else if (operand->flags & ARC_OPERAND_NCHK)
1575 if (operand->insert)
1577 const char *errmsg = NULL;
1578 (*operand->insert)(0,
1579 tok[tokidx].X_add_number,
1590 /* Check if it is register range. */
1591 if ((tok[tokidx].X_add_number == 0)
1592 && contains_register (tok[tokidx].X_add_symbol)
1593 && contains_register (tok[tokidx].X_op_symbol))
1597 regs = get_register (tok[tokidx].X_add_symbol);
1599 regs |= get_register (tok[tokidx].X_op_symbol);
1600 if (operand->insert)
1602 const char *errmsg = NULL;
1603 (*operand->insert)(0,
1615 if (operand->default_reloc == 0)
1616 goto match_failed; /* The operand needs relocation. */
1618 /* Relocs requiring long immediate. FIXME! make it
1619 generic and move it to a function. */
1620 switch (tok[tokidx].X_md)
1629 if (!(operand->flags & ARC_OPERAND_LIMM))
1632 if (!generic_reloc_p (operand->default_reloc))
1639 /* If expect duplicate, make sure it is duplicate. */
1640 if (operand->flags & ARC_OPERAND_DUPLICATE)
1642 if (t->X_op == O_illegal
1643 || t->X_op == O_absent
1644 || t->X_op == O_register
1645 || (t->X_add_number != tok[tokidx].X_add_number))
1652 /* Everything else should have been fake. */
1660 /* Setup ready for flag parsing. */
1662 for (i = 0; i < nflgs; i++)
1663 first_pflag [i].code = 0;
1665 /* Check the flags. Iterate over the valid flag classes. */
1666 for (flgidx = opcode->flags; *flgidx; ++flgidx)
1668 /* Get a valid flag class. */
1669 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
1670 const unsigned *flgopridx;
1673 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
1675 const struct arc_flag_operand *flg_operand;
1676 struct arc_flags *pflag = first_pflag;
1678 flg_operand = &arc_flag_operands[*flgopridx];
1679 for (i = 0; i < nflgs; i++, pflag++)
1681 /* Match against the parsed flags. */
1682 if (!strcmp (flg_operand->name, pflag->name))
1684 if (pflag->code != 0)
1687 pflag->code = *flgopridx;
1689 break; /* goto next flag class and parsed flag. */
1694 if (cl_flags->class == F_CLASS_REQUIRED && cl_matches == 0)
1696 if (cl_flags->class == F_CLASS_OPTIONAL && cl_matches > 1)
1699 /* Did I check all the parsed flags? */
1704 /* Possible match -- did we use all of our input? */
1714 /* Restore the original parameters. */
1715 memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
1718 while (++opcode - arc_opcodes < (int) arc_num_opcodes
1719 && !strcmp (opcode->name, first_opcode->name));
1722 *pcpumatch = got_cpu_match;
1727 /* Swap operand tokens. */
1730 swap_operand (expressionS *operand_array,
1732 unsigned destination)
1734 expressionS cpy_operand;
1735 expressionS *src_operand;
1736 expressionS *dst_operand;
1739 if (source == destination)
1742 src_operand = &operand_array[source];
1743 dst_operand = &operand_array[destination];
1744 size = sizeof (expressionS);
1746 /* Make copy of operand to swap with and swap. */
1747 memcpy (&cpy_operand, dst_operand, size);
1748 memcpy (dst_operand, src_operand, size);
1749 memcpy (src_operand, &cpy_operand, size);
1752 /* Check if *op matches *tok type.
1753 Returns FALSE if they don't match, TRUE if they match. */
1756 pseudo_operand_match (const expressionS *tok,
1757 const struct arc_operand_operation *op)
1759 offsetT min, max, val;
1761 const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
1767 if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
1769 else if (!(operand_real->flags & ARC_OPERAND_IR))
1771 val = tok->X_add_number + op->count;
1772 if (operand_real->flags & ARC_OPERAND_SIGNED)
1774 max = (1 << (operand_real->bits - 1)) - 1;
1775 min = -(1 << (operand_real->bits - 1));
1779 max = (1 << operand_real->bits) - 1;
1782 if (min <= val && val <= max)
1788 /* Handle all symbols as long immediates or signed 9. */
1789 if (operand_real->flags & ARC_OPERAND_LIMM ||
1790 ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
1795 if (operand_real->flags & ARC_OPERAND_IR)
1800 if (operand_real->flags & ARC_OPERAND_BRAKET)
1811 /* Find pseudo instruction in array. */
1813 static const struct arc_pseudo_insn *
1814 find_pseudo_insn (const char *opname,
1816 const expressionS *tok)
1818 const struct arc_pseudo_insn *pseudo_insn = NULL;
1819 const struct arc_operand_operation *op;
1823 for (i = 0; i < arc_num_pseudo_insn; ++i)
1825 pseudo_insn = &arc_pseudo_insns[i];
1826 if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
1828 op = pseudo_insn->operand;
1829 for (j = 0; j < ntok; ++j)
1830 if (!pseudo_operand_match (&tok[j], &op[j]))
1833 /* Found the right instruction. */
1841 /* Assumes the expressionS *tok is of sufficient size. */
1843 static const struct arc_opcode *
1844 find_special_case_pseudo (const char *opname,
1848 struct arc_flags *pflags)
1850 const struct arc_pseudo_insn *pseudo_insn = NULL;
1851 const struct arc_operand_operation *operand_pseudo;
1852 const struct arc_operand *operand_real;
1854 char construct_operand[MAX_CONSTR_STR];
1856 /* Find whether opname is in pseudo instruction array. */
1857 pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
1859 if (pseudo_insn == NULL)
1862 /* Handle flag, Limited to one flag at the moment. */
1863 if (pseudo_insn->flag_r != NULL)
1864 *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
1865 MAX_INSN_FLGS - *nflgs);
1867 /* Handle operand operations. */
1868 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
1870 operand_pseudo = &pseudo_insn->operand[i];
1871 operand_real = &arc_operands[operand_pseudo->operand_idx];
1873 if (operand_real->flags & ARC_OPERAND_BRAKET &&
1874 !operand_pseudo->needs_insert)
1877 /* Has to be inserted (i.e. this token does not exist yet). */
1878 if (operand_pseudo->needs_insert)
1880 if (operand_real->flags & ARC_OPERAND_BRAKET)
1882 tok[i].X_op = O_bracket;
1887 /* Check if operand is a register or constant and handle it
1889 if (operand_real->flags & ARC_OPERAND_IR)
1890 snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
1891 operand_pseudo->count);
1893 snprintf (construct_operand, MAX_CONSTR_STR, "%d",
1894 operand_pseudo->count);
1896 tokenize_arguments (construct_operand, &tok[i], 1);
1900 else if (operand_pseudo->count)
1902 /* Operand number has to be adjusted accordingly (by operand
1904 switch (tok[i].X_op)
1907 tok[i].X_add_number += operand_pseudo->count;
1920 /* Swap operands if necessary. Only supports one swap at the
1922 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
1924 operand_pseudo = &pseudo_insn->operand[i];
1926 if (operand_pseudo->swap_operand_idx == i)
1929 swap_operand (tok, i, operand_pseudo->swap_operand_idx);
1931 /* Prevent a swap back later by breaking out. */
1935 return (const struct arc_opcode *)
1936 hash_find (arc_opcode_hash, pseudo_insn->mnemonic_r);
1939 static const struct arc_opcode *
1940 find_special_case_flag (const char *opname,
1942 struct arc_flags *pflags)
1946 unsigned flag_idx, flag_arr_idx;
1947 size_t flaglen, oplen;
1948 const struct arc_flag_special *arc_flag_special_opcode;
1949 const struct arc_opcode *opcode;
1951 /* Search for special case instruction. */
1952 for (i = 0; i < arc_num_flag_special; i++)
1954 arc_flag_special_opcode = &arc_flag_special_cases[i];
1955 oplen = strlen (arc_flag_special_opcode->name);
1957 if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
1960 /* Found a potential special case instruction, now test for
1962 for (flag_arr_idx = 0;; ++flag_arr_idx)
1964 flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
1966 break; /* End of array, nothing found. */
1968 flagnm = arc_flag_operands[flag_idx].name;
1969 flaglen = strlen (flagnm);
1970 if (strcmp (opname + oplen, flagnm) == 0)
1972 opcode = (const struct arc_opcode *)
1973 hash_find (arc_opcode_hash,
1974 arc_flag_special_opcode->name);
1976 if (*nflgs + 1 > MAX_INSN_FLGS)
1978 memcpy (pflags[*nflgs].name, flagnm, flaglen);
1979 pflags[*nflgs].name[flaglen] = '\0';
1988 /* Used to find special case opcode. */
1990 static const struct arc_opcode *
1991 find_special_case (const char *opname,
1993 struct arc_flags *pflags,
1997 const struct arc_opcode *opcode;
1999 opcode = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
2002 opcode = find_special_case_flag (opname, nflgs, pflags);
2007 /* Given an opcode name, pre-tockenized set of argumenst and the
2008 opcode flags, take it all the way through emission. */
2011 assemble_tokens (const char *opname,
2014 struct arc_flags *pflags,
2017 bfd_boolean found_something = FALSE;
2018 const struct arc_opcode *opcode;
2021 /* Search opcodes. */
2022 opcode = (const struct arc_opcode *) hash_find (arc_opcode_hash, opname);
2024 /* Couldn't find opcode conventional way, try special cases. */
2026 opcode = find_special_case (opname, &nflgs, pflags, tok, &ntok);
2030 pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
2031 frag_now->fr_file, frag_now->fr_line, opcode->name,
2034 found_something = TRUE;
2035 opcode = find_opcode_match (opcode, tok, &ntok, pflags, nflgs, &cpumatch);
2038 struct arc_insn insn;
2039 assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
2045 if (found_something)
2048 as_bad (_("inappropriate arguments for opcode '%s'"), opname);
2050 as_bad (_("opcode '%s' not supported for target %s"), opname,
2054 as_bad (_("unknown opcode '%s'"), opname);
2057 /* The public interface to the instruction assembler. */
2060 md_assemble (char *str)
2063 expressionS tok[MAX_INSN_ARGS];
2066 struct arc_flags flags[MAX_INSN_FLGS];
2068 /* Split off the opcode. */
2069 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
2070 opname = xmalloc (opnamelen + 1);
2071 memcpy (opname, str, opnamelen);
2072 opname[opnamelen] = '\0';
2074 /* Signalize we are assmbling the instructions. */
2075 assembling_insn = TRUE;
2077 /* Tokenize the flags. */
2078 if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2080 as_bad (_("syntax error"));
2084 /* Scan up to the end of the mnemonic which must end in space or end
2087 for (; *str != '\0'; str++)
2091 /* Tokenize the rest of the line. */
2092 if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2094 as_bad (_("syntax error"));
2098 /* Finish it off. */
2099 assemble_tokens (opname, tok, ntok, flags, nflg);
2100 assembling_insn = FALSE;
2103 /* Callback to insert a register into the hash table. */
2106 declare_register (const char *name, int number)
2109 symbolS *regS = symbol_create (name, reg_section,
2110 number, &zero_address_frag);
2112 err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
2114 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2118 /* Construct symbols for each of the general registers. */
2121 declare_register_set (void)
2124 for (i = 0; i < 64; ++i)
2128 sprintf (name, "r%d", i);
2129 declare_register (name, i);
2130 if ((i & 0x01) == 0)
2132 sprintf (name, "r%dr%d", i, i+1);
2133 declare_register (name, i);
2138 /* Port-specific assembler initialization. This function is called
2139 once, at assembler startup time. */
2146 if (!mach_type_specified_p)
2147 arc_select_cpu ("arc700");
2149 /* The endianness can be chosen "at the factory". */
2150 target_big_endian = byte_order == BIG_ENDIAN;
2152 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
2153 as_warn (_("could not set architecture and machine"));
2155 /* Set elf header flags. */
2156 bfd_set_private_flags (stdoutput, arc_eflag);
2158 /* Set up a hash table for the instructions. */
2159 arc_opcode_hash = hash_new ();
2160 if (arc_opcode_hash == NULL)
2161 as_fatal (_("Virtual memory exhausted"));
2163 /* Initialize the hash table with the insns. */
2164 for (i = 0; i < arc_num_opcodes;)
2166 const char *name, *retval;
2168 name = arc_opcodes[i].name;
2169 retval = hash_insert (arc_opcode_hash, name, (void *) &arc_opcodes[i]);
2171 as_fatal (_("internal error: can't hash opcode '%s': %s"),
2174 while (++i < arc_num_opcodes
2175 && (arc_opcodes[i].name == name
2176 || !strcmp (arc_opcodes[i].name, name)))
2180 /* Register declaration. */
2181 arc_reg_hash = hash_new ();
2182 if (arc_reg_hash == NULL)
2183 as_fatal (_("Virtual memory exhausted"));
2185 declare_register_set ();
2186 declare_register ("gp", 26);
2187 declare_register ("fp", 27);
2188 declare_register ("sp", 28);
2189 declare_register ("ilink", 29);
2190 declare_register ("ilink1", 29);
2191 declare_register ("ilink2", 30);
2192 declare_register ("blink", 31);
2194 declare_register ("mlo", 57);
2195 declare_register ("mmid", 58);
2196 declare_register ("mhi", 59);
2198 declare_register ("acc1", 56);
2199 declare_register ("acc2", 57);
2201 declare_register ("lp_count", 60);
2202 declare_register ("pcl", 63);
2204 /* Initialize the last instructions. */
2205 memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2208 /* Write a value out to the object file, using the appropriate
2212 md_number_to_chars (char *buf,
2216 if (target_big_endian)
2217 number_to_chars_bigendian (buf, val, n);
2219 number_to_chars_littleendian (buf, val, n);
2222 /* Round up a section size to the appropriate boundary. */
2225 md_section_align (segT segment,
2228 int align = bfd_get_section_alignment (stdoutput, segment);
2230 return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
2233 /* The location from which a PC relative jump should be calculated,
2234 given a PC relative reloc. */
2237 md_pcrel_from_section (fixS *fixP,
2240 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
2242 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
2244 if (fixP->fx_addsy != (symbolS *) NULL
2245 && (!S_IS_DEFINED (fixP->fx_addsy)
2246 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2248 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
2250 /* The symbol is undefined (or is defined but not in this section).
2251 Let the linker figure it out. */
2255 if ((int) fixP->fx_r_type < 0)
2257 /* These are the "internal" relocations. Align them to
2258 32 bit boundary (PCL), for the moment. */
2263 switch (fixP->fx_r_type)
2265 case BFD_RELOC_ARC_PC32:
2266 /* The hardware calculates relative to the start of the
2267 insn, but this relocation is relative to location of the
2268 LIMM, compensate. The base always needs to be
2269 substracted by 4 as we do not support this type of PCrel
2270 relocation for short instructions. */
2273 case BFD_RELOC_ARC_PLT32:
2274 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2275 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2276 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2277 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2279 case BFD_RELOC_ARC_S21H_PCREL:
2280 case BFD_RELOC_ARC_S25H_PCREL:
2281 case BFD_RELOC_ARC_S13_PCREL:
2282 case BFD_RELOC_ARC_S21W_PCREL:
2283 case BFD_RELOC_ARC_S25W_PCREL:
2287 as_bad_where (fixP->fx_file, fixP->fx_line,
2288 _("unhandled reloc %s in md_pcrel_from_section"),
2289 bfd_get_reloc_code_name (fixP->fx_r_type));
2294 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
2295 fixP->fx_frag->fr_address, fixP->fx_where, base,
2296 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
2297 fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
2302 /* Given a BFD relocation find the coresponding operand. */
2304 static const struct arc_operand *
2305 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
2309 for (i = 0; i < arc_num_operands; i++)
2310 if (arc_operands[i].default_reloc == reloc)
2311 return &arc_operands[i];
2315 /* Insert an operand value into an instruction. */
2318 insert_operand (unsigned insn,
2319 const struct arc_operand *operand,
2324 offsetT min = 0, max = 0;
2326 if (operand->bits != 32
2327 && !(operand->flags & ARC_OPERAND_NCHK)
2328 && !(operand->flags & ARC_OPERAND_FAKE))
2330 if (operand->flags & ARC_OPERAND_SIGNED)
2332 max = (1 << (operand->bits - 1)) - 1;
2333 min = -(1 << (operand->bits - 1));
2337 max = (1 << operand->bits) - 1;
2341 if (val < min || val > max)
2342 as_bad_value_out_of_range (_("operand"),
2343 val, min, max, file, line);
2346 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2347 min, val, max, insn);
2349 if ((operand->flags & ARC_OPERAND_ALIGNED32)
2351 as_bad_where (file, line,
2352 _("Unaligned operand. Needs to be 32bit aligned"));
2354 if ((operand->flags & ARC_OPERAND_ALIGNED16)
2356 as_bad_where (file, line,
2357 _("Unaligned operand. Needs to be 16bit aligned"));
2359 if (operand->insert)
2361 const char *errmsg = NULL;
2363 insn = (*operand->insert) (insn, val, &errmsg);
2365 as_warn_where (file, line, "%s", errmsg);
2369 if (operand->flags & ARC_OPERAND_TRUNCATE)
2371 if (operand->flags & ARC_OPERAND_ALIGNED32)
2373 if (operand->flags & ARC_OPERAND_ALIGNED16)
2376 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2381 /* Apply a fixup to the object code. At this point all symbol values
2382 should be fully resolved, and we attempt to completely resolve the
2383 reloc. If we can not do that, we determine the correct reloc code
2384 and put it back in the fixup. To indicate that a fixup has been
2385 eliminated, set fixP->fx_done. */
2388 md_apply_fix (fixS *fixP,
2392 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
2393 valueT value = *valP;
2395 symbolS *fx_addsy, *fx_subsy;
2397 segT add_symbol_segment = absolute_section;
2398 segT sub_symbol_segment = absolute_section;
2399 const struct arc_operand *operand = NULL;
2400 extended_bfd_reloc_code_real_type reloc;
2402 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2403 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2404 ((int) fixP->fx_r_type < 0) ? "Internal":
2405 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2408 fx_addsy = fixP->fx_addsy;
2409 fx_subsy = fixP->fx_subsy;
2414 add_symbol_segment = S_GET_SEGMENT (fx_addsy);
2418 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
2419 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
2420 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
2422 resolve_symbol_value (fx_subsy);
2423 sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
2425 if (sub_symbol_segment == absolute_section)
2427 /* The symbol is really a constant. */
2428 fx_offset -= S_GET_VALUE (fx_subsy);
2433 as_bad_where (fixP->fx_file, fixP->fx_line,
2434 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2435 fx_addsy ? S_GET_NAME (fx_addsy) : "0",
2436 segment_name (add_symbol_segment),
2437 S_GET_NAME (fx_subsy),
2438 segment_name (sub_symbol_segment));
2444 && !S_IS_WEAK (fx_addsy))
2446 if (add_symbol_segment == seg
2449 value += S_GET_VALUE (fx_addsy);
2450 value -= md_pcrel_from_section (fixP, seg);
2452 fixP->fx_pcrel = FALSE;
2454 else if (add_symbol_segment == absolute_section)
2456 value = fixP->fx_offset;
2457 fx_offset += S_GET_VALUE (fixP->fx_addsy);
2459 fixP->fx_pcrel = FALSE;
2464 fixP->fx_done = TRUE;
2469 && ((S_IS_DEFINED (fx_addsy)
2470 && S_GET_SEGMENT (fx_addsy) != seg)
2471 || S_IS_WEAK (fx_addsy)))
2472 value += md_pcrel_from_section (fixP, seg);
2474 switch (fixP->fx_r_type)
2476 case BFD_RELOC_ARC_32_ME:
2477 /* This is a pc-relative value in a LIMM. Adjust it to the
2478 address of the instruction not to the address of the
2479 LIMM. Note: it is not anylonger valid this afirmation as
2480 the linker consider ARC_PC32 a fixup to entire 64 bit
2482 fixP->fx_offset += fixP->fx_frag->fr_address;
2485 fixP->fx_r_type = BFD_RELOC_ARC_PC32;
2487 case BFD_RELOC_ARC_PC32:
2488 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2491 if ((int) fixP->fx_r_type < 0)
2492 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2498 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2499 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2500 ((int) fixP->fx_r_type < 0) ? "Internal":
2501 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2505 /* Now check for TLS relocations. */
2506 reloc = fixP->fx_r_type;
2509 case BFD_RELOC_ARC_TLS_DTPOFF:
2510 case BFD_RELOC_ARC_TLS_LE_32:
2514 case BFD_RELOC_ARC_TLS_GD_GOT:
2515 case BFD_RELOC_ARC_TLS_IE_GOT:
2516 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2519 case BFD_RELOC_ARC_TLS_GD_LD:
2520 gas_assert (!fixP->fx_offset);
2523 = (S_GET_VALUE (fixP->fx_subsy)
2524 - fixP->fx_frag->fr_address- fixP->fx_where);
2525 fixP->fx_subsy = NULL;
2527 case BFD_RELOC_ARC_TLS_GD_CALL:
2528 /* These two relocs are there just to allow ld to change the tls
2529 model for this symbol, by patching the code. The offset -
2530 and scale, if any - will be installed by the linker. */
2531 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2534 case BFD_RELOC_ARC_TLS_LE_S9:
2535 case BFD_RELOC_ARC_TLS_DTPOFF_S9:
2536 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2548 /* Addjust the value if we have a constant. */
2551 /* For hosts with longs bigger than 32-bits make sure that the top
2552 bits of a 32-bit negative value read in by the parser are set,
2553 so that the correct comparisons are made. */
2554 if (value & 0x80000000)
2555 value |= (-1L << 31);
2557 reloc = fixP->fx_r_type;
2565 case BFD_RELOC_ARC_32_PCREL:
2566 md_number_to_chars (fixpos, value, fixP->fx_size);
2569 case BFD_RELOC_ARC_GOTPC32:
2570 /* I cannot fix an GOTPC relocation because I need to relax it
2571 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2572 as_bad (_("Unsupported operation on reloc"));
2575 case BFD_RELOC_ARC_TLS_DTPOFF:
2576 case BFD_RELOC_ARC_TLS_LE_32:
2577 gas_assert (!fixP->fx_addsy);
2578 gas_assert (!fixP->fx_subsy);
2580 case BFD_RELOC_ARC_GOTOFF:
2581 case BFD_RELOC_ARC_32_ME:
2582 case BFD_RELOC_ARC_PC32:
2583 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2586 case BFD_RELOC_ARC_PLT32:
2587 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2590 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2591 reloc = BFD_RELOC_ARC_S25W_PCREL;
2594 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2595 reloc = BFD_RELOC_ARC_S21H_PCREL;
2598 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2599 reloc = BFD_RELOC_ARC_S25W_PCREL;
2602 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2603 reloc = BFD_RELOC_ARC_S21W_PCREL;
2605 case BFD_RELOC_ARC_S25W_PCREL:
2606 case BFD_RELOC_ARC_S21W_PCREL:
2607 case BFD_RELOC_ARC_S21H_PCREL:
2608 case BFD_RELOC_ARC_S25H_PCREL:
2609 case BFD_RELOC_ARC_S13_PCREL:
2611 operand = find_operand_for_reloc (reloc);
2612 gas_assert (operand);
2617 if ((int) fixP->fx_r_type >= 0)
2618 as_fatal (_("unhandled relocation type %s"),
2619 bfd_get_reloc_code_name (fixP->fx_r_type));
2621 /* The rest of these fixups needs to be completely resolved as
2623 if (fixP->fx_addsy != 0
2624 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
2625 as_bad_where (fixP->fx_file, fixP->fx_line,
2626 _("non-absolute expression in constant field"));
2628 gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
2629 operand = &arc_operands[-(int) fixP->fx_r_type];
2634 if (target_big_endian)
2636 switch (fixP->fx_size)
2639 insn = bfd_getb32 (fixpos);
2642 insn = bfd_getb16 (fixpos);
2645 as_bad_where (fixP->fx_file, fixP->fx_line,
2646 _("unknown fixup size"));
2652 switch (fixP->fx_size)
2655 insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
2658 insn = bfd_getl16 (fixpos);
2661 as_bad_where (fixP->fx_file, fixP->fx_line,
2662 _("unknown fixup size"));
2666 insn = insert_operand (insn, operand, (offsetT) value,
2667 fixP->fx_file, fixP->fx_line);
2669 md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
2672 /* Prepare machine-dependent frags for relaxation.
2674 Called just before relaxation starts. Any symbol that is now undefined
2675 will not become defined.
2677 Return the correct fr_subtype in the frag.
2679 Return the initial "guess for fr_var" to caller. The guess for fr_var
2680 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
2681 or fr_var contributes to our returned value.
2683 Although it may not be explicit in the frag, pretend
2684 fr_var starts with a value. */
2687 md_estimate_size_before_relax (fragS *fragP,
2692 /* If the symbol is not located within the same section AND it's not
2693 an absolute section, use the maximum. OR if the symbol is a
2694 constant AND the insn is by nature not pc-rel, use the maximum.
2695 OR if the symbol is being equated against another symbol, use the
2696 maximum. OR if the symbol is weak use the maximum. */
2697 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
2698 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2699 || (symbol_constant_p (fragP->fr_symbol)
2700 && !fragP->tc_frag_data.pcrel)
2701 || symbol_equated_p (fragP->fr_symbol)
2702 || S_IS_WEAK (fragP->fr_symbol))
2704 while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
2705 ++fragP->fr_subtype;
2708 growth = md_relax_table[fragP->fr_subtype].rlx_length;
2709 fragP->fr_var = growth;
2711 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
2712 fragP->fr_file, fragP->fr_line, growth);
2717 /* Translate internal representation of relocation info to BFD target
2721 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
2725 bfd_reloc_code_real_type code;
2727 reloc = (arelent *) xmalloc (sizeof (* reloc));
2728 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2729 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
2730 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2732 /* Make sure none of our internal relocations make it this far.
2733 They'd better have been fully resolved by this point. */
2734 gas_assert ((int) fixP->fx_r_type > 0);
2736 code = fixP->fx_r_type;
2738 /* if we have something like add gp, pcl,
2739 _GLOBAL_OFFSET_TABLE_@gotpc. */
2740 if (code == BFD_RELOC_ARC_GOTPC32
2742 && fixP->fx_addsy == GOT_symbol)
2743 code = BFD_RELOC_ARC_GOTPC;
2745 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2746 if (reloc->howto == NULL)
2748 as_bad_where (fixP->fx_file, fixP->fx_line,
2749 _("cannot represent `%s' relocation in object file"),
2750 bfd_get_reloc_code_name (code));
2754 if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
2755 as_fatal (_("internal error? cannot generate `%s' relocation"),
2756 bfd_get_reloc_code_name (code));
2758 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
2760 if (code == BFD_RELOC_ARC_TLS_DTPOFF
2761 || code == BFD_RELOC_ARC_TLS_DTPOFF_S9)
2764 = fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL;
2765 /* We just want to store a 24 bit index, but we have to wait
2766 till after write_contents has been called via
2767 bfd_map_over_sections before we can get the index from
2768 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
2769 function is elf32-arc.c has to pick up the slack.
2770 Unfortunately, this leads to problems with hosts that have
2771 pointers wider than long (bfd_vma). There would be various
2772 ways to handle this, all error-prone :-( */
2773 reloc->addend = (bfd_vma) sym;
2774 if ((asymbol *) reloc->addend != sym)
2776 as_bad ("Can't store pointer\n");
2781 reloc->addend = fixP->fx_offset;
2786 /* Perform post-processing of machine-dependent frags after relaxation.
2787 Called after relaxation is finished.
2788 In: Address of frag.
2789 fr_type == rs_machine_dependent.
2790 fr_subtype is what the address relaxed to.
2792 Out: Any fixS:s and constants are set up. */
2795 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
2796 segT segment ATTRIBUTE_UNUSED,
2799 const relax_typeS *table_entry;
2801 const struct arc_opcode *opcode;
2802 struct arc_insn insn;
2804 struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
2806 fix = (fragP->fr_fix < 0 ? 0 : fragP->fr_fix);
2807 dest = fragP->fr_literal + fix;
2808 table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
2810 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
2811 fragP->fr_file, fragP->fr_line,
2812 fragP->fr_subtype, fix, fragP->fr_var);
2814 if (fragP->fr_subtype <= 0
2815 && fragP->fr_subtype >= arc_num_relax_opcodes)
2816 as_fatal (_("no relaxation found for this instruction."));
2818 opcode = &arc_relax_opcodes[fragP->fr_subtype];
2820 assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
2821 relax_arg->nflg, &insn);
2823 apply_fixups (&insn, fragP, fix);
2825 size = insn.short_insn ? (insn.has_limm ? 6 : 2) : (insn.has_limm ? 8 : 4);
2826 gas_assert (table_entry->rlx_length == size);
2827 emit_insn0 (&insn, dest, TRUE);
2829 fragP->fr_fix += table_entry->rlx_length;
2833 /* We have no need to default values of symbols. We could catch
2834 register names here, but that is handled by inserting them all in
2835 the symbol table to begin with. */
2838 md_undefined_symbol (char *name)
2840 /* The arc abi demands that a GOT[0] should be referencible as
2841 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
2842 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
2844 && (*(name+1) == 'G')
2845 && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))
2847 && (*(name+1) == 'D')
2848 && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0)))
2852 if (symbol_find (name))
2853 as_bad ("GOT already in symbol table");
2855 GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
2856 (valueT) 0, &zero_address_frag);
2863 /* Turn a string in input_line_pointer into a floating point constant
2864 of type type, and store the appropriate bytes in *litP. The number
2865 of LITTLENUMS emitted is stored in *sizeP. An error message is
2866 returned, or NULL on OK. */
2869 md_atof (int type, char *litP, int *sizeP)
2871 return ieee_md_atof (type, litP, sizeP, target_big_endian);
2874 /* Called for any expression that can not be recognized. When the
2875 function is called, `input_line_pointer' will point to the start of
2879 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
2881 char *p = input_line_pointer;
2884 input_line_pointer++;
2885 expressionP->X_op = O_symbol;
2886 expression (expressionP);
2890 /* This function is called from the function 'expression', it attempts
2891 to parse special names (in our case register names). It fills in
2892 the expression with the identified register. It returns TRUE if
2893 it is a register and FALSE otherwise. */
2896 arc_parse_name (const char *name,
2897 struct expressionS *e)
2901 if (!assembling_insn)
2904 /* Handle only registers. */
2905 if (e->X_op != O_absent)
2908 sym = hash_find (arc_reg_hash, name);
2911 e->X_op = O_register;
2912 e->X_add_number = S_GET_VALUE (sym);
2919 Invocation line includes a switch not recognized by the base assembler.
2920 See if it's a processor-specific option.
2922 New options (supported) are:
2924 -mcpu=<cpu name> Assemble for selected processor
2925 -EB/-mbig-endian Big-endian
2926 -EL/-mlittle-endian Little-endian
2927 -mrelax Enable relaxation
2929 The following CPU names are recognized:
2930 arc700, av2em, av2hs. */
2933 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
2939 return md_parse_option (OPTION_MCPU, "arc600");
2942 return md_parse_option (OPTION_MCPU, "arc700");
2945 return md_parse_option (OPTION_MCPU, "arcem");
2948 return md_parse_option (OPTION_MCPU, "archs");
2952 arc_select_cpu (arg);
2953 mach_type_specified_p = 1;
2958 arc_target_format = "elf32-bigarc";
2959 byte_order = BIG_ENDIAN;
2963 arc_target_format = "elf32-littlearc";
2964 byte_order = LITTLE_ENDIAN;
2968 /* This option has an effect only on ARC EM. */
2969 if (arc_target & ARC_OPCODE_ARCv2EM)
2970 arc_features |= ARC_CD;
2972 as_warn (_("Code density option invalid for selected CPU"));
2976 relaxation_state = 1;
2979 case OPTION_USER_MODE:
2980 case OPTION_LD_EXT_MASK:
2983 case OPTION_BARREL_SHIFT:
2984 case OPTION_MIN_MAX:
2989 /* Dummy options are accepted but have no effect. */
2993 arc_features |= ARC_SPFP;
2997 arc_features |= ARC_DPFP;
3000 case OPTION_XMAC_D16:
3001 case OPTION_XMAC_24:
3002 case OPTION_DSP_PACKA:
3005 case OPTION_TELEPHONY:
3006 case OPTION_XYMEMORY:
3010 /* Dummy options are accepted but have no effect. */
3014 /* This option has an effect only on ARC EM. */
3015 if (arc_target & ARC_OPCODE_ARCv2EM)
3016 arc_features |= ARC_FPUDA;
3018 as_warn (_("FPUDA invalid for selected CPU"));
3029 md_show_usage (FILE *stream)
3031 fprintf (stream, _("ARC-specific assembler options:\n"));
3033 fprintf (stream, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
3035 " -mcode-density\t enable code density option for ARC EM\n");
3037 fprintf (stream, _("\
3038 -EB assemble code for a big-endian cpu\n"));
3039 fprintf (stream, _("\
3040 -EL assemble code for a little-endian cpu\n"));
3041 fprintf (stream, _("\
3042 -mrelax Enable relaxation\n"));
3046 /* Find the proper relocation for the given opcode. */
3048 static extended_bfd_reloc_code_real_type
3049 find_reloc (const char *name,
3050 const char *opcodename,
3051 const struct arc_flags *pflags,
3053 extended_bfd_reloc_code_real_type reloc)
3057 bfd_boolean found_flag, tmp;
3058 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
3060 for (i = 0; i < arc_num_equiv_tab; i++)
3062 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
3064 /* Find the entry. */
3065 if (strcmp (name, r->name))
3067 if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
3074 unsigned * psflg = (unsigned *)r->flags;
3078 for (j = 0; j < nflg; j++)
3079 if (!strcmp (pflags[j].name,
3080 arc_flag_operands[*psflg].name))
3101 if (reloc != r->oldreloc)
3108 if (ret == BFD_RELOC_UNUSED)
3109 as_bad (_("Unable to find %s relocation for instruction %s"),
3114 /* All the symbol types that are allowed to be used for
3118 may_relax_expr (expressionS tok)
3120 /* Check if we have unrelaxable relocs. */
3145 /* Checks if flags are in line with relaxable insn. */
3148 relaxable_flag (const struct arc_relaxable_ins *ins,
3149 const struct arc_flags *pflags,
3152 unsigned flag_class,
3157 const struct arc_flag_operand *flag_opand;
3158 int i, counttrue = 0;
3160 /* Iterate through flags classes. */
3161 while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
3163 /* Iterate through flags in flag class. */
3164 while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
3167 flag_opand = &arc_flag_operands[flag];
3168 /* Iterate through flags in ins to compare. */
3169 for (i = 0; i < nflgs; ++i)
3171 if (strcmp (flag_opand->name, pflags[i].name) == 0)
3182 /* If counttrue == nflgs, then all flags have been found. */
3183 return (counttrue == nflgs ? TRUE : FALSE);
3186 /* Checks if operands are in line with relaxable insn. */
3189 relaxable_operand (const struct arc_relaxable_ins *ins,
3190 const expressionS *tok,
3193 const enum rlx_operand_type *operand = &ins->operands[0];
3196 while (*operand != EMPTY)
3198 const expressionS *epr = &tok[i];
3200 if (i != 0 && i >= ntok)
3206 if (!(epr->X_op == O_multiply
3207 || epr->X_op == O_divide
3208 || epr->X_op == O_modulus
3209 || epr->X_op == O_add
3210 || epr->X_op == O_subtract
3211 || epr->X_op == O_symbol))
3217 || (epr->X_add_number != tok[i - 1].X_add_number))
3221 if (epr->X_op != O_register)
3226 if (epr->X_op != O_register)
3229 switch (epr->X_add_number)
3231 case 0: case 1: case 2: case 3:
3232 case 12: case 13: case 14: case 15:
3239 case REGISTER_NO_GP:
3240 if ((epr->X_op != O_register)
3241 || (epr->X_add_number == 26)) /* 26 is the gp register. */
3246 if (epr->X_op != O_bracket)
3251 /* Don't understand, bail out. */
3257 operand = &ins->operands[i];
3260 return (i == ntok ? TRUE : FALSE);
3263 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3266 relax_insn_p (const struct arc_opcode *opcode,
3267 const expressionS *tok,
3269 const struct arc_flags *pflags,
3273 bfd_boolean rv = FALSE;
3275 /* Check the relaxation table. */
3276 for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
3278 const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
3280 if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
3281 && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
3282 && relaxable_operand (arc_rlx_ins, tok, ntok)
3283 && relaxable_flag (arc_rlx_ins, pflags, nflg))
3286 frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
3287 memcpy (&frag_now->tc_frag_data.tok, tok,
3288 sizeof (expressionS) * ntok);
3289 memcpy (&frag_now->tc_frag_data.pflags, pflags,
3290 sizeof (struct arc_flags) * nflg);
3291 frag_now->tc_frag_data.nflg = nflg;
3292 frag_now->tc_frag_data.ntok = ntok;
3300 /* Turn an opcode description and a set of arguments into
3301 an instruction and a fixup. */
3304 assemble_insn (const struct arc_opcode *opcode,
3305 const expressionS *tok,
3307 const struct arc_flags *pflags,
3309 struct arc_insn *insn)
3311 const expressionS *reloc_exp = NULL;
3313 const unsigned char *argidx;
3316 unsigned char pcrel = 0;
3317 bfd_boolean needGOTSymbol;
3318 bfd_boolean has_delay_slot = FALSE;
3319 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3321 memset (insn, 0, sizeof (*insn));
3322 image = opcode->opcode;
3324 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3325 frag_now->fr_file, frag_now->fr_line, opcode->name,
3328 /* Handle operands. */
3329 for (argidx = opcode->operands; *argidx; ++argidx)
3331 const struct arc_operand *operand = &arc_operands[*argidx];
3332 const expressionS *t = (const expressionS *) 0;
3334 if ((operand->flags & ARC_OPERAND_FAKE)
3335 && !(operand->flags & ARC_OPERAND_BRAKET))
3338 if (operand->flags & ARC_OPERAND_DUPLICATE)
3340 /* Duplicate operand, already inserted. */
3352 /* Regardless if we have a reloc or not mark the instruction
3353 limm if it is the case. */
3354 if (operand->flags & ARC_OPERAND_LIMM)
3355 insn->has_limm = TRUE;
3360 image = insert_operand (image, operand, regno (t->X_add_number),
3365 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
3367 if (operand->flags & ARC_OPERAND_LIMM)
3368 insn->limm = t->X_add_number;
3372 /* Ignore brackets. */
3376 gas_assert (operand->flags & ARC_OPERAND_IGNORE);
3380 /* Maybe register range. */
3381 if ((t->X_add_number == 0)
3382 && contains_register (t->X_add_symbol)
3383 && contains_register (t->X_op_symbol))
3387 regs = get_register (t->X_add_symbol);
3389 regs |= get_register (t->X_op_symbol);
3390 image = insert_operand (image, operand, regs, NULL, 0);
3395 /* This operand needs a relocation. */
3396 needGOTSymbol = FALSE;
3401 if (opcode->class == JUMP)
3402 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3403 _("Unable to use @plt relocatio for insn %s"),
3405 needGOTSymbol = TRUE;
3406 reloc = find_reloc ("plt", opcode->name,
3408 operand->default_reloc);
3413 needGOTSymbol = TRUE;
3414 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3417 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3418 if (ARC_SHORT (opcode->mask) || opcode->class == JUMP)
3419 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3420 _("Unable to use @pcl relocation for insn %s"),
3424 reloc = find_reloc ("sda", opcode->name,
3426 operand->default_reloc);
3430 needGOTSymbol = TRUE;
3435 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3438 case O_tpoff9: /*FIXME! Check for the conditionality of
3440 case O_dtpoff9: /*FIXME! Check for the conditionality of
3442 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3446 /* Just consider the default relocation. */
3447 reloc = operand->default_reloc;
3451 if (needGOTSymbol && (GOT_symbol == NULL))
3452 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
3459 /* sanity checks. */
3460 reloc_howto_type *reloc_howto
3461 = bfd_reloc_type_lookup (stdoutput,
3462 (bfd_reloc_code_real_type) reloc);
3463 unsigned reloc_bitsize = reloc_howto->bitsize;
3464 if (reloc_howto->rightshift)
3465 reloc_bitsize -= reloc_howto->rightshift;
3466 if (reloc_bitsize != operand->bits)
3468 as_bad (_("invalid relocation %s for field"),
3469 bfd_get_reloc_code_name (reloc));
3474 if (insn->nfixups >= MAX_INSN_FIXUPS)
3475 as_fatal (_("too many fixups"));
3477 struct arc_fixup *fixup;
3478 fixup = &insn->fixups[insn->nfixups++];
3480 fixup->reloc = reloc;
3481 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
3482 fixup->pcrel = pcrel;
3483 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
3490 for (i = 0; i < nflg; i++)
3492 const struct arc_flag_operand *flg_operand =
3493 &arc_flag_operands[pflags[i].code];
3495 /* Check if the instruction has a delay slot. */
3496 if (!strcmp (flg_operand->name, "d"))
3497 has_delay_slot = TRUE;
3499 /* There is an exceptional case when we cannot insert a flag
3500 just as it is. The .T flag must be handled in relation with
3501 the relative address. */
3502 if (!strcmp (flg_operand->name, "t")
3503 || !strcmp (flg_operand->name, "nt"))
3505 unsigned bitYoperand = 0;
3506 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3507 if (!strcmp (flg_operand->name, "t"))
3508 if (!strcmp (opcode->name, "bbit0")
3509 || !strcmp (opcode->name, "bbit1"))
3510 bitYoperand = arc_NToperand;
3512 bitYoperand = arc_Toperand;
3514 if (!strcmp (opcode->name, "bbit0")
3515 || !strcmp (opcode->name, "bbit1"))
3516 bitYoperand = arc_Toperand;
3518 bitYoperand = arc_NToperand;
3520 gas_assert (reloc_exp != NULL);
3521 if (reloc_exp->X_op == O_constant)
3523 /* Check if we have a constant and solved it
3525 offsetT val = reloc_exp->X_add_number;
3526 image |= insert_operand (image, &arc_operands[bitYoperand],
3531 struct arc_fixup *fixup;
3533 if (insn->nfixups >= MAX_INSN_FIXUPS)
3534 as_fatal (_("too many fixups"));
3536 fixup = &insn->fixups[insn->nfixups++];
3537 fixup->exp = *reloc_exp;
3538 fixup->reloc = -bitYoperand;
3539 fixup->pcrel = pcrel;
3540 fixup->islong = FALSE;
3544 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
3545 << flg_operand->shift;
3548 insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
3550 /* Short instruction? */
3551 insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
3555 /* Update last insn status. */
3556 arc_last_insns[1] = arc_last_insns[0];
3557 arc_last_insns[0].opcode = opcode;
3558 arc_last_insns[0].has_limm = insn->has_limm;
3559 arc_last_insns[0].has_delay_slot = has_delay_slot;
3561 /* Check if the current instruction is legally used. */
3562 if (arc_last_insns[1].has_delay_slot
3563 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3564 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3565 _("A jump/branch instruction in delay slot."));
3569 arc_handle_align (fragS* fragP)
3571 if ((fragP)->fr_type == rs_align_code)
3573 char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
3574 valueT count = ((fragP)->fr_next->fr_address
3575 - (fragP)->fr_address - (fragP)->fr_fix);
3577 (fragP)->fr_var = 2;
3579 if (count & 1)/* Padding in the gap till the next 2-byte
3580 boundary with 0s. */
3585 /* Writing nop_s. */
3586 md_number_to_chars (dest, NOP_OPCODE_S, 2);
3590 /* Here we decide which fixups can be adjusted to make them relative
3591 to the beginning of the section instead of the symbol. Basically
3592 we need to make sure that the dynamic relocations are done
3593 correctly, so in some cases we force the original symbol to be
3597 tc_arc_fix_adjustable (fixS *fixP)
3600 /* Prevent all adjustments to global symbols. */
3601 if (S_IS_EXTERNAL (fixP->fx_addsy))
3603 if (S_IS_WEAK (fixP->fx_addsy))
3606 /* Adjust_reloc_syms doesn't know about the GOT. */
3607 switch (fixP->fx_r_type)
3609 case BFD_RELOC_ARC_GOTPC32:
3610 case BFD_RELOC_ARC_PLT32:
3611 case BFD_RELOC_ARC_S25H_PCREL_PLT:
3612 case BFD_RELOC_ARC_S21H_PCREL_PLT:
3613 case BFD_RELOC_ARC_S25W_PCREL_PLT:
3614 case BFD_RELOC_ARC_S21W_PCREL_PLT:
3624 /* Compute the reloc type of an expression EXP. */
3627 arc_check_reloc (expressionS *exp,
3628 bfd_reloc_code_real_type *r_type_p)
3630 if (*r_type_p == BFD_RELOC_32
3631 && exp->X_op == O_subtract
3632 && exp->X_op_symbol != NULL
3633 && exp->X_op_symbol->bsym->section == now_seg)
3634 *r_type_p = BFD_RELOC_ARC_32_PCREL;
3638 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3641 arc_cons_fix_new (fragS *frag,
3645 bfd_reloc_code_real_type r_type)
3647 r_type = BFD_RELOC_UNUSED;
3652 r_type = BFD_RELOC_8;
3656 r_type = BFD_RELOC_16;
3660 r_type = BFD_RELOC_24;
3664 r_type = BFD_RELOC_32;
3665 arc_check_reloc (exp, &r_type);
3669 r_type = BFD_RELOC_64;
3673 as_bad (_("unsupported BFD relocation size %u"), size);
3674 r_type = BFD_RELOC_UNUSED;
3677 fix_new_exp (frag, off, size, exp, 0, r_type);
3680 /* The actual routine that checks the ZOL conditions. */
3683 check_zol (symbolS *s)
3685 switch (arc_mach_type)
3687 case bfd_mach_arc_arcv2:
3688 if (arc_target & ARC_OPCODE_ARCv2EM)
3691 if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
3692 || arc_last_insns[1].has_delay_slot)
3693 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3697 case bfd_mach_arc_arc600:
3699 if (is_kernel_insn_p (arc_last_insns[0].opcode))
3700 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3703 if (arc_last_insns[0].has_limm
3704 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3705 as_bad (_("A jump instruction with long immediate detected at the \
3706 end of the ZOL label @%s"), S_GET_NAME (s));
3709 case bfd_mach_arc_nps400:
3710 case bfd_mach_arc_arc700:
3711 if (arc_last_insns[0].has_delay_slot)
3712 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3721 /* If ZOL end check the last two instruction for illegals. */
3723 arc_frob_label (symbolS * sym)
3725 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
3728 dwarf2_emit_label (sym);
3731 /* Used because generic relaxation assumes a pc-rel value whilst we
3732 also relax instructions that use an absolute value resolved out of
3733 relative values (if that makes any sense). An example: 'add r1,
3734 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
3735 but if they're in the same section we can subtract the section
3736 offset relocation which ends up in a resolved value. So if @.L2 is
3737 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
3738 .text + 0x40 = 0x10. */
3740 arc_pcrel_adjust (fragS *fragP)
3742 if (!fragP->tc_frag_data.pcrel)
3743 return fragP->fr_address + fragP->fr_fix;
3748 /* Initialize the DWARF-2 unwind information for this procedure. */
3751 tc_arc_frame_initial_instructions (void)
3753 /* Stack pointer is register 28. */
3754 cfi_add_CFA_def_cfa_register (28);
3758 tc_arc_regname_to_dw2regnum (char *regname)
3762 sym = hash_find (arc_reg_hash, regname);
3764 return S_GET_VALUE (sym);