1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2018 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 "dwarf2dbg.h"
26 #include "dw2gencfi.h"
27 #include "safe-ctype.h"
29 #include "opcode/arc.h"
30 #include "opcode/arc-attrs.h"
32 #include "../opcodes/arc-ext.h"
34 /* Defines section. */
36 #define MAX_INSN_FIXUPS 2
37 #define MAX_CONSTR_STR 20
38 #define FRAG_MAX_GROWTH 8
41 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
43 # define pr_debug(fmt, args...)
46 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
47 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
48 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) \
49 && (SUB_OPCODE (x) == 0x28))
51 /* Equal to MAX_PRECISION in atof-ieee.c. */
52 #define MAX_LITTLENUMS 6
54 #ifndef TARGET_WITH_CPU
55 #define TARGET_WITH_CPU "arc700"
56 #endif /* TARGET_WITH_CPU */
58 #define ARC_GET_FLAG(s) (*symbol_get_tc (s))
59 #define ARC_SET_FLAG(s,v) (*symbol_get_tc (s) |= (v))
60 #define streq(a, b) (strcmp (a, b) == 0)
62 /* Enum used to enumerate the relaxable ins operands. */
67 REGISTER_S, /* Register for short instruction(s). */
68 REGISTER_NO_GP, /* Is a register but not gp register specifically. */
69 REGISTER_DUP, /* Duplication of previous operand of type register. */
101 /* Macros section. */
103 #define regno(x) ((x) & 0x3F)
104 #define is_ir_num(x) (((x) & ~0x3F) == 0)
105 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
106 #define is_spfp_p(op) (((sc) == SPX))
107 #define is_dpfp_p(op) (((sc) == DPX))
108 #define is_fpuda_p(op) (((sc) == DPA))
109 #define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH \
110 || (op)->insn_class == JUMP \
111 || (op)->insn_class == BRCC \
112 || (op)->insn_class == BBIT0 \
113 || (op)->insn_class == BBIT1 \
114 || (op)->insn_class == BI \
115 || (op)->insn_class == EI \
116 || (op)->insn_class == ENTER \
117 || (op)->insn_class == JLI \
118 || (op)->insn_class == LOOP \
119 || (op)->insn_class == LEAVE \
121 #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL))
122 #define is_nps400_p(op) (((sc) == NPS400))
124 /* Generic assembler global variables which must be defined by all
127 /* Characters which always start a comment. */
128 const char comment_chars[] = "#;";
130 /* Characters which start a comment at the beginning of a line. */
131 const char line_comment_chars[] = "#";
133 /* Characters which may be used to separate multiple commands on a
135 const char line_separator_chars[] = "`";
137 /* Characters which are used to indicate an exponent in a floating
139 const char EXP_CHARS[] = "eE";
141 /* Chars that mean this number is a floating point constant
142 As in 0f12.456 or 0d1.2345e12. */
143 const char FLT_CHARS[] = "rRsSfFdD";
146 extern int target_big_endian;
147 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
148 static int byte_order = DEFAULT_BYTE_ORDER;
150 /* Arc extension section. */
151 static segT arcext_section;
153 /* By default relaxation is disabled. */
154 static int relaxation_state = 0;
156 extern int arc_get_mach (char *);
158 /* Forward declarations. */
159 static void arc_lcomm (int);
160 static void arc_option (int);
161 static void arc_extra_reloc (int);
162 static void arc_extinsn (int);
163 static void arc_extcorereg (int);
164 static void arc_attribute (int);
166 const pseudo_typeS md_pseudo_table[] =
168 /* Make sure that .word is 32 bits. */
171 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
172 { "lcomm", arc_lcomm, 0 },
173 { "lcommon", arc_lcomm, 0 },
174 { "cpu", arc_option, 0 },
176 { "arc_attribute", arc_attribute, 0 },
177 { "extinstruction", arc_extinsn, 0 },
178 { "extcoreregister", arc_extcorereg, EXT_CORE_REGISTER },
179 { "extauxregister", arc_extcorereg, EXT_AUX_REGISTER },
180 { "extcondcode", arc_extcorereg, EXT_COND_CODE },
182 { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
183 { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
188 const char *md_shortopts = "";
192 OPTION_EB = OPTION_MD_BASE,
210 /* The following options are deprecated and provided here only for
211 compatibility reasons. */
234 struct option md_longopts[] =
236 { "EB", no_argument, NULL, OPTION_EB },
237 { "EL", no_argument, NULL, OPTION_EL },
238 { "mcpu", required_argument, NULL, OPTION_MCPU },
239 { "mA6", no_argument, NULL, OPTION_ARC600 },
240 { "mARC600", no_argument, NULL, OPTION_ARC600 },
241 { "mARC601", no_argument, NULL, OPTION_ARC601 },
242 { "mARC700", no_argument, NULL, OPTION_ARC700 },
243 { "mA7", no_argument, NULL, OPTION_ARC700 },
244 { "mEM", no_argument, NULL, OPTION_ARCEM },
245 { "mHS", no_argument, NULL, OPTION_ARCHS },
246 { "mcode-density", no_argument, NULL, OPTION_CD },
247 { "mrelax", no_argument, NULL, OPTION_RELAX },
248 { "mnps400", no_argument, NULL, OPTION_NPS400 },
250 /* Floating point options */
251 { "mspfp", no_argument, NULL, OPTION_SPFP},
252 { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
253 { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
254 { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
255 { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
256 { "mdpfp", no_argument, NULL, OPTION_DPFP},
257 { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
258 { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
259 { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
260 { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
261 { "mfpuda", no_argument, NULL, OPTION_FPUDA},
263 /* The following options are deprecated and provided here only for
264 compatibility reasons. */
265 { "mav2em", no_argument, NULL, OPTION_ARCEM },
266 { "mav2hs", no_argument, NULL, OPTION_ARCHS },
267 { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
268 { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
269 { "mswap", no_argument, NULL, OPTION_SWAP },
270 { "mnorm", no_argument, NULL, OPTION_NORM },
271 { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
272 { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
273 { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
274 { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
275 { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
276 { "mea", no_argument, NULL, OPTION_EA },
277 { "mEA", no_argument, NULL, OPTION_EA },
278 { "mmul64", no_argument, NULL, OPTION_MUL64 },
279 { "msimd", no_argument, NULL, OPTION_SIMD},
280 { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
281 { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
282 { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
283 { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
284 { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
285 { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
286 { "mcrc", no_argument, NULL, OPTION_CRC},
287 { "mdvbf", no_argument, NULL, OPTION_DVBF},
288 { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
289 { "mxy", no_argument, NULL, OPTION_XYMEMORY},
290 { "mlock", no_argument, NULL, OPTION_LOCK},
291 { "mswape", no_argument, NULL, OPTION_SWAPE},
292 { "mrtsc", no_argument, NULL, OPTION_RTSC},
294 { NULL, no_argument, NULL, 0 }
297 size_t md_longopts_size = sizeof (md_longopts);
299 /* Local data and data types. */
301 /* Used since new relocation types are introduced in this
302 file (DUMMY_RELOC_LITUSE_*). */
303 typedef int extended_bfd_reloc_code_real_type;
309 extended_bfd_reloc_code_real_type reloc;
311 /* index into arc_operands. */
312 unsigned int opindex;
314 /* PC-relative, used by internals fixups. */
317 /* TRUE if this fixup is for LIMM operand. */
323 unsigned long long int insn;
325 struct arc_fixup fixups[MAX_INSN_FIXUPS];
327 unsigned int len; /* Length of instruction in bytes. */
328 bfd_boolean has_limm; /* Boolean value: TRUE if limm field is
330 bfd_boolean relax; /* Boolean value: TRUE if needs
334 /* Structure to hold any last two instructions. */
335 static struct arc_last_insn
337 /* Saved instruction opcode. */
338 const struct arc_opcode *opcode;
340 /* Boolean value: TRUE if current insn is short. */
341 bfd_boolean has_limm;
343 /* Boolean value: TRUE if current insn has delay slot. */
344 bfd_boolean has_delay_slot;
347 /* Extension instruction suffix classes. */
355 static const attributes_t suffixclass[] =
357 { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG },
358 { "SUFFIX_COND", 11, ARC_SUFFIX_COND },
359 { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE }
362 /* Extension instruction syntax classes. */
363 static const attributes_t syntaxclass[] =
365 { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP },
366 { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP },
367 { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP },
368 { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP }
371 /* Extension instruction syntax classes modifiers. */
372 static const attributes_t syntaxclassmod[] =
374 { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED },
375 { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM }
378 /* Extension register type. */
386 /* A structure to hold the additional conditional codes. */
389 struct arc_flag_operand *arc_ext_condcode;
391 } ext_condcode = { NULL, 0 };
393 /* Structure to hold an entry in ARC_OPCODE_HASH. */
394 struct arc_opcode_hash_entry
396 /* The number of pointers in the OPCODE list. */
399 /* Points to a list of opcode pointers. */
400 const struct arc_opcode **opcode;
403 /* Structure used for iterating through an arc_opcode_hash_entry. */
404 struct arc_opcode_hash_entry_iterator
406 /* Index into the OPCODE element of the arc_opcode_hash_entry. */
409 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
410 returned by this iterator. */
411 const struct arc_opcode *opcode;
414 /* Forward declaration. */
415 static void assemble_insn
416 (const struct arc_opcode *, const expressionS *, int,
417 const struct arc_flags *, int, struct arc_insn *);
419 /* The selection of the machine type can come from different sources. This
420 enum is used to track how the selection was made in order to perform
422 enum mach_selection_type
425 MACH_SELECTION_FROM_DEFAULT,
426 MACH_SELECTION_FROM_CPU_DIRECTIVE,
427 MACH_SELECTION_FROM_COMMAND_LINE
430 /* How the current machine type was selected. */
431 static enum mach_selection_type mach_selection_mode = MACH_SELECTION_NONE;
433 /* The hash table of instruction opcodes. */
434 static struct hash_control *arc_opcode_hash;
436 /* The hash table of register symbols. */
437 static struct hash_control *arc_reg_hash;
439 /* The hash table of aux register symbols. */
440 static struct hash_control *arc_aux_hash;
442 /* The hash table of address types. */
443 static struct hash_control *arc_addrtype_hash;
445 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \
446 { #NAME, ARC_OPCODE_ARC600, bfd_mach_arc_arc600, \
447 E_ARC_MACH_ARC600, EXTRA}
448 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \
449 { #NAME, ARC_OPCODE_ARC700, bfd_mach_arc_arc700, \
450 E_ARC_MACH_ARC700, EXTRA}
451 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \
452 { #NAME, ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2, \
453 EF_ARC_CPU_ARCV2EM, EXTRA}
454 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \
455 { #NAME, ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2, \
456 EF_ARC_CPU_ARCV2HS, EXTRA}
457 #define ARC_CPU_TYPE_NONE \
460 /* A table of CPU names and opcode sets. */
461 static const struct cpu_type
471 #include "elf/arc-cpu.def"
474 /* Information about the cpu/variant we're assembling for. */
475 static struct cpu_type selected_cpu = { 0, 0, 0, E_ARC_OSABI_CURRENT, 0 };
477 /* TRUE if current assembly code uses RF16 only registers. */
478 static bfd_boolean rf16_only = TRUE;
481 static unsigned mpy_option = 0;
484 static unsigned pic_option = 0;
486 /* Use small data. */
487 static unsigned sda_option = 0;
490 static unsigned tls_option = 0;
492 /* Command line given features. */
493 static unsigned cl_features = 0;
495 /* Used by the arc_reloc_op table. Order is important. */
496 #define O_gotoff O_md1 /* @gotoff relocation. */
497 #define O_gotpc O_md2 /* @gotpc relocation. */
498 #define O_plt O_md3 /* @plt relocation. */
499 #define O_sda O_md4 /* @sda relocation. */
500 #define O_pcl O_md5 /* @pcl relocation. */
501 #define O_tlsgd O_md6 /* @tlsgd relocation. */
502 #define O_tlsie O_md7 /* @tlsie relocation. */
503 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
504 #define O_tpoff O_md9 /* @tpoff relocation. */
505 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
506 #define O_dtpoff O_md11 /* @dtpoff relocation. */
507 #define O_last O_dtpoff
509 /* Used to define a bracket as operand in tokens. */
510 #define O_bracket O_md32
512 /* Used to define a colon as an operand in tokens. */
513 #define O_colon O_md31
515 /* Used to define address types in nps400. */
516 #define O_addrtype O_md30
518 /* Dummy relocation, to be sorted out. */
519 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
521 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
523 /* A table to map the spelling of a relocation operand into an appropriate
524 bfd_reloc_code_real_type type. The table is assumed to be ordered such
525 that op-O_literal indexes into it. */
526 #define ARC_RELOC_TABLE(op) \
527 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
529 : (int) (op) - (int) O_gotoff) ])
531 #define DEF(NAME, RELOC, REQ) \
532 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
534 static const struct arc_reloc_op_tag
536 /* String to lookup. */
538 /* Size of the string. */
540 /* Which operator to use. */
542 extended_bfd_reloc_code_real_type reloc;
543 /* Allows complex relocation expression like identifier@reloc +
545 unsigned int complex_expr : 1;
549 DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
550 DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
551 DEF (plt, BFD_RELOC_ARC_PLT32, 0),
552 DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
553 DEF (pcl, BFD_RELOC_ARC_PC32, 1),
554 DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0),
555 DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0),
556 DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0),
557 DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 1),
558 DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0),
559 DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 1),
562 static const int arc_num_reloc_op
563 = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
565 /* Structure for relaxable instruction that have to be swapped with a
566 smaller alternative instruction. */
567 struct arc_relaxable_ins
569 /* Mnemonic that should be checked. */
570 const char *mnemonic_r;
572 /* Operands that should be checked.
573 Indexes of operands from operand array. */
574 enum rlx_operand_type operands[6];
576 /* Flags that should be checked. */
577 unsigned flag_classes[5];
579 /* Mnemonic (smaller) alternative to be used later for relaxation. */
580 const char *mnemonic_alt;
582 /* Index of operand that generic relaxation has to check. */
585 /* Base subtype index used. */
586 enum arc_rlx_types subtype;
589 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
590 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
591 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
595 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
596 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
597 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
602 /* ARC relaxation table. */
603 const relax_typeS md_relax_table[] =
610 RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL),
611 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE),
615 RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B),
616 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE),
621 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6),
622 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM),
623 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
625 /* LD_S a, [b, u7] ->
626 LD<zz><.x><.aa><.di> a, [b, s9] ->
627 LD<zz><.x><.aa><.di> a, [b, limm] */
628 RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9),
629 RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM),
630 RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE),
635 RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12),
636 RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM),
637 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
641 SUB<.f> a, b, limm. */
642 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6),
643 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM),
644 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
646 /* MPY<.f> a, b, u6 ->
647 MPY<.f> a, b, limm. */
648 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM),
649 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
651 /* MOV<.f><.cc> b, u6 ->
652 MOV<.f><.cc> b, limm. */
653 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM),
654 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
656 /* ADD<.f><.cc> b, b, u6 ->
657 ADD<.f><.cc> b, b, limm. */
658 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM),
659 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
662 /* Order of this table's entries matters! */
663 const struct arc_relaxable_ins arc_relaxable_insns[] =
665 { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S },
666 { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S },
667 { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add",
668 2, ARC_RLX_ADD_RRU6},
669 { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2,
671 { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2,
673 { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET },
674 { 0 }, "ld_s", 3, ARC_RLX_LD_U7 },
675 { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET },
676 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 },
677 { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 },
678 { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 },
679 { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 },
680 { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2,
682 { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2,
684 { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2,
688 const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns);
690 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
691 symbolS * GOT_symbol = 0;
693 /* Set to TRUE when we assemble instructions. */
694 static bfd_boolean assembling_insn = FALSE;
696 /* List with attributes set explicitly. */
697 static bfd_boolean attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
699 /* Functions implementation. */
701 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
702 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
703 are no matching entries in ARC_OPCODE_HASH. */
705 static const struct arc_opcode_hash_entry *
706 arc_find_opcode (const char *name)
708 const struct arc_opcode_hash_entry *entry;
710 entry = hash_find (arc_opcode_hash, name);
714 /* Initialise the iterator ITER. */
717 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator *iter)
723 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
724 calls to this function. Return NULL when all ARC_OPCODE entries have
727 static const struct arc_opcode *
728 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry,
729 struct arc_opcode_hash_entry_iterator *iter)
731 if (iter->opcode == NULL && iter->index == 0)
733 gas_assert (entry->count > 0);
734 iter->opcode = entry->opcode[iter->index];
736 else if (iter->opcode != NULL)
738 const char *old_name = iter->opcode->name;
741 if (iter->opcode->name == NULL
742 || strcmp (old_name, iter->opcode->name) != 0)
745 if (iter->index == entry->count)
748 iter->opcode = entry->opcode[iter->index];
755 /* Insert an opcode into opcode hash structure. */
758 arc_insert_opcode (const struct arc_opcode *opcode)
760 const char *name, *retval;
761 struct arc_opcode_hash_entry *entry;
764 entry = hash_find (arc_opcode_hash, name);
767 entry = XNEW (struct arc_opcode_hash_entry);
769 entry->opcode = NULL;
771 retval = hash_insert (arc_opcode_hash, name, (void *) entry);
773 as_fatal (_("internal error: can't hash opcode '%s': %s"),
777 entry->opcode = XRESIZEVEC (const struct arc_opcode *, entry->opcode,
780 if (entry->opcode == NULL)
781 as_fatal (_("Virtual memory exhausted"));
783 entry->opcode[entry->count] = opcode;
788 /* Like md_number_to_chars but for middle-endian values. The 4-byte limm
789 value, is encoded as 'middle-endian' for a little-endian target. This
790 function is used for regular 4, 6, and 8 byte instructions as well. */
793 md_number_to_chars_midend (char *buf, unsigned long long val, int n)
798 md_number_to_chars (buf, val, n);
801 md_number_to_chars (buf, (val & 0xffff00000000ull) >> 32, 2);
802 md_number_to_chars_midend (buf + 2, (val & 0xffffffff), 4);
805 md_number_to_chars (buf, (val & 0xffff0000) >> 16, 2);
806 md_number_to_chars (buf + 2, (val & 0xffff), 2);
809 md_number_to_chars_midend (buf, (val & 0xffffffff00000000ull) >> 32, 4);
810 md_number_to_chars_midend (buf + 4, (val & 0xffffffff), 4);
817 /* Check if a feature is allowed for a specific CPU. */
820 arc_check_feature (void)
824 if (!selected_cpu.features
825 || !selected_cpu.name)
828 for (i = 0; i < ARRAY_SIZE (feature_list); i++)
829 if ((selected_cpu.features & feature_list[i].feature)
830 && !(selected_cpu.flags & feature_list[i].cpus))
831 as_bad (_("invalid %s option for %s cpu"), feature_list[i].name,
834 for (i = 0; i < ARRAY_SIZE (conflict_list); i++)
835 if ((selected_cpu.features & conflict_list[i]) == conflict_list[i])
836 as_bad(_("conflicting ISA extension attributes."));
839 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
840 the relevant static global variables. Parameter SEL describes where
841 this selection originated from. */
844 arc_select_cpu (const char *arg, enum mach_selection_type sel)
848 /* We should only set a default if we've not made a selection from some
850 gas_assert (sel != MACH_SELECTION_FROM_DEFAULT
851 || mach_selection_mode == MACH_SELECTION_NONE);
853 if ((mach_selection_mode == MACH_SELECTION_FROM_CPU_DIRECTIVE)
854 && (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE))
855 as_bad (_("Multiple .cpu directives found"));
857 /* Look for a matching entry in CPU_TYPES array. */
858 for (i = 0; cpu_types[i].name; ++i)
860 if (!strcasecmp (cpu_types[i].name, arg))
862 /* If a previous selection was made on the command line, then we
863 allow later selections on the command line to override earlier
864 ones. However, a selection from a '.cpu NAME' directive must
865 match the command line selection, or we give a warning. */
866 if (mach_selection_mode == MACH_SELECTION_FROM_COMMAND_LINE)
868 gas_assert (sel == MACH_SELECTION_FROM_COMMAND_LINE
869 || sel == MACH_SELECTION_FROM_CPU_DIRECTIVE);
870 if (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE
871 && selected_cpu.mach != cpu_types[i].mach)
873 as_warn (_("Command-line value overrides \".cpu\" directive"));
878 /* Initialise static global data about selected machine type. */
879 selected_cpu.flags = cpu_types[i].flags;
880 selected_cpu.name = cpu_types[i].name;
881 selected_cpu.features = cpu_types[i].features | cl_features;
882 selected_cpu.mach = cpu_types[i].mach;
883 selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_MACH_MSK)
884 | cpu_types[i].eflags);
889 if (!cpu_types[i].name)
890 as_fatal (_("unknown architecture: %s\n"), arg);
892 /* Check if set features are compatible with the chosen CPU. */
893 arc_check_feature ();
895 mach_selection_mode = sel;
898 /* Here ends all the ARCompact extension instruction assembling
902 arc_extra_reloc (int r_type)
905 symbolS *sym, *lab = NULL;
907 if (*input_line_pointer == '@')
908 input_line_pointer++;
909 c = get_symbol_name (&sym_name);
910 sym = symbol_find_or_make (sym_name);
911 restore_line_pointer (c);
912 if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
914 ++input_line_pointer;
916 c = get_symbol_name (&lab_name);
917 lab = symbol_find_or_make (lab_name);
918 restore_line_pointer (c);
921 /* These relocations exist as a mechanism for the compiler to tell the
922 linker how to patch the code if the tls model is optimised. However,
923 the relocation itself does not require any space within the assembler
924 fragment, and so we pass a size of 0.
926 The lines that generate these relocations look like this:
928 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
930 The '.tls_gd_ld @.tdata' is processed first and generates the
931 additional relocation, while the 'bl __tls_get_addr@plt' is processed
932 second and generates the additional branch.
934 It is possible that the additional relocation generated by the
935 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
936 while the 'bl __tls_get_addr@plt' will be generated as the first thing
937 in the next fragment. This will be fine; both relocations will still
938 appear to be at the same address in the generated object file.
939 However, this only works as the additional relocation is generated
940 with size of 0 bytes. */
942 = fix_new (frag_now, /* Which frag? */
943 frag_now_fix (), /* Where in that frag? */
944 0, /* size: 1, 2, or 4 usually. */
945 sym, /* X_add_symbol. */
946 0, /* X_add_number. */
947 FALSE, /* TRUE if PC-relative relocation. */
948 r_type /* Relocation type. */);
949 fixP->fx_subsy = lab;
953 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
954 symbolS *symbolP, addressT size)
959 if (*input_line_pointer == ',')
961 align = parse_align (1);
963 if (align == (addressT) -1)
978 bss_alloc (symbolP, size, align);
979 S_CLEAR_EXTERNAL (symbolP);
985 arc_lcomm (int ignore)
987 symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
990 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
993 /* Select the cpu we're assembling for. */
996 arc_option (int ignore ATTRIBUTE_UNUSED)
1000 const char *cpu_name;
1002 c = get_symbol_name (&cpu);
1005 if ((!strcmp ("ARC600", cpu))
1006 || (!strcmp ("ARC601", cpu))
1007 || (!strcmp ("A6", cpu)))
1008 cpu_name = "arc600";
1009 else if ((!strcmp ("ARC700", cpu))
1010 || (!strcmp ("A7", cpu)))
1011 cpu_name = "arc700";
1012 else if (!strcmp ("EM", cpu))
1014 else if (!strcmp ("HS", cpu))
1016 else if (!strcmp ("NPS400", cpu))
1017 cpu_name = "nps400";
1019 arc_select_cpu (cpu_name, MACH_SELECTION_FROM_CPU_DIRECTIVE);
1021 restore_line_pointer (c);
1022 demand_empty_rest_of_line ();
1025 /* Smartly print an expression. */
1028 debug_exp (expressionS *t)
1030 const char *name ATTRIBUTE_UNUSED;
1031 const char *namemd ATTRIBUTE_UNUSED;
1033 pr_debug ("debug_exp: ");
1037 default: name = "unknown"; break;
1038 case O_illegal: name = "O_illegal"; break;
1039 case O_absent: name = "O_absent"; break;
1040 case O_constant: name = "O_constant"; break;
1041 case O_symbol: name = "O_symbol"; break;
1042 case O_symbol_rva: name = "O_symbol_rva"; break;
1043 case O_register: name = "O_register"; break;
1044 case O_big: name = "O_big"; break;
1045 case O_uminus: name = "O_uminus"; break;
1046 case O_bit_not: name = "O_bit_not"; break;
1047 case O_logical_not: name = "O_logical_not"; break;
1048 case O_multiply: name = "O_multiply"; break;
1049 case O_divide: name = "O_divide"; break;
1050 case O_modulus: name = "O_modulus"; break;
1051 case O_left_shift: name = "O_left_shift"; break;
1052 case O_right_shift: name = "O_right_shift"; break;
1053 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1054 case O_bit_or_not: name = "O_bit_or_not"; break;
1055 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1056 case O_bit_and: name = "O_bit_and"; break;
1057 case O_add: name = "O_add"; break;
1058 case O_subtract: name = "O_subtract"; break;
1059 case O_eq: name = "O_eq"; break;
1060 case O_ne: name = "O_ne"; break;
1061 case O_lt: name = "O_lt"; break;
1062 case O_le: name = "O_le"; break;
1063 case O_ge: name = "O_ge"; break;
1064 case O_gt: name = "O_gt"; break;
1065 case O_logical_and: name = "O_logical_and"; break;
1066 case O_logical_or: name = "O_logical_or"; break;
1067 case O_index: name = "O_index"; break;
1068 case O_bracket: name = "O_bracket"; break;
1069 case O_colon: name = "O_colon"; break;
1070 case O_addrtype: name = "O_addrtype"; break;
1075 default: namemd = "unknown"; break;
1076 case O_gotoff: namemd = "O_gotoff"; break;
1077 case O_gotpc: namemd = "O_gotpc"; break;
1078 case O_plt: namemd = "O_plt"; break;
1079 case O_sda: namemd = "O_sda"; break;
1080 case O_pcl: namemd = "O_pcl"; break;
1081 case O_tlsgd: namemd = "O_tlsgd"; break;
1082 case O_tlsie: namemd = "O_tlsie"; break;
1083 case O_tpoff9: namemd = "O_tpoff9"; break;
1084 case O_tpoff: namemd = "O_tpoff"; break;
1085 case O_dtpoff9: namemd = "O_dtpoff9"; break;
1086 case O_dtpoff: namemd = "O_dtpoff"; break;
1089 pr_debug ("%s (%s, %s, %d, %s)", name,
1090 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1091 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1092 (int) t->X_add_number,
1093 (t->X_md) ? namemd : "--");
1098 /* Parse the arguments to an opcode. */
1101 tokenize_arguments (char *str,
1105 char *old_input_line_pointer;
1106 bfd_boolean saw_comma = FALSE;
1107 bfd_boolean saw_arg = FALSE;
1112 const struct arc_reloc_op_tag *r;
1114 char *reloc_name, c;
1116 memset (tok, 0, sizeof (*tok) * ntok);
1118 /* Save and restore input_line_pointer around this function. */
1119 old_input_line_pointer = input_line_pointer;
1120 input_line_pointer = str;
1122 while (*input_line_pointer)
1125 switch (*input_line_pointer)
1131 input_line_pointer++;
1132 if (saw_comma || !saw_arg)
1139 ++input_line_pointer;
1141 if (!saw_arg || num_args == ntok)
1143 tok->X_op = O_bracket;
1150 input_line_pointer++;
1151 if (brk_lvl || num_args == ntok)
1154 tok->X_op = O_bracket;
1160 input_line_pointer++;
1161 if (!saw_arg || num_args == ntok)
1163 tok->X_op = O_colon;
1170 /* We have labels, function names and relocations, all
1171 starting with @ symbol. Sort them out. */
1172 if ((saw_arg && !saw_comma) || num_args == ntok)
1176 tok->X_op = O_symbol;
1177 tok->X_md = O_absent;
1179 if (*input_line_pointer != '@')
1180 goto normalsymbol; /* This is not a relocation. */
1184 /* A relocation operand has the following form
1185 @identifier@relocation_type. The identifier is already
1187 if (tok->X_op != O_symbol)
1189 as_bad (_("No valid label relocation operand"));
1193 /* Parse @relocation_type. */
1194 input_line_pointer++;
1195 c = get_symbol_name (&reloc_name);
1196 len = input_line_pointer - reloc_name;
1199 as_bad (_("No relocation operand"));
1203 /* Go through known relocation and try to find a match. */
1204 r = &arc_reloc_op[0];
1205 for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
1206 if (len == r->length
1207 && memcmp (reloc_name, r->name, len) == 0)
1211 as_bad (_("Unknown relocation operand: @%s"), reloc_name);
1215 *input_line_pointer = c;
1216 SKIP_WHITESPACE_AFTER_NAME ();
1217 /* Extra check for TLS: base. */
1218 if (*input_line_pointer == '@')
1221 if (tok->X_op_symbol != NULL
1222 || tok->X_op != O_symbol)
1224 as_bad (_("Unable to parse TLS base: %s"),
1225 input_line_pointer);
1228 input_line_pointer++;
1230 c = get_symbol_name (&sym_name);
1231 base = symbol_find_or_make (sym_name);
1232 tok->X_op = O_subtract;
1233 tok->X_op_symbol = base;
1234 restore_line_pointer (c);
1235 tmpE.X_add_number = 0;
1237 if ((*input_line_pointer != '+')
1238 && (*input_line_pointer != '-'))
1240 tmpE.X_add_number = 0;
1244 /* Parse the constant of a complex relocation expression
1245 like @identifier@reloc +/- const. */
1246 if (! r->complex_expr)
1248 as_bad (_("@%s is not a complex relocation."), r->name);
1252 if (tmpE.X_op != O_constant)
1254 as_bad (_("Bad expression: @%s + %s."),
1255 r->name, input_line_pointer);
1261 tok->X_add_number = tmpE.X_add_number;
1272 /* Can be a register. */
1273 ++input_line_pointer;
1277 if ((saw_arg && !saw_comma) || num_args == ntok)
1280 tok->X_op = O_absent;
1281 tok->X_md = O_absent;
1284 /* Legacy: There are cases when we have
1285 identifier@relocation_type, if it is the case parse the
1286 relocation type as well. */
1287 if (*input_line_pointer == '@')
1293 if (tok->X_op == O_illegal
1294 || tok->X_op == O_absent
1295 || num_args == ntok)
1307 if (saw_comma || brk_lvl)
1309 input_line_pointer = old_input_line_pointer;
1315 as_bad (_("Brackets in operand field incorrect"));
1317 as_bad (_("extra comma"));
1319 as_bad (_("missing argument"));
1321 as_bad (_("missing comma or colon"));
1322 input_line_pointer = old_input_line_pointer;
1326 /* Parse the flags to a structure. */
1329 tokenize_flags (const char *str,
1330 struct arc_flags flags[],
1333 char *old_input_line_pointer;
1334 bfd_boolean saw_flg = FALSE;
1335 bfd_boolean saw_dot = FALSE;
1339 memset (flags, 0, sizeof (*flags) * nflg);
1341 /* Save and restore input_line_pointer around this function. */
1342 old_input_line_pointer = input_line_pointer;
1343 input_line_pointer = (char *) str;
1345 while (*input_line_pointer)
1347 switch (*input_line_pointer)
1354 input_line_pointer++;
1362 if (saw_flg && !saw_dot)
1365 if (num_flags >= nflg)
1368 flgnamelen = strspn (input_line_pointer,
1369 "abcdefghijklmnopqrstuvwxyz0123456789");
1370 if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1373 memcpy (flags->name, input_line_pointer, flgnamelen);
1375 input_line_pointer += flgnamelen;
1385 input_line_pointer = old_input_line_pointer;
1390 as_bad (_("extra dot"));
1392 as_bad (_("unrecognized flag"));
1394 as_bad (_("failed to parse flags"));
1395 input_line_pointer = old_input_line_pointer;
1399 /* Apply the fixups in order. */
1402 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1406 for (i = 0; i < insn->nfixups; i++)
1408 struct arc_fixup *fixup = &insn->fixups[i];
1409 int size, pcrel, offset = 0;
1411 /* FIXME! the reloc size is wrong in the BFD file.
1412 When it is fixed please delete me. */
1413 size = ((insn->len == 2) && !fixup->islong) ? 2 : 4;
1418 /* Some fixups are only used internally, thus no howto. */
1419 if ((int) fixup->reloc == 0)
1420 as_fatal (_("Unhandled reloc type"));
1422 if ((int) fixup->reloc < 0)
1424 /* FIXME! the reloc size is wrong in the BFD file.
1425 When it is fixed please enable me.
1426 size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
1427 pcrel = fixup->pcrel;
1431 reloc_howto_type *reloc_howto =
1432 bfd_reloc_type_lookup (stdoutput,
1433 (bfd_reloc_code_real_type) fixup->reloc);
1434 gas_assert (reloc_howto);
1436 /* FIXME! the reloc size is wrong in the BFD file.
1437 When it is fixed please enable me.
1438 size = bfd_get_reloc_size (reloc_howto); */
1439 pcrel = reloc_howto->pc_relative;
1442 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1444 fragP->fr_file, fragP->fr_line,
1445 (fixup->reloc < 0) ? "Internal" :
1446 bfd_get_reloc_code_name (fixup->reloc),
1449 fix_new_exp (fragP, fix + offset,
1450 size, &fixup->exp, pcrel, fixup->reloc);
1452 /* Check for ZOLs, and update symbol info if any. */
1453 if (LP_INSN (insn->insn))
1455 gas_assert (fixup->exp.X_add_symbol);
1456 ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
1461 /* Actually output an instruction with its fixup. */
1464 emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax)
1469 pr_debug ("Emit insn : 0x%llx\n", insn->insn);
1470 pr_debug ("\tLength : 0x%d\n", insn->len);
1471 pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
1473 /* Write out the instruction. */
1474 total_len = insn->len + (insn->has_limm ? 4 : 0);
1476 f = frag_more (total_len);
1478 md_number_to_chars_midend(f, insn->insn, insn->len);
1481 md_number_to_chars_midend (f + insn->len, insn->limm, 4);
1482 dwarf2_emit_insn (total_len);
1485 apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
1489 emit_insn1 (struct arc_insn *insn)
1491 /* How frag_var's args are currently configured:
1492 - rs_machine_dependent, to dictate it's a relaxation frag.
1493 - FRAG_MAX_GROWTH, maximum size of instruction
1494 - 0, variable size that might grow...unused by generic relaxation.
1495 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1496 - s, opand expression.
1497 - 0, offset but it's unused.
1498 - 0, opcode but it's unused. */
1499 symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
1500 frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
1502 if (frag_room () < FRAG_MAX_GROWTH)
1504 /* Handle differently when frag literal memory is exhausted.
1505 This is used because when there's not enough memory left in
1506 the current frag, a new frag is created and the information
1507 we put into frag_now->tc_frag_data is disregarded. */
1509 struct arc_relax_type relax_info_copy;
1510 relax_substateT subtype = frag_now->fr_subtype;
1512 memcpy (&relax_info_copy, &frag_now->tc_frag_data,
1513 sizeof (struct arc_relax_type));
1515 frag_wane (frag_now);
1516 frag_grow (FRAG_MAX_GROWTH);
1518 memcpy (&frag_now->tc_frag_data, &relax_info_copy,
1519 sizeof (struct arc_relax_type));
1521 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1525 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1526 frag_now->fr_subtype, s, 0, 0);
1530 emit_insn (struct arc_insn *insn)
1535 emit_insn0 (insn, NULL, FALSE);
1538 /* Check whether a symbol involves a register. */
1541 contains_register (symbolS *sym)
1545 expressionS *ex = symbol_get_value_expression (sym);
1547 return ((O_register == ex->X_op)
1548 && !contains_register (ex->X_add_symbol)
1549 && !contains_register (ex->X_op_symbol));
1555 /* Returns the register number within a symbol. */
1558 get_register (symbolS *sym)
1560 if (!contains_register (sym))
1563 expressionS *ex = symbol_get_value_expression (sym);
1564 return regno (ex->X_add_number);
1567 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1568 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1571 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
1578 case BFD_RELOC_ARC_SDA_LDST:
1579 case BFD_RELOC_ARC_SDA_LDST1:
1580 case BFD_RELOC_ARC_SDA_LDST2:
1581 case BFD_RELOC_ARC_SDA16_LD:
1582 case BFD_RELOC_ARC_SDA16_LD1:
1583 case BFD_RELOC_ARC_SDA16_LD2:
1584 case BFD_RELOC_ARC_SDA16_ST2:
1585 case BFD_RELOC_ARC_SDA32_ME:
1592 /* Allocates a tok entry. */
1595 allocate_tok (expressionS *tok, int ntok, int cidx)
1597 if (ntok > MAX_INSN_ARGS - 2)
1598 return 0; /* No space left. */
1601 return 0; /* Incorrect args. */
1603 memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
1606 return 1; /* Success. */
1607 return allocate_tok (tok, ntok - 1, cidx);
1610 /* Check if an particular ARC feature is enabled. */
1613 check_cpu_feature (insn_subclass_t sc)
1615 if (is_code_density_p (sc) && !(selected_cpu.features & CD))
1618 if (is_spfp_p (sc) && !(selected_cpu.features & SPX))
1621 if (is_dpfp_p (sc) && !(selected_cpu.features & DPX))
1624 if (is_fpuda_p (sc) && !(selected_cpu.features & DPA))
1627 if (is_nps400_p (sc) && !(selected_cpu.features & NPS400))
1633 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1634 operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG
1635 array and returns TRUE if the flag operands all match, otherwise,
1636 returns FALSE, in which case the FIRST_PFLAG array may have been
1640 parse_opcode_flags (const struct arc_opcode *opcode,
1642 struct arc_flags *first_pflag)
1645 const unsigned char *flgidx;
1648 for (i = 0; i < nflgs; i++)
1649 first_pflag[i].flgp = NULL;
1651 /* Check the flags. Iterate over the valid flag classes. */
1652 for (flgidx = opcode->flags; *flgidx; ++flgidx)
1654 /* Get a valid flag class. */
1655 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
1656 const unsigned *flgopridx;
1658 struct arc_flags *pflag = NULL;
1660 /* Check if opcode has implicit flag classes. */
1661 if (cl_flags->flag_class & F_CLASS_IMPLICIT)
1664 /* Check for extension conditional codes. */
1665 if (ext_condcode.arc_ext_condcode
1666 && cl_flags->flag_class & F_CLASS_EXTEND)
1668 struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode;
1671 pflag = first_pflag;
1672 for (i = 0; i < nflgs; i++, pflag++)
1674 if (!strcmp (pf->name, pflag->name))
1676 if (pflag->flgp != NULL)
1689 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
1691 const struct arc_flag_operand *flg_operand;
1693 pflag = first_pflag;
1694 flg_operand = &arc_flag_operands[*flgopridx];
1695 for (i = 0; i < nflgs; i++, pflag++)
1697 /* Match against the parsed flags. */
1698 if (!strcmp (flg_operand->name, pflag->name))
1700 if (pflag->flgp != NULL)
1703 pflag->flgp = flg_operand;
1705 break; /* goto next flag class and parsed flag. */
1710 if ((cl_flags->flag_class & F_CLASS_REQUIRED) && cl_matches == 0)
1712 if ((cl_flags->flag_class & F_CLASS_OPTIONAL) && cl_matches > 1)
1716 /* Did I check all the parsed flags? */
1717 return lnflg ? FALSE : TRUE;
1721 /* Search forward through all variants of an opcode looking for a
1724 static const struct arc_opcode *
1725 find_opcode_match (const struct arc_opcode_hash_entry *entry,
1728 struct arc_flags *first_pflag,
1731 const char **errmsg)
1733 const struct arc_opcode *opcode;
1734 struct arc_opcode_hash_entry_iterator iter;
1736 int got_cpu_match = 0;
1737 expressionS bktok[MAX_INSN_ARGS];
1741 arc_opcode_hash_entry_iterator_init (&iter);
1742 memset (&emptyE, 0, sizeof (emptyE));
1743 memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
1746 for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter);
1748 opcode = arc_opcode_hash_entry_iterator_next (entry, &iter))
1750 const unsigned char *opidx;
1752 const expressionS *t = &emptyE;
1754 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
1755 frag_now->fr_file, frag_now->fr_line, opcode->opcode);
1757 /* Don't match opcodes that don't exist on this
1759 if (!(opcode->cpu & selected_cpu.flags))
1762 if (!check_cpu_feature (opcode->subclass))
1768 /* Check the operands. */
1769 for (opidx = opcode->operands; *opidx; ++opidx)
1771 const struct arc_operand *operand = &arc_operands[*opidx];
1773 /* Only take input from real operands. */
1774 if (ARC_OPERAND_IS_FAKE (operand))
1777 /* When we expect input, make sure we have it. */
1781 /* Match operand type with expression type. */
1782 switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
1784 case ARC_OPERAND_ADDRTYPE:
1788 /* Check to be an address type. */
1789 if (tok[tokidx].X_op != O_addrtype)
1792 /* All address type operands need to have an insert
1793 method in order to check that we have the correct
1795 gas_assert (operand->insert != NULL);
1796 (*operand->insert) (0, tok[tokidx].X_add_number,
1798 if (*errmsg != NULL)
1803 case ARC_OPERAND_IR:
1804 /* Check to be a register. */
1805 if ((tok[tokidx].X_op != O_register
1806 || !is_ir_num (tok[tokidx].X_add_number))
1807 && !(operand->flags & ARC_OPERAND_IGNORE))
1810 /* If expect duplicate, make sure it is duplicate. */
1811 if (operand->flags & ARC_OPERAND_DUPLICATE)
1813 /* Check for duplicate. */
1814 if (t->X_op != O_register
1815 || !is_ir_num (t->X_add_number)
1816 || (regno (t->X_add_number) !=
1817 regno (tok[tokidx].X_add_number)))
1821 /* Special handling? */
1822 if (operand->insert)
1825 (*operand->insert)(0,
1826 regno (tok[tokidx].X_add_number),
1830 if (operand->flags & ARC_OPERAND_IGNORE)
1832 /* Missing argument, create one. */
1833 if (!allocate_tok (tok, ntok - 1, tokidx))
1836 tok[tokidx].X_op = O_absent;
1847 case ARC_OPERAND_BRAKET:
1848 /* Check if bracket is also in opcode table as
1850 if (tok[tokidx].X_op != O_bracket)
1854 case ARC_OPERAND_COLON:
1855 /* Check if colon is also in opcode table as operand. */
1856 if (tok[tokidx].X_op != O_colon)
1860 case ARC_OPERAND_LIMM:
1861 case ARC_OPERAND_SIGNED:
1862 case ARC_OPERAND_UNSIGNED:
1863 switch (tok[tokidx].X_op)
1871 /* Got an (too) early bracket, check if it is an
1872 ignored operand. N.B. This procedure works only
1873 when bracket is the last operand! */
1874 if (!(operand->flags & ARC_OPERAND_IGNORE))
1876 /* Insert the missing operand. */
1877 if (!allocate_tok (tok, ntok - 1, tokidx))
1880 tok[tokidx].X_op = O_absent;
1888 const struct arc_aux_reg *auxr;
1890 if (opcode->insn_class != AUXREG)
1892 p = S_GET_NAME (tok[tokidx].X_add_symbol);
1894 /* For compatibility reasons, an aux register can
1895 be spelled with upper or lower case
1898 for (pp = tmpp; *pp; ++pp) *pp = TOLOWER (*pp);
1900 auxr = hash_find (arc_aux_hash, tmpp);
1903 /* We modify the token array here, safe in the
1904 knowledge, that if this was the wrong
1905 choice then the original contents will be
1906 restored from BKTOK. */
1907 tok[tokidx].X_op = O_constant;
1908 tok[tokidx].X_add_number = auxr->address;
1909 ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX);
1913 if (tok[tokidx].X_op != O_constant)
1918 /* Check the range. */
1919 if (operand->bits != 32
1920 && !(operand->flags & ARC_OPERAND_NCHK))
1922 offsetT min, max, val;
1923 val = tok[tokidx].X_add_number;
1925 if (operand->flags & ARC_OPERAND_SIGNED)
1927 max = (1 << (operand->bits - 1)) - 1;
1928 min = -(1 << (operand->bits - 1));
1932 max = (1 << operand->bits) - 1;
1936 if (val < min || val > max)
1939 /* Check alignments. */
1940 if ((operand->flags & ARC_OPERAND_ALIGNED32)
1944 if ((operand->flags & ARC_OPERAND_ALIGNED16)
1948 else if (operand->flags & ARC_OPERAND_NCHK)
1950 if (operand->insert)
1953 (*operand->insert)(0,
1954 tok[tokidx].X_add_number,
1959 else if (!(operand->flags & ARC_OPERAND_IGNORE))
1965 /* Check if it is register range. */
1966 if ((tok[tokidx].X_add_number == 0)
1967 && contains_register (tok[tokidx].X_add_symbol)
1968 && contains_register (tok[tokidx].X_op_symbol))
1972 regs = get_register (tok[tokidx].X_add_symbol);
1974 regs |= get_register (tok[tokidx].X_op_symbol);
1975 if (operand->insert)
1978 (*operand->insert)(0,
1991 if (operand->default_reloc == 0)
1992 goto match_failed; /* The operand needs relocation. */
1994 /* Relocs requiring long immediate. FIXME! make it
1995 generic and move it to a function. */
1996 switch (tok[tokidx].X_md)
2005 if (!(operand->flags & ARC_OPERAND_LIMM))
2009 if (!generic_reloc_p (operand->default_reloc))
2017 /* If expect duplicate, make sure it is duplicate. */
2018 if (operand->flags & ARC_OPERAND_DUPLICATE)
2020 if (t->X_op == O_illegal
2021 || t->X_op == O_absent
2022 || t->X_op == O_register
2023 || (t->X_add_number != tok[tokidx].X_add_number))
2030 /* Everything else should have been fake. */
2038 /* Setup ready for flag parsing. */
2039 if (!parse_opcode_flags (opcode, nflgs, first_pflag))
2043 /* Possible match -- did we use all of our input? */
2053 /* Restore the original parameters. */
2054 memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
2059 *pcpumatch = got_cpu_match;
2064 /* Swap operand tokens. */
2067 swap_operand (expressionS *operand_array,
2069 unsigned destination)
2071 expressionS cpy_operand;
2072 expressionS *src_operand;
2073 expressionS *dst_operand;
2076 if (source == destination)
2079 src_operand = &operand_array[source];
2080 dst_operand = &operand_array[destination];
2081 size = sizeof (expressionS);
2083 /* Make copy of operand to swap with and swap. */
2084 memcpy (&cpy_operand, dst_operand, size);
2085 memcpy (dst_operand, src_operand, size);
2086 memcpy (src_operand, &cpy_operand, size);
2089 /* Check if *op matches *tok type.
2090 Returns FALSE if they don't match, TRUE if they match. */
2093 pseudo_operand_match (const expressionS *tok,
2094 const struct arc_operand_operation *op)
2096 offsetT min, max, val;
2098 const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
2104 if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
2106 else if (!(operand_real->flags & ARC_OPERAND_IR))
2108 val = tok->X_add_number + op->count;
2109 if (operand_real->flags & ARC_OPERAND_SIGNED)
2111 max = (1 << (operand_real->bits - 1)) - 1;
2112 min = -(1 << (operand_real->bits - 1));
2116 max = (1 << operand_real->bits) - 1;
2119 if (min <= val && val <= max)
2125 /* Handle all symbols as long immediates or signed 9. */
2126 if (operand_real->flags & ARC_OPERAND_LIMM
2127 || ((operand_real->flags & ARC_OPERAND_SIGNED)
2128 && operand_real->bits == 9))
2133 if (operand_real->flags & ARC_OPERAND_IR)
2138 if (operand_real->flags & ARC_OPERAND_BRAKET)
2149 /* Find pseudo instruction in array. */
2151 static const struct arc_pseudo_insn *
2152 find_pseudo_insn (const char *opname,
2154 const expressionS *tok)
2156 const struct arc_pseudo_insn *pseudo_insn = NULL;
2157 const struct arc_operand_operation *op;
2161 for (i = 0; i < arc_num_pseudo_insn; ++i)
2163 pseudo_insn = &arc_pseudo_insns[i];
2164 if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
2166 op = pseudo_insn->operand;
2167 for (j = 0; j < ntok; ++j)
2168 if (!pseudo_operand_match (&tok[j], &op[j]))
2171 /* Found the right instruction. */
2179 /* Assumes the expressionS *tok is of sufficient size. */
2181 static const struct arc_opcode_hash_entry *
2182 find_special_case_pseudo (const char *opname,
2186 struct arc_flags *pflags)
2188 const struct arc_pseudo_insn *pseudo_insn = NULL;
2189 const struct arc_operand_operation *operand_pseudo;
2190 const struct arc_operand *operand_real;
2192 char construct_operand[MAX_CONSTR_STR];
2194 /* Find whether opname is in pseudo instruction array. */
2195 pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
2197 if (pseudo_insn == NULL)
2200 /* Handle flag, Limited to one flag at the moment. */
2201 if (pseudo_insn->flag_r != NULL)
2202 *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
2203 MAX_INSN_FLGS - *nflgs);
2205 /* Handle operand operations. */
2206 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2208 operand_pseudo = &pseudo_insn->operand[i];
2209 operand_real = &arc_operands[operand_pseudo->operand_idx];
2211 if (operand_real->flags & ARC_OPERAND_BRAKET
2212 && !operand_pseudo->needs_insert)
2215 /* Has to be inserted (i.e. this token does not exist yet). */
2216 if (operand_pseudo->needs_insert)
2218 if (operand_real->flags & ARC_OPERAND_BRAKET)
2220 tok[i].X_op = O_bracket;
2225 /* Check if operand is a register or constant and handle it
2227 if (operand_real->flags & ARC_OPERAND_IR)
2228 snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
2229 operand_pseudo->count);
2231 snprintf (construct_operand, MAX_CONSTR_STR, "%d",
2232 operand_pseudo->count);
2234 tokenize_arguments (construct_operand, &tok[i], 1);
2238 else if (operand_pseudo->count)
2240 /* Operand number has to be adjusted accordingly (by operand
2242 switch (tok[i].X_op)
2245 tok[i].X_add_number += operand_pseudo->count;
2258 /* Swap operands if necessary. Only supports one swap at the
2260 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2262 operand_pseudo = &pseudo_insn->operand[i];
2264 if (operand_pseudo->swap_operand_idx == i)
2267 swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2269 /* Prevent a swap back later by breaking out. */
2273 return arc_find_opcode (pseudo_insn->mnemonic_r);
2276 static const struct arc_opcode_hash_entry *
2277 find_special_case_flag (const char *opname,
2279 struct arc_flags *pflags)
2283 unsigned flag_idx, flag_arr_idx;
2284 size_t flaglen, oplen;
2285 const struct arc_flag_special *arc_flag_special_opcode;
2286 const struct arc_opcode_hash_entry *entry;
2288 /* Search for special case instruction. */
2289 for (i = 0; i < arc_num_flag_special; i++)
2291 arc_flag_special_opcode = &arc_flag_special_cases[i];
2292 oplen = strlen (arc_flag_special_opcode->name);
2294 if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2297 /* Found a potential special case instruction, now test for
2299 for (flag_arr_idx = 0;; ++flag_arr_idx)
2301 flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2303 break; /* End of array, nothing found. */
2305 flagnm = arc_flag_operands[flag_idx].name;
2306 flaglen = strlen (flagnm);
2307 if (strcmp (opname + oplen, flagnm) == 0)
2309 entry = arc_find_opcode (arc_flag_special_opcode->name);
2311 if (*nflgs + 1 > MAX_INSN_FLGS)
2313 memcpy (pflags[*nflgs].name, flagnm, flaglen);
2314 pflags[*nflgs].name[flaglen] = '\0';
2323 /* Used to find special case opcode. */
2325 static const struct arc_opcode_hash_entry *
2326 find_special_case (const char *opname,
2328 struct arc_flags *pflags,
2332 const struct arc_opcode_hash_entry *entry;
2334 entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
2337 entry = find_special_case_flag (opname, nflgs, pflags);
2342 /* Autodetect cpu attribute list. */
2345 autodetect_attributes (const struct arc_opcode *opcode,
2346 const expressionS *tok,
2354 } mpy_list[] = {{ MPY1E, 1 }, { MPY6E, 6 }, { MPY7E, 7 }, { MPY8E, 8 },
2357 for (i = 0; i < ARRAY_SIZE (feature_list); i++)
2358 if (opcode->subclass == feature_list[i].feature)
2359 selected_cpu.features |= feature_list[i].feature;
2361 for (i = 0; i < ARRAY_SIZE (mpy_list); i++)
2362 if (opcode->subclass == mpy_list[i].feature)
2363 mpy_option = mpy_list[i].encoding;
2365 for (i = 0; i < (unsigned) ntok; i++)
2367 switch (tok[i].X_md)
2389 switch (tok[i].X_op)
2392 if ((tok[i].X_add_number >= 4 && tok[i].X_add_number <= 9)
2393 || (tok[i].X_add_number >= 16 && tok[i].X_add_number <= 25))
2402 /* Given an opcode name, pre-tockenized set of argumenst and the
2403 opcode flags, take it all the way through emission. */
2406 assemble_tokens (const char *opname,
2409 struct arc_flags *pflags,
2412 bfd_boolean found_something = FALSE;
2413 const struct arc_opcode_hash_entry *entry;
2415 const char *errmsg = NULL;
2417 /* Search opcodes. */
2418 entry = arc_find_opcode (opname);
2420 /* Couldn't find opcode conventional way, try special cases. */
2422 entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
2426 const struct arc_opcode *opcode;
2428 pr_debug ("%s:%d: assemble_tokens: %s\n",
2429 frag_now->fr_file, frag_now->fr_line, opname);
2430 found_something = TRUE;
2431 opcode = find_opcode_match (entry, tok, &ntok, pflags,
2432 nflgs, &cpumatch, &errmsg);
2435 struct arc_insn insn;
2437 autodetect_attributes (opcode, tok, ntok);
2438 assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
2444 if (found_something)
2448 as_bad (_("%s for instruction '%s'"), errmsg, opname);
2450 as_bad (_("inappropriate arguments for opcode '%s'"), opname);
2452 as_bad (_("opcode '%s' not supported for target %s"), opname,
2456 as_bad (_("unknown opcode '%s'"), opname);
2459 /* The public interface to the instruction assembler. */
2462 md_assemble (char *str)
2465 expressionS tok[MAX_INSN_ARGS];
2468 struct arc_flags flags[MAX_INSN_FLGS];
2470 /* Split off the opcode. */
2471 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
2472 opname = xmemdup0 (str, opnamelen);
2474 /* Signalize we are assembling the instructions. */
2475 assembling_insn = TRUE;
2477 /* Tokenize the flags. */
2478 if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2480 as_bad (_("syntax error"));
2484 /* Scan up to the end of the mnemonic which must end in space or end
2487 for (; *str != '\0'; str++)
2491 /* Tokenize the rest of the line. */
2492 if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2494 as_bad (_("syntax error"));
2498 /* Finish it off. */
2499 assemble_tokens (opname, tok, ntok, flags, nflg);
2500 assembling_insn = FALSE;
2503 /* Callback to insert a register into the hash table. */
2506 declare_register (const char *name, int number)
2509 symbolS *regS = symbol_create (name, reg_section,
2510 number, &zero_address_frag);
2512 err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
2514 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2518 /* Construct symbols for each of the general registers. */
2521 declare_register_set (void)
2524 for (i = 0; i < 64; ++i)
2528 sprintf (name, "r%d", i);
2529 declare_register (name, i);
2530 if ((i & 0x01) == 0)
2532 sprintf (name, "r%dr%d", i, i+1);
2533 declare_register (name, i);
2538 /* Construct a symbol for an address type. */
2541 declare_addrtype (const char *name, int number)
2544 symbolS *addrtypeS = symbol_create (name, undefined_section,
2545 number, &zero_address_frag);
2547 err = hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS),
2548 (void *) addrtypeS);
2550 as_fatal (_("Inserting \"%s\" into address type table failed: %s"),
2554 /* Port-specific assembler initialization. This function is called
2555 once, at assembler startup time. */
2560 const struct arc_opcode *opcode = arc_opcodes;
2562 if (mach_selection_mode == MACH_SELECTION_NONE)
2563 arc_select_cpu (TARGET_WITH_CPU, MACH_SELECTION_FROM_DEFAULT);
2565 /* The endianness can be chosen "at the factory". */
2566 target_big_endian = byte_order == BIG_ENDIAN;
2568 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
2569 as_warn (_("could not set architecture and machine"));
2571 /* Set elf header flags. */
2572 bfd_set_private_flags (stdoutput, selected_cpu.eflags);
2574 /* Set up a hash table for the instructions. */
2575 arc_opcode_hash = hash_new ();
2576 if (arc_opcode_hash == NULL)
2577 as_fatal (_("Virtual memory exhausted"));
2579 /* Initialize the hash table with the insns. */
2582 const char *name = opcode->name;
2584 arc_insert_opcode (opcode);
2586 while (++opcode && opcode->name
2587 && (opcode->name == name
2588 || !strcmp (opcode->name, name)))
2590 }while (opcode->name);
2592 /* Register declaration. */
2593 arc_reg_hash = hash_new ();
2594 if (arc_reg_hash == NULL)
2595 as_fatal (_("Virtual memory exhausted"));
2597 declare_register_set ();
2598 declare_register ("gp", 26);
2599 declare_register ("fp", 27);
2600 declare_register ("sp", 28);
2601 declare_register ("ilink", 29);
2602 declare_register ("ilink1", 29);
2603 declare_register ("ilink2", 30);
2604 declare_register ("blink", 31);
2606 /* XY memory registers. */
2607 declare_register ("x0_u0", 32);
2608 declare_register ("x0_u1", 33);
2609 declare_register ("x1_u0", 34);
2610 declare_register ("x1_u1", 35);
2611 declare_register ("x2_u0", 36);
2612 declare_register ("x2_u1", 37);
2613 declare_register ("x3_u0", 38);
2614 declare_register ("x3_u1", 39);
2615 declare_register ("y0_u0", 40);
2616 declare_register ("y0_u1", 41);
2617 declare_register ("y1_u0", 42);
2618 declare_register ("y1_u1", 43);
2619 declare_register ("y2_u0", 44);
2620 declare_register ("y2_u1", 45);
2621 declare_register ("y3_u0", 46);
2622 declare_register ("y3_u1", 47);
2623 declare_register ("x0_nu", 48);
2624 declare_register ("x1_nu", 49);
2625 declare_register ("x2_nu", 50);
2626 declare_register ("x3_nu", 51);
2627 declare_register ("y0_nu", 52);
2628 declare_register ("y1_nu", 53);
2629 declare_register ("y2_nu", 54);
2630 declare_register ("y3_nu", 55);
2632 declare_register ("mlo", 57);
2633 declare_register ("mmid", 58);
2634 declare_register ("mhi", 59);
2636 declare_register ("acc1", 56);
2637 declare_register ("acc2", 57);
2639 declare_register ("lp_count", 60);
2640 declare_register ("pcl", 63);
2642 /* Initialize the last instructions. */
2643 memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2645 /* Aux register declaration. */
2646 arc_aux_hash = hash_new ();
2647 if (arc_aux_hash == NULL)
2648 as_fatal (_("Virtual memory exhausted"));
2650 const struct arc_aux_reg *auxr = &arc_aux_regs[0];
2652 for (i = 0; i < arc_num_aux_regs; i++, auxr++)
2656 if (!(auxr->cpu & selected_cpu.flags))
2659 if ((auxr->subclass != NONE)
2660 && !check_cpu_feature (auxr->subclass))
2663 retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr);
2665 as_fatal (_("internal error: can't hash aux register '%s': %s"),
2666 auxr->name, retval);
2669 /* Address type declaration. */
2670 arc_addrtype_hash = hash_new ();
2671 if (arc_addrtype_hash == NULL)
2672 as_fatal (_("Virtual memory exhausted"));
2674 declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD);
2675 declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID);
2676 declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD);
2677 declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD);
2678 declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD);
2679 declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM);
2680 declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA);
2681 declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD);
2682 declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD);
2683 declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD);
2684 declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID);
2685 declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD);
2686 declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM);
2687 declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD);
2688 declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA);
2689 declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD);
2692 /* Write a value out to the object file, using the appropriate
2696 md_number_to_chars (char *buf,
2700 if (target_big_endian)
2701 number_to_chars_bigendian (buf, val, n);
2703 number_to_chars_littleendian (buf, val, n);
2706 /* Round up a section size to the appropriate boundary. */
2709 md_section_align (segT segment,
2712 int align = bfd_get_section_alignment (stdoutput, segment);
2714 return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
2717 /* The location from which a PC relative jump should be calculated,
2718 given a PC relative reloc. */
2721 md_pcrel_from_section (fixS *fixP,
2724 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
2726 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
2728 if (fixP->fx_addsy != (symbolS *) NULL
2729 && (!S_IS_DEFINED (fixP->fx_addsy)
2730 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2732 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
2734 /* The symbol is undefined (or is defined but not in this section).
2735 Let the linker figure it out. */
2739 if ((int) fixP->fx_r_type < 0)
2741 /* These are the "internal" relocations. Align them to
2742 32 bit boundary (PCL), for the moment. */
2747 switch (fixP->fx_r_type)
2749 case BFD_RELOC_ARC_PC32:
2750 /* The hardware calculates relative to the start of the
2751 insn, but this relocation is relative to location of the
2752 LIMM, compensate. The base always needs to be
2753 subtracted by 4 as we do not support this type of PCrel
2754 relocation for short instructions. */
2757 case BFD_RELOC_ARC_PLT32:
2758 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2759 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2760 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2761 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2763 case BFD_RELOC_ARC_S21H_PCREL:
2764 case BFD_RELOC_ARC_S25H_PCREL:
2765 case BFD_RELOC_ARC_S13_PCREL:
2766 case BFD_RELOC_ARC_S21W_PCREL:
2767 case BFD_RELOC_ARC_S25W_PCREL:
2771 as_bad_where (fixP->fx_file, fixP->fx_line,
2772 _("unhandled reloc %s in md_pcrel_from_section"),
2773 bfd_get_reloc_code_name (fixP->fx_r_type));
2778 pr_debug ("pcrel from %"BFD_VMA_FMT"x + %lx = %"BFD_VMA_FMT"x, "
2779 "symbol: %s (%"BFD_VMA_FMT"x)\n",
2780 fixP->fx_frag->fr_address, fixP->fx_where, base,
2781 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
2782 fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
2787 /* Given a BFD relocation find the corresponding operand. */
2789 static const struct arc_operand *
2790 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
2794 for (i = 0; i < arc_num_operands; i++)
2795 if (arc_operands[i].default_reloc == reloc)
2796 return &arc_operands[i];
2800 /* Insert an operand value into an instruction. */
2802 static unsigned long long
2803 insert_operand (unsigned long long insn,
2804 const struct arc_operand *operand,
2809 offsetT min = 0, max = 0;
2811 if (operand->bits != 32
2812 && !(operand->flags & ARC_OPERAND_NCHK)
2813 && !(operand->flags & ARC_OPERAND_FAKE))
2815 if (operand->flags & ARC_OPERAND_SIGNED)
2817 max = (1 << (operand->bits - 1)) - 1;
2818 min = -(1 << (operand->bits - 1));
2822 max = (1 << operand->bits) - 1;
2826 if (val < min || val > max)
2827 as_bad_value_out_of_range (_("operand"),
2828 val, min, max, file, line);
2831 pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
2832 min, val, max, insn);
2834 if ((operand->flags & ARC_OPERAND_ALIGNED32)
2836 as_bad_where (file, line,
2837 _("Unaligned operand. Needs to be 32bit aligned"));
2839 if ((operand->flags & ARC_OPERAND_ALIGNED16)
2841 as_bad_where (file, line,
2842 _("Unaligned operand. Needs to be 16bit aligned"));
2844 if (operand->insert)
2846 const char *errmsg = NULL;
2848 insn = (*operand->insert) (insn, val, &errmsg);
2850 as_warn_where (file, line, "%s", errmsg);
2854 if (operand->flags & ARC_OPERAND_TRUNCATE)
2856 if (operand->flags & ARC_OPERAND_ALIGNED32)
2858 if (operand->flags & ARC_OPERAND_ALIGNED16)
2861 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2866 /* Apply a fixup to the object code. At this point all symbol values
2867 should be fully resolved, and we attempt to completely resolve the
2868 reloc. If we can not do that, we determine the correct reloc code
2869 and put it back in the fixup. To indicate that a fixup has been
2870 eliminated, set fixP->fx_done. */
2873 md_apply_fix (fixS *fixP,
2877 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
2878 valueT value = *valP;
2880 symbolS *fx_addsy, *fx_subsy;
2882 segT add_symbol_segment = absolute_section;
2883 segT sub_symbol_segment = absolute_section;
2884 const struct arc_operand *operand = NULL;
2885 extended_bfd_reloc_code_real_type reloc;
2887 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2888 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2889 ((int) fixP->fx_r_type < 0) ? "Internal":
2890 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2893 fx_addsy = fixP->fx_addsy;
2894 fx_subsy = fixP->fx_subsy;
2899 add_symbol_segment = S_GET_SEGMENT (fx_addsy);
2903 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
2904 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
2905 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
2907 resolve_symbol_value (fx_subsy);
2908 sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
2910 if (sub_symbol_segment == absolute_section)
2912 /* The symbol is really a constant. */
2913 fx_offset -= S_GET_VALUE (fx_subsy);
2918 as_bad_where (fixP->fx_file, fixP->fx_line,
2919 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2920 fx_addsy ? S_GET_NAME (fx_addsy) : "0",
2921 segment_name (add_symbol_segment),
2922 S_GET_NAME (fx_subsy),
2923 segment_name (sub_symbol_segment));
2929 && !S_IS_WEAK (fx_addsy))
2931 if (add_symbol_segment == seg
2934 value += S_GET_VALUE (fx_addsy);
2935 value -= md_pcrel_from_section (fixP, seg);
2937 fixP->fx_pcrel = FALSE;
2939 else if (add_symbol_segment == absolute_section)
2941 value = fixP->fx_offset;
2942 fx_offset += S_GET_VALUE (fixP->fx_addsy);
2944 fixP->fx_pcrel = FALSE;
2949 fixP->fx_done = TRUE;
2954 && ((S_IS_DEFINED (fx_addsy)
2955 && S_GET_SEGMENT (fx_addsy) != seg)
2956 || S_IS_WEAK (fx_addsy)))
2957 value += md_pcrel_from_section (fixP, seg);
2959 switch (fixP->fx_r_type)
2961 case BFD_RELOC_ARC_32_ME:
2962 /* This is a pc-relative value in a LIMM. Adjust it to the
2963 address of the instruction not to the address of the
2964 LIMM. Note: it is not any longer valid this affirmation as
2965 the linker consider ARC_PC32 a fixup to entire 64 bit
2967 fixP->fx_offset += fixP->fx_frag->fr_address;
2970 fixP->fx_r_type = BFD_RELOC_ARC_PC32;
2972 case BFD_RELOC_ARC_PC32:
2973 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2976 if ((int) fixP->fx_r_type < 0)
2977 as_bad_where (fixP->fx_file, fixP->fx_line,
2978 _("PC relative relocation not allowed for (internal)"
2985 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2986 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2987 ((int) fixP->fx_r_type < 0) ? "Internal":
2988 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2992 /* Now check for TLS relocations. */
2993 reloc = fixP->fx_r_type;
2996 case BFD_RELOC_ARC_TLS_DTPOFF:
2997 case BFD_RELOC_ARC_TLS_LE_32:
3001 case BFD_RELOC_ARC_TLS_GD_GOT:
3002 case BFD_RELOC_ARC_TLS_IE_GOT:
3003 S_SET_THREAD_LOCAL (fixP->fx_addsy);
3006 case BFD_RELOC_ARC_TLS_GD_LD:
3007 gas_assert (!fixP->fx_offset);
3010 = (S_GET_VALUE (fixP->fx_subsy)
3011 - fixP->fx_frag->fr_address- fixP->fx_where);
3012 fixP->fx_subsy = NULL;
3014 case BFD_RELOC_ARC_TLS_GD_CALL:
3015 /* These two relocs are there just to allow ld to change the tls
3016 model for this symbol, by patching the code. The offset -
3017 and scale, if any - will be installed by the linker. */
3018 S_SET_THREAD_LOCAL (fixP->fx_addsy);
3021 case BFD_RELOC_ARC_TLS_LE_S9:
3022 case BFD_RELOC_ARC_TLS_DTPOFF_S9:
3023 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3035 /* Adjust the value if we have a constant. */
3038 /* For hosts with longs bigger than 32-bits make sure that the top
3039 bits of a 32-bit negative value read in by the parser are set,
3040 so that the correct comparisons are made. */
3041 if (value & 0x80000000)
3042 value |= (-1UL << 31);
3044 reloc = fixP->fx_r_type;
3052 case BFD_RELOC_ARC_32_PCREL:
3053 md_number_to_chars (fixpos, value, fixP->fx_size);
3056 case BFD_RELOC_ARC_GOTPC32:
3057 /* I cannot fix an GOTPC relocation because I need to relax it
3058 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
3059 as_bad (_("Unsupported operation on reloc"));
3062 case BFD_RELOC_ARC_TLS_DTPOFF:
3063 case BFD_RELOC_ARC_TLS_LE_32:
3064 gas_assert (!fixP->fx_addsy);
3065 gas_assert (!fixP->fx_subsy);
3068 case BFD_RELOC_ARC_GOTOFF:
3069 case BFD_RELOC_ARC_32_ME:
3070 case BFD_RELOC_ARC_PC32:
3071 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
3074 case BFD_RELOC_ARC_PLT32:
3075 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
3078 case BFD_RELOC_ARC_S25H_PCREL_PLT:
3079 reloc = BFD_RELOC_ARC_S25W_PCREL;
3082 case BFD_RELOC_ARC_S21H_PCREL_PLT:
3083 reloc = BFD_RELOC_ARC_S21H_PCREL;
3086 case BFD_RELOC_ARC_S25W_PCREL_PLT:
3087 reloc = BFD_RELOC_ARC_S25W_PCREL;
3090 case BFD_RELOC_ARC_S21W_PCREL_PLT:
3091 reloc = BFD_RELOC_ARC_S21W_PCREL;
3094 case BFD_RELOC_ARC_S25W_PCREL:
3095 case BFD_RELOC_ARC_S21W_PCREL:
3096 case BFD_RELOC_ARC_S21H_PCREL:
3097 case BFD_RELOC_ARC_S25H_PCREL:
3098 case BFD_RELOC_ARC_S13_PCREL:
3100 operand = find_operand_for_reloc (reloc);
3101 gas_assert (operand);
3106 if ((int) fixP->fx_r_type >= 0)
3107 as_fatal (_("unhandled relocation type %s"),
3108 bfd_get_reloc_code_name (fixP->fx_r_type));
3110 /* The rest of these fixups needs to be completely resolved as
3112 if (fixP->fx_addsy != 0
3113 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
3114 as_bad_where (fixP->fx_file, fixP->fx_line,
3115 _("non-absolute expression in constant field"));
3117 gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
3118 operand = &arc_operands[-(int) fixP->fx_r_type];
3123 if (target_big_endian)
3125 switch (fixP->fx_size)
3128 insn = bfd_getb32 (fixpos);
3131 insn = bfd_getb16 (fixpos);
3134 as_bad_where (fixP->fx_file, fixP->fx_line,
3135 _("unknown fixup size"));
3141 switch (fixP->fx_size)
3144 insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
3147 insn = bfd_getl16 (fixpos);
3150 as_bad_where (fixP->fx_file, fixP->fx_line,
3151 _("unknown fixup size"));
3155 insn = insert_operand (insn, operand, (offsetT) value,
3156 fixP->fx_file, fixP->fx_line);
3158 md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
3161 /* Prepare machine-dependent frags for relaxation.
3163 Called just before relaxation starts. Any symbol that is now undefined
3164 will not become defined.
3166 Return the correct fr_subtype in the frag.
3168 Return the initial "guess for fr_var" to caller. The guess for fr_var
3169 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3170 or fr_var contributes to our returned value.
3172 Although it may not be explicit in the frag, pretend
3173 fr_var starts with a value. */
3176 md_estimate_size_before_relax (fragS *fragP,
3181 /* If the symbol is not located within the same section AND it's not
3182 an absolute section, use the maximum. OR if the symbol is a
3183 constant AND the insn is by nature not pc-rel, use the maximum.
3184 OR if the symbol is being equated against another symbol, use the
3185 maximum. OR if the symbol is weak use the maximum. */
3186 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
3187 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
3188 || (symbol_constant_p (fragP->fr_symbol)
3189 && !fragP->tc_frag_data.pcrel)
3190 || symbol_equated_p (fragP->fr_symbol)
3191 || S_IS_WEAK (fragP->fr_symbol))
3193 while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
3194 ++fragP->fr_subtype;
3197 growth = md_relax_table[fragP->fr_subtype].rlx_length;
3198 fragP->fr_var = growth;
3200 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3201 fragP->fr_file, fragP->fr_line, growth);
3206 /* Translate internal representation of relocation info to BFD target
3210 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
3214 bfd_reloc_code_real_type code;
3216 reloc = XNEW (arelent);
3217 reloc->sym_ptr_ptr = XNEW (asymbol *);
3218 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3219 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3221 /* Make sure none of our internal relocations make it this far.
3222 They'd better have been fully resolved by this point. */
3223 gas_assert ((int) fixP->fx_r_type > 0);
3225 code = fixP->fx_r_type;
3227 /* if we have something like add gp, pcl,
3228 _GLOBAL_OFFSET_TABLE_@gotpc. */
3229 if (code == BFD_RELOC_ARC_GOTPC32
3231 && fixP->fx_addsy == GOT_symbol)
3232 code = BFD_RELOC_ARC_GOTPC;
3234 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
3235 if (reloc->howto == NULL)
3237 as_bad_where (fixP->fx_file, fixP->fx_line,
3238 _("cannot represent `%s' relocation in object file"),
3239 bfd_get_reloc_code_name (code));
3243 if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
3244 as_fatal (_("internal error? cannot generate `%s' relocation"),
3245 bfd_get_reloc_code_name (code));
3247 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
3249 reloc->addend = fixP->fx_offset;
3254 /* Perform post-processing of machine-dependent frags after relaxation.
3255 Called after relaxation is finished.
3256 In: Address of frag.
3257 fr_type == rs_machine_dependent.
3258 fr_subtype is what the address relaxed to.
3260 Out: Any fixS:s and constants are set up. */
3263 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
3264 segT segment ATTRIBUTE_UNUSED,
3267 const relax_typeS *table_entry;
3269 const struct arc_opcode *opcode;
3270 struct arc_insn insn;
3272 struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
3274 fix = (fragP->fr_fix < 0 ? 0 : fragP->fr_fix);
3275 dest = fragP->fr_literal + fix;
3276 table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
3278 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3279 "var: %"BFD_VMA_FMT"d\n",
3280 fragP->fr_file, fragP->fr_line,
3281 fragP->fr_subtype, fix, fragP->fr_var);
3283 if (fragP->fr_subtype <= 0
3284 && fragP->fr_subtype >= arc_num_relax_opcodes)
3285 as_fatal (_("no relaxation found for this instruction."));
3287 opcode = &arc_relax_opcodes[fragP->fr_subtype];
3289 assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
3290 relax_arg->nflg, &insn);
3292 apply_fixups (&insn, fragP, fix);
3294 size = insn.len + (insn.has_limm ? 4 : 0);
3295 gas_assert (table_entry->rlx_length == size);
3296 emit_insn0 (&insn, dest, TRUE);
3298 fragP->fr_fix += table_entry->rlx_length;
3302 /* We have no need to default values of symbols. We could catch
3303 register names here, but that is handled by inserting them all in
3304 the symbol table to begin with. */
3307 md_undefined_symbol (char *name)
3309 /* The arc abi demands that a GOT[0] should be referencible as
3310 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3311 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3313 && (*(name+1) == 'G')
3314 && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)))
3318 if (symbol_find (name))
3319 as_bad ("GOT already in symbol table");
3321 GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
3322 (valueT) 0, &zero_address_frag);
3329 /* Turn a string in input_line_pointer into a floating point constant
3330 of type type, and store the appropriate bytes in *litP. The number
3331 of LITTLENUMS emitted is stored in *sizeP. An error message is
3332 returned, or NULL on OK. */
3335 md_atof (int type, char *litP, int *sizeP)
3337 return ieee_md_atof (type, litP, sizeP, target_big_endian);
3340 /* Called for any expression that can not be recognized. When the
3341 function is called, `input_line_pointer' will point to the start of
3345 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
3347 char *p = input_line_pointer;
3350 input_line_pointer++;
3351 expressionP->X_op = O_symbol;
3352 expression (expressionP);
3356 /* This function is called from the function 'expression', it attempts
3357 to parse special names (in our case register names). It fills in
3358 the expression with the identified register. It returns TRUE if
3359 it is a register and FALSE otherwise. */
3362 arc_parse_name (const char *name,
3363 struct expressionS *e)
3367 if (!assembling_insn)
3370 if (e->X_op == O_symbol)
3373 sym = hash_find (arc_reg_hash, name);
3376 e->X_op = O_register;
3377 e->X_add_number = S_GET_VALUE (sym);
3381 sym = hash_find (arc_addrtype_hash, name);
3384 e->X_op = O_addrtype;
3385 e->X_add_number = S_GET_VALUE (sym);
3393 Invocation line includes a switch not recognized by the base assembler.
3394 See if it's a processor-specific option.
3396 New options (supported) are:
3398 -mcpu=<cpu name> Assemble for selected processor
3399 -EB/-mbig-endian Big-endian
3400 -EL/-mlittle-endian Little-endian
3401 -mrelax Enable relaxation
3403 The following CPU names are recognized:
3404 arc600, arc700, arcem, archs, nps400. */
3407 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
3413 return md_parse_option (OPTION_MCPU, "arc600");
3416 return md_parse_option (OPTION_MCPU, "arc700");
3419 return md_parse_option (OPTION_MCPU, "arcem");
3422 return md_parse_option (OPTION_MCPU, "archs");
3426 arc_select_cpu (arg, MACH_SELECTION_FROM_COMMAND_LINE);
3431 arc_target_format = "elf32-bigarc";
3432 byte_order = BIG_ENDIAN;
3436 arc_target_format = "elf32-littlearc";
3437 byte_order = LITTLE_ENDIAN;
3441 selected_cpu.features |= CD;
3443 arc_check_feature ();
3447 relaxation_state = 1;
3451 selected_cpu.features |= NPS400;
3452 cl_features |= NPS400;
3453 arc_check_feature ();
3457 selected_cpu.features |= SPX;
3459 arc_check_feature ();
3463 selected_cpu.features |= DPX;
3465 arc_check_feature ();
3469 selected_cpu.features |= DPA;
3471 arc_check_feature ();
3474 /* Dummy options are accepted but have no effect. */
3475 case OPTION_USER_MODE:
3476 case OPTION_LD_EXT_MASK:
3479 case OPTION_BARREL_SHIFT:
3480 case OPTION_MIN_MAX:
3485 case OPTION_XMAC_D16:
3486 case OPTION_XMAC_24:
3487 case OPTION_DSP_PACKA:
3490 case OPTION_TELEPHONY:
3491 case OPTION_XYMEMORY:
3504 /* Display the list of cpu names for use in the help text. */
3507 arc_show_cpu_list (FILE *stream)
3510 static const char *space_buf = " ";
3512 fprintf (stream, "%s", space_buf);
3513 offset = strlen (space_buf);
3514 for (i = 0; cpu_types[i].name != NULL; ++i)
3516 bfd_boolean last = (cpu_types[i + 1].name == NULL);
3518 /* If displaying the new cpu name string, and the ', ' (for all
3519 but the last one) will take us past a target width of 80
3520 characters, then it's time for a new line. */
3521 if (offset + strlen (cpu_types[i].name) + (last ? 0 : 2) > 80)
3523 fprintf (stream, "\n%s", space_buf);
3524 offset = strlen (space_buf);
3527 fprintf (stream, "%s%s", cpu_types[i].name, (last ? "\n" : ", "));
3528 offset += strlen (cpu_types [i].name) + (last ? 0 : 2);
3533 md_show_usage (FILE *stream)
3535 fprintf (stream, _("ARC-specific assembler options:\n"));
3537 fprintf (stream, " -mcpu=<cpu name>\t (default: %s), assemble for"
3538 " CPU <cpu name>, one of:\n", TARGET_WITH_CPU);
3539 arc_show_cpu_list (stream);
3540 fprintf (stream, "\n");
3541 fprintf (stream, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3542 fprintf (stream, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3543 fprintf (stream, " -mEM\t\t\t same as -mcpu=arcem\n");
3544 fprintf (stream, " -mHS\t\t\t same as -mcpu=archs\n");
3546 fprintf (stream, " -mnps400\t\t enable NPS-400 extended instructions\n");
3547 fprintf (stream, " -mspfp\t\t enable single-precision floating point"
3549 fprintf (stream, " -mdpfp\t\t enable double-precision floating point"
3551 fprintf (stream, " -mfpuda\t\t enable double-precision assist floating "
3552 "point\n\t\t\t instructions for ARC EM\n");
3555 " -mcode-density\t enable code density option for ARC EM\n");
3557 fprintf (stream, _("\
3558 -EB assemble code for a big-endian cpu\n"));
3559 fprintf (stream, _("\
3560 -EL assemble code for a little-endian cpu\n"));
3561 fprintf (stream, _("\
3562 -mrelax enable relaxation\n"));
3564 fprintf (stream, _("The following ARC-specific assembler options are "
3565 "deprecated and are accepted\nfor compatibility only:\n"));
3567 fprintf (stream, _(" -mEA\n"
3568 " -mbarrel-shifter\n"
3569 " -mbarrel_shifter\n"
3574 " -mld-extension-reg-mask\n"
3590 " -muser-mode-only\n"
3594 /* Find the proper relocation for the given opcode. */
3596 static extended_bfd_reloc_code_real_type
3597 find_reloc (const char *name,
3598 const char *opcodename,
3599 const struct arc_flags *pflags,
3601 extended_bfd_reloc_code_real_type reloc)
3605 bfd_boolean found_flag, tmp;
3606 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
3608 for (i = 0; i < arc_num_equiv_tab; i++)
3610 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
3612 /* Find the entry. */
3613 if (strcmp (name, r->name))
3615 if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
3622 unsigned * psflg = (unsigned *)r->flags;
3626 for (j = 0; j < nflg; j++)
3627 if (!strcmp (pflags[j].name,
3628 arc_flag_operands[*psflg].name))
3649 if (reloc != r->oldreloc)
3656 if (ret == BFD_RELOC_UNUSED)
3657 as_bad (_("Unable to find %s relocation for instruction %s"),
3662 /* All the symbol types that are allowed to be used for
3666 may_relax_expr (expressionS tok)
3668 /* Check if we have unrelaxable relocs. */
3693 /* Checks if flags are in line with relaxable insn. */
3696 relaxable_flag (const struct arc_relaxable_ins *ins,
3697 const struct arc_flags *pflags,
3700 unsigned flag_class,
3705 const struct arc_flag_operand *flag_opand;
3706 int i, counttrue = 0;
3708 /* Iterate through flags classes. */
3709 while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
3711 /* Iterate through flags in flag class. */
3712 while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
3715 flag_opand = &arc_flag_operands[flag];
3716 /* Iterate through flags in ins to compare. */
3717 for (i = 0; i < nflgs; ++i)
3719 if (strcmp (flag_opand->name, pflags[i].name) == 0)
3730 /* If counttrue == nflgs, then all flags have been found. */
3731 return (counttrue == nflgs ? TRUE : FALSE);
3734 /* Checks if operands are in line with relaxable insn. */
3737 relaxable_operand (const struct arc_relaxable_ins *ins,
3738 const expressionS *tok,
3741 const enum rlx_operand_type *operand = &ins->operands[0];
3744 while (*operand != EMPTY)
3746 const expressionS *epr = &tok[i];
3748 if (i != 0 && i >= ntok)
3754 if (!(epr->X_op == O_multiply
3755 || epr->X_op == O_divide
3756 || epr->X_op == O_modulus
3757 || epr->X_op == O_add
3758 || epr->X_op == O_subtract
3759 || epr->X_op == O_symbol))
3765 || (epr->X_add_number != tok[i - 1].X_add_number))
3769 if (epr->X_op != O_register)
3774 if (epr->X_op != O_register)
3777 switch (epr->X_add_number)
3779 case 0: case 1: case 2: case 3:
3780 case 12: case 13: case 14: case 15:
3787 case REGISTER_NO_GP:
3788 if ((epr->X_op != O_register)
3789 || (epr->X_add_number == 26)) /* 26 is the gp register. */
3794 if (epr->X_op != O_bracket)
3799 /* Don't understand, bail out. */
3805 operand = &ins->operands[i];
3808 return (i == ntok ? TRUE : FALSE);
3811 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3814 relax_insn_p (const struct arc_opcode *opcode,
3815 const expressionS *tok,
3817 const struct arc_flags *pflags,
3821 bfd_boolean rv = FALSE;
3823 /* Check the relaxation table. */
3824 for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
3826 const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
3828 if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
3829 && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
3830 && relaxable_operand (arc_rlx_ins, tok, ntok)
3831 && relaxable_flag (arc_rlx_ins, pflags, nflg))
3834 frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
3835 memcpy (&frag_now->tc_frag_data.tok, tok,
3836 sizeof (expressionS) * ntok);
3837 memcpy (&frag_now->tc_frag_data.pflags, pflags,
3838 sizeof (struct arc_flags) * nflg);
3839 frag_now->tc_frag_data.nflg = nflg;
3840 frag_now->tc_frag_data.ntok = ntok;
3848 /* Turn an opcode description and a set of arguments into
3849 an instruction and a fixup. */
3852 assemble_insn (const struct arc_opcode *opcode,
3853 const expressionS *tok,
3855 const struct arc_flags *pflags,
3857 struct arc_insn *insn)
3859 const expressionS *reloc_exp = NULL;
3860 unsigned long long image;
3861 const unsigned char *argidx;
3864 unsigned char pcrel = 0;
3865 bfd_boolean needGOTSymbol;
3866 bfd_boolean has_delay_slot = FALSE;
3867 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3869 memset (insn, 0, sizeof (*insn));
3870 image = opcode->opcode;
3872 pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
3873 frag_now->fr_file, frag_now->fr_line, opcode->name,
3876 /* Handle operands. */
3877 for (argidx = opcode->operands; *argidx; ++argidx)
3879 const struct arc_operand *operand = &arc_operands[*argidx];
3880 const expressionS *t = (const expressionS *) 0;
3882 if (ARC_OPERAND_IS_FAKE (operand))
3885 if (operand->flags & ARC_OPERAND_DUPLICATE)
3887 /* Duplicate operand, already inserted. */
3899 /* Regardless if we have a reloc or not mark the instruction
3900 limm if it is the case. */
3901 if (operand->flags & ARC_OPERAND_LIMM)
3902 insn->has_limm = TRUE;
3907 image = insert_operand (image, operand, regno (t->X_add_number),
3912 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
3914 if (operand->flags & ARC_OPERAND_LIMM)
3915 insn->limm = t->X_add_number;
3921 /* Ignore brackets, colons, and address types. */
3925 gas_assert (operand->flags & ARC_OPERAND_IGNORE);
3929 /* Maybe register range. */
3930 if ((t->X_add_number == 0)
3931 && contains_register (t->X_add_symbol)
3932 && contains_register (t->X_op_symbol))
3936 regs = get_register (t->X_add_symbol);
3938 regs |= get_register (t->X_op_symbol);
3939 image = insert_operand (image, operand, regs, NULL, 0);
3945 /* This operand needs a relocation. */
3946 needGOTSymbol = FALSE;
3951 if (opcode->insn_class == JUMP)
3952 as_bad (_("Unable to use @plt relocation for insn %s"),
3954 needGOTSymbol = TRUE;
3955 reloc = find_reloc ("plt", opcode->name,
3957 operand->default_reloc);
3962 needGOTSymbol = TRUE;
3963 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3966 if (operand->flags & ARC_OPERAND_LIMM)
3968 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3969 if (arc_opcode_len (opcode) == 2
3970 || opcode->insn_class == JUMP)
3971 as_bad (_("Unable to use @pcl relocation for insn %s"),
3976 /* This is a relaxed operand which initially was
3977 limm, choose whatever we have defined in the
3979 reloc = operand->default_reloc;
3983 reloc = find_reloc ("sda", opcode->name,
3985 operand->default_reloc);
3989 needGOTSymbol = TRUE;
3994 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3997 case O_tpoff9: /*FIXME! Check for the conditionality of
3999 case O_dtpoff9: /*FIXME! Check for the conditionality of
4001 as_bad (_("TLS_*_S9 relocs are not supported yet"));
4005 /* Just consider the default relocation. */
4006 reloc = operand->default_reloc;
4010 if (needGOTSymbol && (GOT_symbol == NULL))
4011 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
4018 /* sanity checks. */
4019 reloc_howto_type *reloc_howto
4020 = bfd_reloc_type_lookup (stdoutput,
4021 (bfd_reloc_code_real_type) reloc);
4022 unsigned reloc_bitsize = reloc_howto->bitsize;
4023 if (reloc_howto->rightshift)
4024 reloc_bitsize -= reloc_howto->rightshift;
4025 if (reloc_bitsize != operand->bits)
4027 as_bad (_("invalid relocation %s for field"),
4028 bfd_get_reloc_code_name (reloc));
4033 if (insn->nfixups >= MAX_INSN_FIXUPS)
4034 as_fatal (_("too many fixups"));
4036 struct arc_fixup *fixup;
4037 fixup = &insn->fixups[insn->nfixups++];
4039 fixup->reloc = reloc;
4040 if ((int) reloc < 0)
4041 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
4044 reloc_howto_type *reloc_howto =
4045 bfd_reloc_type_lookup (stdoutput,
4046 (bfd_reloc_code_real_type) fixup->reloc);
4047 pcrel = reloc_howto->pc_relative;
4049 fixup->pcrel = pcrel;
4050 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
4057 for (i = 0; i < nflg; i++)
4059 const struct arc_flag_operand *flg_operand = pflags[i].flgp;
4061 /* Check if the instruction has a delay slot. */
4062 if (!strcmp (flg_operand->name, "d"))
4063 has_delay_slot = TRUE;
4065 /* There is an exceptional case when we cannot insert a flag just as
4066 it is. On ARCv2 the '.t' and '.nt' flags must be handled in
4067 relation with the relative address. Unfortunately, some of the
4068 ARC700 extensions (NPS400) also have a '.nt' flag that should be
4069 handled in the normal way.
4071 Flag operands don't have an architecture field, so we can't
4072 directly validate that FLAG_OPERAND is valid for the current
4073 architecture, what we do instead is just validate that we're
4074 assembling for an ARCv2 architecture. */
4075 if ((selected_cpu.flags & ARC_OPCODE_ARCV2)
4076 && (!strcmp (flg_operand->name, "t")
4077 || !strcmp (flg_operand->name, "nt")))
4079 unsigned bitYoperand = 0;
4080 /* FIXME! move selection bbit/brcc in arc-opc.c. */
4081 if (!strcmp (flg_operand->name, "t"))
4082 if (!strcmp (opcode->name, "bbit0")
4083 || !strcmp (opcode->name, "bbit1"))
4084 bitYoperand = arc_NToperand;
4086 bitYoperand = arc_Toperand;
4088 if (!strcmp (opcode->name, "bbit0")
4089 || !strcmp (opcode->name, "bbit1"))
4090 bitYoperand = arc_Toperand;
4092 bitYoperand = arc_NToperand;
4094 gas_assert (reloc_exp != NULL);
4095 if (reloc_exp->X_op == O_constant)
4097 /* Check if we have a constant and solved it
4099 offsetT val = reloc_exp->X_add_number;
4100 image |= insert_operand (image, &arc_operands[bitYoperand],
4105 struct arc_fixup *fixup;
4107 if (insn->nfixups >= MAX_INSN_FIXUPS)
4108 as_fatal (_("too many fixups"));
4110 fixup = &insn->fixups[insn->nfixups++];
4111 fixup->exp = *reloc_exp;
4112 fixup->reloc = -bitYoperand;
4113 fixup->pcrel = pcrel;
4114 fixup->islong = FALSE;
4118 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
4119 << flg_operand->shift;
4122 insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
4124 /* Instruction length. */
4125 insn->len = arc_opcode_len (opcode);
4129 /* Update last insn status. */
4130 arc_last_insns[1] = arc_last_insns[0];
4131 arc_last_insns[0].opcode = opcode;
4132 arc_last_insns[0].has_limm = insn->has_limm;
4133 arc_last_insns[0].has_delay_slot = has_delay_slot;
4135 /* Check if the current instruction is legally used. */
4136 if (arc_last_insns[1].has_delay_slot
4137 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
4138 as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."),
4139 arc_last_insns[1].opcode->name,
4140 arc_last_insns[0].opcode->name);
4141 if (arc_last_insns[1].has_delay_slot
4142 && arc_last_insns[0].has_limm)
4143 as_bad (_("Insn %s has an instruction %s with limm in its delay slot."),
4144 arc_last_insns[1].opcode->name,
4145 arc_last_insns[0].opcode->name);
4149 arc_handle_align (fragS* fragP)
4151 if ((fragP)->fr_type == rs_align_code)
4153 char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
4154 valueT count = ((fragP)->fr_next->fr_address
4155 - (fragP)->fr_address - (fragP)->fr_fix);
4157 (fragP)->fr_var = 2;
4159 if (count & 1)/* Padding in the gap till the next 2-byte
4160 boundary with 0s. */
4165 /* Writing nop_s. */
4166 md_number_to_chars (dest, NOP_OPCODE_S, 2);
4170 /* Here we decide which fixups can be adjusted to make them relative
4171 to the beginning of the section instead of the symbol. Basically
4172 we need to make sure that the dynamic relocations are done
4173 correctly, so in some cases we force the original symbol to be
4177 tc_arc_fix_adjustable (fixS *fixP)
4180 /* Prevent all adjustments to global symbols. */
4181 if (S_IS_EXTERNAL (fixP->fx_addsy))
4183 if (S_IS_WEAK (fixP->fx_addsy))
4186 /* Adjust_reloc_syms doesn't know about the GOT. */
4187 switch (fixP->fx_r_type)
4189 case BFD_RELOC_ARC_GOTPC32:
4190 case BFD_RELOC_ARC_PLT32:
4191 case BFD_RELOC_ARC_S25H_PCREL_PLT:
4192 case BFD_RELOC_ARC_S21H_PCREL_PLT:
4193 case BFD_RELOC_ARC_S25W_PCREL_PLT:
4194 case BFD_RELOC_ARC_S21W_PCREL_PLT:
4204 /* Compute the reloc type of an expression EXP. */
4207 arc_check_reloc (expressionS *exp,
4208 bfd_reloc_code_real_type *r_type_p)
4210 if (*r_type_p == BFD_RELOC_32
4211 && exp->X_op == O_subtract
4212 && exp->X_op_symbol != NULL
4213 && S_GET_SEGMENT (exp->X_op_symbol) == now_seg)
4214 *r_type_p = BFD_RELOC_ARC_32_PCREL;
4218 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4221 arc_cons_fix_new (fragS *frag,
4225 bfd_reloc_code_real_type r_type)
4227 r_type = BFD_RELOC_UNUSED;
4232 r_type = BFD_RELOC_8;
4236 r_type = BFD_RELOC_16;
4240 r_type = BFD_RELOC_24;
4244 r_type = BFD_RELOC_32;
4245 arc_check_reloc (exp, &r_type);
4249 r_type = BFD_RELOC_64;
4253 as_bad (_("unsupported BFD relocation size %u"), size);
4254 r_type = BFD_RELOC_UNUSED;
4257 fix_new_exp (frag, off, size, exp, 0, r_type);
4260 /* The actual routine that checks the ZOL conditions. */
4263 check_zol (symbolS *s)
4265 switch (selected_cpu.mach)
4267 case bfd_mach_arc_arcv2:
4268 if (selected_cpu.flags & ARC_OPCODE_ARCv2EM)
4271 if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
4272 || arc_last_insns[1].has_delay_slot)
4273 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4277 case bfd_mach_arc_arc600:
4279 if (is_kernel_insn_p (arc_last_insns[0].opcode))
4280 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4283 if (arc_last_insns[0].has_limm
4284 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
4285 as_bad (_("A jump instruction with long immediate detected at the \
4286 end of the ZOL label @%s"), S_GET_NAME (s));
4289 case bfd_mach_arc_arc700:
4290 if (arc_last_insns[0].has_delay_slot)
4291 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4300 /* If ZOL end check the last two instruction for illegals. */
4302 arc_frob_label (symbolS * sym)
4304 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
4307 dwarf2_emit_label (sym);
4310 /* Used because generic relaxation assumes a pc-rel value whilst we
4311 also relax instructions that use an absolute value resolved out of
4312 relative values (if that makes any sense). An example: 'add r1,
4313 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4314 but if they're in the same section we can subtract the section
4315 offset relocation which ends up in a resolved value. So if @.L2 is
4316 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4317 .text + 0x40 = 0x10. */
4319 arc_pcrel_adjust (fragS *fragP)
4321 pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
4322 fragP->fr_address, fragP->fr_fix,
4323 fragP->tc_frag_data.pcrel ? "Y" : "N");
4325 if (!fragP->tc_frag_data.pcrel)
4326 return fragP->fr_address + fragP->fr_fix;
4328 /* Take into account the PCL rounding. */
4329 return (fragP->fr_address + fragP->fr_fix) & 0x03;
4332 /* Initialize the DWARF-2 unwind information for this procedure. */
4335 tc_arc_frame_initial_instructions (void)
4337 /* Stack pointer is register 28. */
4338 cfi_add_CFA_def_cfa (28, 0);
4342 tc_arc_regname_to_dw2regnum (char *regname)
4346 sym = hash_find (arc_reg_hash, regname);
4348 return S_GET_VALUE (sym);
4353 /* Adjust the symbol table. Delete found AUX register symbols. */
4356 arc_adjust_symtab (void)
4360 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
4362 /* I've created a symbol during parsing process. Now, remove
4363 the symbol as it is found to be an AUX register. */
4364 if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX)
4365 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
4368 /* Now do generic ELF adjustments. */
4369 elf_adjust_symtab ();
4373 tokenize_extinsn (extInstruction_t *einsn)
4377 unsigned char major_opcode;
4378 unsigned char sub_opcode;
4379 unsigned char syntax_class = 0;
4380 unsigned char syntax_class_modifiers = 0;
4381 unsigned char suffix_class = 0;
4386 /* 1st: get instruction name. */
4387 p = input_line_pointer;
4388 c = get_symbol_name (&p);
4390 insn_name = xstrdup (p);
4391 restore_line_pointer (c);
4393 /* Convert to lower case. */
4394 for (p = insn_name; *p; ++p)
4397 /* 2nd: get major opcode. */
4398 if (*input_line_pointer != ',')
4400 as_bad (_("expected comma after instruction name"));
4401 ignore_rest_of_line ();
4404 input_line_pointer++;
4405 major_opcode = get_absolute_expression ();
4407 /* 3rd: get sub-opcode. */
4410 if (*input_line_pointer != ',')
4412 as_bad (_("expected comma after major opcode"));
4413 ignore_rest_of_line ();
4416 input_line_pointer++;
4417 sub_opcode = get_absolute_expression ();
4419 /* 4th: get suffix class. */
4422 if (*input_line_pointer != ',')
4424 as_bad ("expected comma after sub opcode");
4425 ignore_rest_of_line ();
4428 input_line_pointer++;
4434 for (i = 0; i < ARRAY_SIZE (suffixclass); i++)
4436 if (!strncmp (suffixclass[i].name, input_line_pointer,
4437 suffixclass[i].len))
4439 suffix_class |= suffixclass[i].attr_class;
4440 input_line_pointer += suffixclass[i].len;
4445 if (i == ARRAY_SIZE (suffixclass))
4447 as_bad ("invalid suffix class");
4448 ignore_rest_of_line ();
4454 if (*input_line_pointer == '|')
4455 input_line_pointer++;
4460 /* 5th: get syntax class and syntax class modifiers. */
4461 if (*input_line_pointer != ',')
4463 as_bad ("expected comma after suffix class");
4464 ignore_rest_of_line ();
4467 input_line_pointer++;
4473 for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++)
4475 if (!strncmp (syntaxclassmod[i].name,
4477 syntaxclassmod[i].len))
4479 syntax_class_modifiers |= syntaxclassmod[i].attr_class;
4480 input_line_pointer += syntaxclassmod[i].len;
4485 if (i == ARRAY_SIZE (syntaxclassmod))
4487 for (i = 0; i < ARRAY_SIZE (syntaxclass); i++)
4489 if (!strncmp (syntaxclass[i].name,
4491 syntaxclass[i].len))
4493 syntax_class |= syntaxclass[i].attr_class;
4494 input_line_pointer += syntaxclass[i].len;
4499 if (i == ARRAY_SIZE (syntaxclass))
4501 as_bad ("missing syntax class");
4502 ignore_rest_of_line ();
4509 if (*input_line_pointer == '|')
4510 input_line_pointer++;
4515 demand_empty_rest_of_line ();
4517 einsn->name = insn_name;
4518 einsn->major = major_opcode;
4519 einsn->minor = sub_opcode;
4520 einsn->syntax = syntax_class;
4521 einsn->modsyn = syntax_class_modifiers;
4522 einsn->suffix = suffix_class;
4523 einsn->flags = syntax_class
4524 | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0);
4527 /* Generate an extension section. */
4530 arc_set_ext_seg (void)
4532 if (!arcext_section)
4534 arcext_section = subseg_new (".arcextmap", 0);
4535 bfd_set_section_flags (stdoutput, arcext_section,
4536 SEC_READONLY | SEC_HAS_CONTENTS);
4539 subseg_set (arcext_section, 0);
4543 /* Create an extension instruction description in the arc extension
4544 section of the output file.
4545 The structure for an instruction is like this:
4546 [0]: Length of the record.
4547 [1]: Type of the record.
4551 [4]: Syntax (flags).
4552 [5]+ Name instruction.
4554 The sequence is terminated by an empty entry. */
4557 create_extinst_section (extInstruction_t *einsn)
4560 segT old_sec = now_seg;
4561 int old_subsec = now_subseg;
4563 int name_len = strlen (einsn->name);
4568 *p = 5 + name_len + 1;
4570 *p = EXT_INSTRUCTION;
4577 p = frag_more (name_len + 1);
4578 strcpy (p, einsn->name);
4580 subseg_set (old_sec, old_subsec);
4583 /* Handler .extinstruction pseudo-op. */
4586 arc_extinsn (int ignore ATTRIBUTE_UNUSED)
4588 extInstruction_t einsn;
4589 struct arc_opcode *arc_ext_opcodes;
4590 const char *errmsg = NULL;
4591 unsigned char moplow, mophigh;
4593 memset (&einsn, 0, sizeof (einsn));
4594 tokenize_extinsn (&einsn);
4596 /* Check if the name is already used. */
4597 if (arc_find_opcode (einsn.name))
4598 as_warn (_("Pseudocode already used %s"), einsn.name);
4600 /* Check the opcode ranges. */
4602 mophigh = (selected_cpu.flags & (ARC_OPCODE_ARCv2EM
4603 | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a;
4605 if ((einsn.major > mophigh) || (einsn.major < moplow))
4606 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh);
4608 if ((einsn.minor > 0x3f) && (einsn.major != 0x0a)
4609 && (einsn.major != 5) && (einsn.major != 9))
4610 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4612 switch (einsn.syntax & ARC_SYNTAX_MASK)
4614 case ARC_SYNTAX_3OP:
4615 if (einsn.modsyn & ARC_OP1_IMM_IMPLIED)
4616 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4618 case ARC_SYNTAX_2OP:
4619 case ARC_SYNTAX_1OP:
4620 case ARC_SYNTAX_NOP:
4621 if (einsn.modsyn & ARC_OP1_MUST_BE_IMM)
4622 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4628 arc_ext_opcodes = arcExtMap_genOpcode (&einsn, selected_cpu.flags, &errmsg);
4629 if (arc_ext_opcodes == NULL)
4632 as_fatal ("%s", errmsg);
4634 as_fatal (_("Couldn't generate extension instruction opcodes"));
4637 as_warn ("%s", errmsg);
4639 /* Insert the extension instruction. */
4640 arc_insert_opcode ((const struct arc_opcode *) arc_ext_opcodes);
4642 create_extinst_section (&einsn);
4646 tokenize_extregister (extRegister_t *ereg, int opertype)
4652 int number, imode = 0;
4653 bfd_boolean isCore_p = (opertype == EXT_CORE_REGISTER) ? TRUE : FALSE;
4654 bfd_boolean isReg_p = (opertype == EXT_CORE_REGISTER
4655 || opertype == EXT_AUX_REGISTER) ? TRUE : FALSE;
4657 /* 1st: get register name. */
4659 p = input_line_pointer;
4660 c = get_symbol_name (&p);
4663 restore_line_pointer (c);
4665 /* 2nd: get register number. */
4668 if (*input_line_pointer != ',')
4670 as_bad (_("expected comma after name"));
4671 ignore_rest_of_line ();
4675 input_line_pointer++;
4676 number = get_absolute_expression ();
4679 && (opertype != EXT_AUX_REGISTER))
4681 as_bad (_("%s second argument cannot be a negative number %d"),
4682 isCore_p ? "extCoreRegister's" : "extCondCode's",
4684 ignore_rest_of_line ();
4691 /* 3rd: get register mode. */
4694 if (*input_line_pointer != ',')
4696 as_bad (_("expected comma after register number"));
4697 ignore_rest_of_line ();
4702 input_line_pointer++;
4703 mode = input_line_pointer;
4705 if (!strncmp (mode, "r|w", 3))
4708 input_line_pointer += 3;
4710 else if (!strncmp (mode, "r", 1))
4712 imode = ARC_REGISTER_READONLY;
4713 input_line_pointer += 1;
4715 else if (strncmp (mode, "w", 1))
4717 as_bad (_("invalid mode"));
4718 ignore_rest_of_line ();
4724 imode = ARC_REGISTER_WRITEONLY;
4725 input_line_pointer += 1;
4731 /* 4th: get core register shortcut. */
4733 if (*input_line_pointer != ',')
4735 as_bad (_("expected comma after register mode"));
4736 ignore_rest_of_line ();
4741 input_line_pointer++;
4743 if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
4745 imode |= ARC_REGISTER_NOSHORT_CUT;
4746 input_line_pointer += 15;
4748 else if (strncmp (input_line_pointer, "can_shortcut", 12))
4750 as_bad (_("shortcut designator invalid"));
4751 ignore_rest_of_line ();
4757 input_line_pointer += 12;
4760 demand_empty_rest_of_line ();
4763 ereg->number = number;
4764 ereg->imode = imode;
4768 /* Create an extension register/condition description in the arc
4769 extension section of the output file.
4771 The structure for an instruction is like this:
4772 [0]: Length of the record.
4773 [1]: Type of the record.
4775 For core regs and condition codes:
4779 For auxiliary registers:
4783 The sequence is terminated by an empty entry. */
4786 create_extcore_section (extRegister_t *ereg, int opertype)
4788 segT old_sec = now_seg;
4789 int old_subsec = now_subseg;
4791 int name_len = strlen (ereg->name);
4798 case EXT_CORE_REGISTER:
4800 *p = 3 + name_len + 1;
4806 case EXT_AUX_REGISTER:
4808 *p = 6 + name_len + 1;
4810 *p = EXT_AUX_REGISTER;
4812 *p = (ereg->number >> 24) & 0xff;
4814 *p = (ereg->number >> 16) & 0xff;
4816 *p = (ereg->number >> 8) & 0xff;
4818 *p = (ereg->number) & 0xff;
4824 p = frag_more (name_len + 1);
4825 strcpy (p, ereg->name);
4827 subseg_set (old_sec, old_subsec);
4830 /* Handler .extCoreRegister pseudo-op. */
4833 arc_extcorereg (int opertype)
4836 struct arc_aux_reg *auxr;
4838 struct arc_flag_operand *ccode;
4840 memset (&ereg, 0, sizeof (ereg));
4841 if (!tokenize_extregister (&ereg, opertype))
4846 case EXT_CORE_REGISTER:
4847 /* Core register. */
4848 if (ereg.number > 60)
4849 as_bad (_("core register %s value (%d) too large"), ereg.name,
4851 declare_register (ereg.name, ereg.number);
4853 case EXT_AUX_REGISTER:
4854 /* Auxiliary register. */
4855 auxr = XNEW (struct arc_aux_reg);
4856 auxr->name = ereg.name;
4857 auxr->cpu = selected_cpu.flags;
4858 auxr->subclass = NONE;
4859 auxr->address = ereg.number;
4860 retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr);
4862 as_fatal (_("internal error: can't hash aux register '%s': %s"),
4863 auxr->name, retval);
4866 /* Condition code. */
4867 if (ereg.number > 31)
4868 as_bad (_("condition code %s value (%d) too large"), ereg.name,
4870 ext_condcode.size ++;
4871 ext_condcode.arc_ext_condcode =
4872 XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode,
4873 ext_condcode.size + 1);
4874 if (ext_condcode.arc_ext_condcode == NULL)
4875 as_fatal (_("Virtual memory exhausted"));
4877 ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1;
4878 ccode->name = ereg.name;
4879 ccode->code = ereg.number;
4882 ccode->favail = 0; /* not used. */
4884 memset (ccode, 0, sizeof (struct arc_flag_operand));
4887 as_bad (_("Unknown extension"));
4890 create_extcore_section (&ereg, opertype);
4893 /* Parse a .arc_attribute directive. */
4896 arc_attribute (int ignored ATTRIBUTE_UNUSED)
4898 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
4900 if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
4901 attributes_set_explicitly[tag] = TRUE;
4904 /* Set an attribute if it has not already been set by the user. */
4907 arc_set_attribute_int (int tag, int value)
4910 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
4911 || !attributes_set_explicitly[tag])
4912 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
4916 arc_set_attribute_string (int tag, const char *value)
4919 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
4920 || !attributes_set_explicitly[tag])
4921 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
4924 /* Allocate and concatenate two strings. s1 can be NULL but not
4925 s2. s1 pointer is freed at end of this procedure. */
4928 arc_stralloc (char * s1, const char * s2)
4934 len = strlen (s1) + 1;
4936 /* Only s1 can be null. */
4938 len += strlen (s2) + 1;
4940 p = (char *) xmalloc (len);
4942 as_fatal (_("Virtual memory exhausted"));
4957 /* Set the public ARC object attributes. */
4960 arc_set_public_attributes (void)
4966 /* Tag_ARC_CPU_name. */
4967 arc_set_attribute_string (Tag_ARC_CPU_name, selected_cpu.name);
4969 /* Tag_ARC_CPU_base. */
4970 switch (selected_cpu.eflags & EF_ARC_MACH_MSK)
4972 case E_ARC_MACH_ARC600:
4973 case E_ARC_MACH_ARC601:
4974 base = TAG_CPU_ARC6xx;
4976 case E_ARC_MACH_ARC700:
4977 base = TAG_CPU_ARC7xx;
4979 case EF_ARC_CPU_ARCV2EM:
4980 base = TAG_CPU_ARCEM;
4982 case EF_ARC_CPU_ARCV2HS:
4983 base = TAG_CPU_ARCHS;
4989 if (attributes_set_explicitly[Tag_ARC_CPU_base]
4990 && (base != bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
4992 as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
4993 bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_CPU_base, base);
4995 /* Tag_ARC_ABI_osver. */
4996 if (attributes_set_explicitly[Tag_ARC_ABI_osver])
4998 int val = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5001 selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_OSABI_MSK)
5002 | (val & 0x0f << 8));
5006 arc_set_attribute_int (Tag_ARC_ABI_osver, E_ARC_OSABI_CURRENT >> 8);
5009 /* Tag_ARC_ISA_config. */
5010 arc_check_feature();
5012 for (i = 0; i < ARRAY_SIZE (feature_list); i++)
5013 if (selected_cpu.features & feature_list[i].feature)
5014 s = arc_stralloc (s, feature_list[i].attr);
5017 arc_set_attribute_string (Tag_ARC_ISA_config, s);
5019 /* Tag_ARC_ISA_mpy_option. */
5020 arc_set_attribute_int (Tag_ARC_ISA_mpy_option, mpy_option);
5022 /* Tag_ARC_ABI_pic. */
5023 arc_set_attribute_int (Tag_ARC_ABI_pic, pic_option);
5025 /* Tag_ARC_ABI_sda. */
5026 arc_set_attribute_int (Tag_ARC_ABI_sda, sda_option);
5028 /* Tag_ARC_ABI_tls. */
5029 arc_set_attribute_int (Tag_ARC_ABI_tls, tls_option);
5031 /* Tag_ARC_ATR_version. */
5032 arc_set_attribute_int (Tag_ARC_ATR_version, 1);
5034 /* Tag_ARC_ABI_rf16. */
5035 if (attributes_set_explicitly[Tag_ARC_ABI_rf16]
5036 && bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5040 as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full "
5042 bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_ABI_rf16, 0);
5046 /* Add the default contents for the .ARC.attributes section. */
5051 arc_set_public_attributes ();
5053 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
5054 as_fatal (_("could not set architecture and machine"));
5056 bfd_set_private_flags (stdoutput, selected_cpu.eflags);
5059 void arc_copy_symbol_attributes (symbolS *dest, symbolS *src)
5061 ARC_GET_FLAG (dest) = ARC_GET_FLAG (src);
5064 int arc_convert_symbolic_attribute (const char *name)
5073 #define T(tag) {#tag, tag}
5074 T (Tag_ARC_PCS_config),
5075 T (Tag_ARC_CPU_base),
5076 T (Tag_ARC_CPU_variation),
5077 T (Tag_ARC_CPU_name),
5078 T (Tag_ARC_ABI_rf16),
5079 T (Tag_ARC_ABI_osver),
5080 T (Tag_ARC_ABI_sda),
5081 T (Tag_ARC_ABI_pic),
5082 T (Tag_ARC_ABI_tls),
5083 T (Tag_ARC_ABI_enumsize),
5084 T (Tag_ARC_ABI_exceptions),
5085 T (Tag_ARC_ABI_double_size),
5086 T (Tag_ARC_ISA_config),
5087 T (Tag_ARC_ISA_apex),
5088 T (Tag_ARC_ISA_mpy_option),
5089 T (Tag_ARC_ATR_version)
5097 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
5098 if (streq (name, attribute_table[i].name))
5099 return attribute_table[i].tag;
5105 eval: (c-set-style "gnu")