1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
25 #include "struc-symbol.h"
26 #include "dwarf2dbg.h"
27 #include "dw2gencfi.h"
28 #include "safe-ctype.h"
30 #include "opcode/arc.h"
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 /* Enum used to enumerate the relaxable ins operands. */
59 REGISTER_S, /* Register for short instruction(s). */
60 REGISTER_NO_GP, /* Is a register but not gp register specifically. */
61 REGISTER_DUP, /* Duplication of previous operand of type register. */
95 #define regno(x) ((x) & 0x3F)
96 #define is_ir_num(x) (((x) & ~0x3F) == 0)
97 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
98 #define is_spfp_p(op) (((sc) == SPX))
99 #define is_dpfp_p(op) (((sc) == DPX))
100 #define is_fpuda_p(op) (((sc) == DPA))
101 #define is_br_jmp_insn_p(op) (((op)->class == BRANCH || (op)->class == JUMP))
102 #define is_kernel_insn_p(op) (((op)->class == KERNEL))
104 /* Generic assembler global variables which must be defined by all
107 /* Characters which always start a comment. */
108 const char comment_chars[] = "#;";
110 /* Characters which start a comment at the beginning of a line. */
111 const char line_comment_chars[] = "#";
113 /* Characters which may be used to separate multiple commands on a
115 const char line_separator_chars[] = "`";
117 /* Characters which are used to indicate an exponent in a floating
119 const char EXP_CHARS[] = "eE";
121 /* Chars that mean this number is a floating point constant
122 As in 0f12.456 or 0d1.2345e12. */
123 const char FLT_CHARS[] = "rRsSfFdD";
126 extern int target_big_endian;
127 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
128 static int byte_order = DEFAULT_BYTE_ORDER;
130 /* Arc extension section. */
131 static segT arcext_section;
133 /* By default relaxation is disabled. */
134 static int relaxation_state = 0;
136 extern int arc_get_mach (char *);
138 /* Forward declarations. */
139 static void arc_lcomm (int);
140 static void arc_option (int);
141 static void arc_extra_reloc (int);
142 static void arc_extinsn (int);
143 static void arc_extcorereg (int);
145 const pseudo_typeS md_pseudo_table[] =
147 /* Make sure that .word is 32 bits. */
150 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
151 { "lcomm", arc_lcomm, 0 },
152 { "lcommon", arc_lcomm, 0 },
153 { "cpu", arc_option, 0 },
155 { "extinstruction", arc_extinsn, 0 },
156 { "extcoreregister", arc_extcorereg, EXT_CORE_REGISTER },
157 { "extauxregister", arc_extcorereg, EXT_AUX_REGISTER },
158 { "extcondcode", arc_extcorereg, EXT_COND_CODE },
160 { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
161 { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
166 const char *md_shortopts = "";
170 OPTION_EB = OPTION_MD_BASE,
183 /* The following options are deprecated and provided here only for
184 compatibility reasons. */
210 struct option md_longopts[] =
212 { "EB", no_argument, NULL, OPTION_EB },
213 { "EL", no_argument, NULL, OPTION_EL },
214 { "mcpu", required_argument, NULL, OPTION_MCPU },
215 { "mA6", no_argument, NULL, OPTION_ARC600 },
216 { "mARC600", no_argument, NULL, OPTION_ARC600 },
217 { "mARC601", no_argument, NULL, OPTION_ARC601 },
218 { "mARC700", no_argument, NULL, OPTION_ARC700 },
219 { "mA7", no_argument, NULL, OPTION_ARC700 },
220 { "mEM", no_argument, NULL, OPTION_ARCEM },
221 { "mHS", no_argument, NULL, OPTION_ARCHS },
222 { "mcode-density", no_argument, NULL, OPTION_CD },
223 { "mrelax", no_argument, NULL, OPTION_RELAX },
225 /* The following options are deprecated and provided here only for
226 compatibility reasons. */
227 { "mav2em", no_argument, NULL, OPTION_ARCEM },
228 { "mav2hs", no_argument, NULL, OPTION_ARCHS },
229 { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
230 { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
231 { "mswap", no_argument, NULL, OPTION_SWAP },
232 { "mnorm", no_argument, NULL, OPTION_NORM },
233 { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
234 { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
235 { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
236 { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
237 { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
238 { "mea", no_argument, NULL, OPTION_EA },
239 { "mEA", no_argument, NULL, OPTION_EA },
240 { "mmul64", no_argument, NULL, OPTION_MUL64 },
241 { "msimd", no_argument, NULL, OPTION_SIMD},
242 { "mspfp", no_argument, NULL, OPTION_SPFP},
243 { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
244 { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
245 { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
246 { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
247 { "mdpfp", no_argument, NULL, OPTION_DPFP},
248 { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
249 { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
250 { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
251 { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
252 { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
253 { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
254 { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
255 { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
256 { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
257 { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
258 { "mcrc", no_argument, NULL, OPTION_CRC},
259 { "mdvbf", no_argument, NULL, OPTION_DVBF},
260 { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
261 { "mxy", no_argument, NULL, OPTION_XYMEMORY},
262 { "mlock", no_argument, NULL, OPTION_LOCK},
263 { "mswape", no_argument, NULL, OPTION_SWAPE},
264 { "mrtsc", no_argument, NULL, OPTION_RTSC},
265 { "mfpuda", no_argument, NULL, OPTION_FPUDA},
267 { NULL, no_argument, NULL, 0 }
270 size_t md_longopts_size = sizeof (md_longopts);
272 /* Local data and data types. */
274 /* Used since new relocation types are introduced in this
275 file (DUMMY_RELOC_LITUSE_*). */
276 typedef int extended_bfd_reloc_code_real_type;
282 extended_bfd_reloc_code_real_type reloc;
284 /* index into arc_operands. */
285 unsigned int opindex;
287 /* PC-relative, used by internals fixups. */
290 /* TRUE if this fixup is for LIMM operand. */
298 struct arc_fixup fixups[MAX_INSN_FIXUPS];
300 bfd_boolean short_insn; /* Boolean value: TRUE if current insn is
302 bfd_boolean has_limm; /* Boolean value: TRUE if limm field is
304 bfd_boolean relax; /* Boolean value: TRUE if needs
308 /* Structure to hold any last two instructions. */
309 static struct arc_last_insn
311 /* Saved instruction opcode. */
312 const struct arc_opcode *opcode;
314 /* Boolean value: TRUE if current insn is short. */
315 bfd_boolean has_limm;
317 /* Boolean value: TRUE if current insn has delay slot. */
318 bfd_boolean has_delay_slot;
321 /* Extension instruction suffix classes. */
329 static const attributes_t suffixclass[] =
331 { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG },
332 { "SUFFIX_COND", 11, ARC_SUFFIX_COND },
333 { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE }
336 /* Extension instruction syntax classes. */
337 static const attributes_t syntaxclass[] =
339 { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP },
340 { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP }
343 /* Extension instruction syntax classes modifiers. */
344 static const attributes_t syntaxclassmod[] =
346 { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED },
347 { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM }
350 /* Extension register type. */
358 /* A structure to hold the additional conditional codes. */
361 struct arc_flag_operand *arc_ext_condcode;
363 } ext_condcode = { NULL, 0 };
365 /* Structure to hold an entry in ARC_OPCODE_HASH. */
366 struct arc_opcode_hash_entry
368 /* The number of pointers in the OPCODE list. */
371 /* Points to a list of opcode pointers. */
372 const struct arc_opcode **opcode;
375 /* Structure used for iterating through an arc_opcode_hash_entry. */
376 struct arc_opcode_hash_entry_iterator
378 /* Index into the OPCODE element of the arc_opcode_hash_entry. */
381 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
382 returned by this iterator. */
383 const struct arc_opcode *opcode;
386 /* Forward declaration. */
387 static void assemble_insn
388 (const struct arc_opcode *, const expressionS *, int,
389 const struct arc_flags *, int, struct arc_insn *);
391 /* The cpu for which we are generating code. */
392 static unsigned arc_target;
393 static const char *arc_target_name;
394 static unsigned arc_features;
396 /* The default architecture. */
397 static int arc_mach_type;
399 /* TRUE if the cpu type has been explicitly specified. */
400 static bfd_boolean mach_type_specified_p = FALSE;
402 /* The hash table of instruction opcodes. */
403 static struct hash_control *arc_opcode_hash;
405 /* The hash table of register symbols. */
406 static struct hash_control *arc_reg_hash;
408 /* The hash table of aux register symbols. */
409 static struct hash_control *arc_aux_hash;
411 /* A table of CPU names and opcode sets. */
412 static const struct cpu_type
422 { "arc600", ARC_OPCODE_ARC600, bfd_mach_arc_arc600,
423 E_ARC_MACH_ARC600, 0x00},
424 { "arc700", ARC_OPCODE_ARC700, bfd_mach_arc_arc700,
425 E_ARC_MACH_ARC700, 0x00},
426 { "nps400", ARC_OPCODE_ARC700 | ARC_OPCODE_NPS400, bfd_mach_arc_nps400,
427 E_ARC_MACH_NPS400, 0x00},
428 { "arcem", ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
429 EF_ARC_CPU_ARCV2EM, ARC_CD},
430 { "archs", ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
431 EF_ARC_CPU_ARCV2HS, ARC_CD},
435 /* Used by the arc_reloc_op table. Order is important. */
436 #define O_gotoff O_md1 /* @gotoff relocation. */
437 #define O_gotpc O_md2 /* @gotpc relocation. */
438 #define O_plt O_md3 /* @plt relocation. */
439 #define O_sda O_md4 /* @sda relocation. */
440 #define O_pcl O_md5 /* @pcl relocation. */
441 #define O_tlsgd O_md6 /* @tlsgd relocation. */
442 #define O_tlsie O_md7 /* @tlsie relocation. */
443 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
444 #define O_tpoff O_md9 /* @tpoff relocation. */
445 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
446 #define O_dtpoff O_md11 /* @dtpoff relocation. */
447 #define O_last O_dtpoff
449 /* Used to define a bracket as operand in tokens. */
450 #define O_bracket O_md32
452 /* Dummy relocation, to be sorted out. */
453 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
455 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
457 /* A table to map the spelling of a relocation operand into an appropriate
458 bfd_reloc_code_real_type type. The table is assumed to be ordered such
459 that op-O_literal indexes into it. */
460 #define ARC_RELOC_TABLE(op) \
461 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
463 : (int) (op) - (int) O_gotoff) ])
465 #define DEF(NAME, RELOC, REQ) \
466 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
468 static const struct arc_reloc_op_tag
470 /* String to lookup. */
472 /* Size of the string. */
474 /* Which operator to use. */
476 extended_bfd_reloc_code_real_type reloc;
477 /* Allows complex relocation expression like identifier@reloc +
479 unsigned int complex_expr : 1;
483 DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
484 DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
485 DEF (plt, BFD_RELOC_ARC_PLT32, 0),
486 DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
487 DEF (pcl, BFD_RELOC_ARC_PC32, 1),
488 DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0),
489 DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0),
490 DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0),
491 DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 1),
492 DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0),
493 DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0),
496 static const int arc_num_reloc_op
497 = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
499 /* Structure for relaxable instruction that have to be swapped with a
500 smaller alternative instruction. */
501 struct arc_relaxable_ins
503 /* Mnemonic that should be checked. */
504 const char *mnemonic_r;
506 /* Operands that should be checked.
507 Indexes of operands from operand array. */
508 enum rlx_operand_type operands[6];
510 /* Flags that should be checked. */
511 unsigned flag_classes[5];
513 /* Mnemonic (smaller) alternative to be used later for relaxation. */
514 const char *mnemonic_alt;
516 /* Index of operand that generic relaxation has to check. */
519 /* Base subtype index used. */
520 enum arc_rlx_types subtype;
523 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
524 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
525 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
529 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
530 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
531 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
536 /* ARC relaxation table. */
537 const relax_typeS md_relax_table[] =
544 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL),
545 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
549 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B),
550 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
555 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6),
556 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM),
557 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
559 /* LD_S a, [b, u7] ->
560 LD<zz><.x><.aa><.di> a, [b, s9] ->
561 LD<zz><.x><.aa><.di> a, [b, limm] */
562 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9),
563 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM),
564 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE),
569 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12),
570 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM),
571 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
575 SUB<.f> a, b, limm. */
576 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6),
577 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM),
578 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
580 /* MPY<.f> a, b, u6 ->
581 MPY<.f> a, b, limm. */
582 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM),
583 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
585 /* MOV<.f><.cc> b, u6 ->
586 MOV<.f><.cc> b, limm. */
587 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM),
588 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
590 /* ADD<.f><.cc> b, b, u6 ->
591 ADD<.f><.cc> b, b, limm. */
592 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM),
593 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
596 /* Order of this table's entries matters! */
597 const struct arc_relaxable_ins arc_relaxable_insns[] =
599 { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S },
600 { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S },
601 { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add",
602 2, ARC_RLX_ADD_RRU6},
603 { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2,
605 { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2,
607 { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET },
608 { 0 }, "ld_s", 3, ARC_RLX_LD_U7 },
609 { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET },
610 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 },
611 { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 },
612 { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 },
613 { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 },
614 { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2,
616 { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2,
618 { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2,
622 const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns);
624 /* Flags to set in the elf header. */
625 static flagword arc_eflag = 0x00;
627 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
628 symbolS * GOT_symbol = 0;
630 /* Set to TRUE when we assemble instructions. */
631 static bfd_boolean assembling_insn = FALSE;
633 /* Functions implementation. */
635 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
636 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
637 are no matching entries in ARC_OPCODE_HASH. */
639 static const struct arc_opcode_hash_entry *
640 arc_find_opcode (const char *name)
642 const struct arc_opcode_hash_entry *entry;
644 entry = hash_find (arc_opcode_hash, name);
648 /* Initialise the iterator ITER. */
651 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator *iter)
657 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
658 calls to this function. Return NULL when all ARC_OPCODE entries have
661 static const struct arc_opcode *
662 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry,
663 struct arc_opcode_hash_entry_iterator *iter)
665 if (iter->opcode == NULL && iter->index == 0)
667 gas_assert (entry->count > 0);
668 iter->opcode = entry->opcode[iter->index];
670 else if (iter->opcode != NULL)
672 const char *old_name = iter->opcode->name;
675 if (iter->opcode->name
676 && (strcmp (old_name, iter->opcode->name) != 0))
679 if (iter->index == entry->count)
682 iter->opcode = entry->opcode[iter->index];
689 /* Insert an opcode into opcode hash structure. */
692 arc_insert_opcode (const struct arc_opcode *opcode)
694 const char *name, *retval;
695 struct arc_opcode_hash_entry *entry;
698 entry = hash_find (arc_opcode_hash, name);
701 entry = xmalloc (sizeof (*entry));
703 entry->opcode = NULL;
705 retval = hash_insert (arc_opcode_hash, name, (void *) entry);
707 as_fatal (_("internal error: can't hash opcode '%s': %s"),
711 entry->opcode = xrealloc (entry->opcode,
712 sizeof (const struct arc_opcode *)
713 * (entry->count + 1));
715 if (entry->opcode == NULL)
716 as_fatal (_("Virtual memory exhausted"));
718 entry->opcode[entry->count] = opcode;
723 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
724 is encoded as 'middle-endian' for a little-endian target. FIXME!
725 this function is used for regular 4 byte instructions as well. */
728 md_number_to_chars_midend (char *buf, valueT val, int n)
732 md_number_to_chars (buf, (val & 0xffff0000) >> 16, 2);
733 md_number_to_chars (buf + 2, (val & 0xffff), 2);
737 md_number_to_chars (buf, val, n);
741 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
742 the relevant static global variables. */
745 arc_select_cpu (const char *arg)
750 for (i = 0; cpu_types[i].name; ++i)
752 if (!strcasecmp (cpu_types[i].name, arg))
754 arc_target = cpu_types[i].flags;
755 arc_target_name = cpu_types[i].name;
756 arc_features = cpu_types[i].features;
757 arc_mach_type = cpu_types[i].mach;
758 cpu_flags = cpu_types[i].eflags;
763 if (!cpu_types[i].name)
764 as_fatal (_("unknown architecture: %s\n"), arg);
765 gas_assert (cpu_flags != 0);
766 arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
769 /* Here ends all the ARCompact extension instruction assembling
773 arc_extra_reloc (int r_type)
776 symbolS *sym, *lab = NULL;
778 if (*input_line_pointer == '@')
779 input_line_pointer++;
780 c = get_symbol_name (&sym_name);
781 sym = symbol_find_or_make (sym_name);
782 restore_line_pointer (c);
783 if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
785 ++input_line_pointer;
787 c = get_symbol_name (&lab_name);
788 lab = symbol_find_or_make (lab_name);
789 restore_line_pointer (c);
792 /* These relocations exist as a mechanism for the compiler to tell the
793 linker how to patch the code if the tls model is optimised. However,
794 the relocation itself does not require any space within the assembler
795 fragment, and so we pass a size of 0.
797 The lines that generate these relocations look like this:
799 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
801 The '.tls_gd_ld @.tdata' is processed first and generates the
802 additional relocation, while the 'bl __tls_get_addr@plt' is processed
803 second and generates the additional branch.
805 It is possible that the additional relocation generated by the
806 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
807 while the 'bl __tls_get_addr@plt' will be generated as the first thing
808 in the next fragment. This will be fine; both relocations will still
809 appear to be at the same address in the generated object file.
810 However, this only works as the additional relocation is generated
811 with size of 0 bytes. */
813 = fix_new (frag_now, /* Which frag? */
814 frag_now_fix (), /* Where in that frag? */
815 0, /* size: 1, 2, or 4 usually. */
816 sym, /* X_add_symbol. */
817 0, /* X_add_number. */
818 FALSE, /* TRUE if PC-relative relocation. */
819 r_type /* Relocation type. */);
820 fixP->fx_subsy = lab;
824 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
825 symbolS *symbolP, addressT size)
830 if (*input_line_pointer == ',')
832 align = parse_align (1);
834 if (align == (addressT) -1)
849 bss_alloc (symbolP, size, align);
850 S_CLEAR_EXTERNAL (symbolP);
856 arc_lcomm (int ignore)
858 symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
861 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
864 /* Select the cpu we're assembling for. */
867 arc_option (int ignore ATTRIBUTE_UNUSED)
873 c = get_symbol_name (&cpu);
874 mach = arc_get_mach (cpu);
879 if (!mach_type_specified_p)
881 if ((!strcmp ("ARC600", cpu))
882 || (!strcmp ("ARC601", cpu))
883 || (!strcmp ("A6", cpu)))
885 md_parse_option (OPTION_MCPU, "arc600");
887 else if ((!strcmp ("ARC700", cpu))
888 || (!strcmp ("A7", cpu)))
890 md_parse_option (OPTION_MCPU, "arc700");
892 else if (!strcmp ("EM", cpu))
894 md_parse_option (OPTION_MCPU, "arcem");
896 else if (!strcmp ("HS", cpu))
898 md_parse_option (OPTION_MCPU, "archs");
901 as_fatal (_("could not find the architecture"));
903 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
904 as_fatal (_("could not set architecture and machine"));
906 /* Set elf header flags. */
907 bfd_set_private_flags (stdoutput, arc_eflag);
910 if (arc_mach_type != mach)
911 as_warn (_("Command-line value overrides \".cpu\" directive"));
913 restore_line_pointer (c);
914 demand_empty_rest_of_line ();
918 restore_line_pointer (c);
919 as_bad (_("invalid identifier for \".cpu\""));
920 ignore_rest_of_line ();
923 /* Smartly print an expression. */
926 debug_exp (expressionS *t)
928 const char *name ATTRIBUTE_UNUSED;
929 const char *namemd ATTRIBUTE_UNUSED;
931 pr_debug ("debug_exp: ");
935 default: name = "unknown"; break;
936 case O_illegal: name = "O_illegal"; break;
937 case O_absent: name = "O_absent"; break;
938 case O_constant: name = "O_constant"; break;
939 case O_symbol: name = "O_symbol"; break;
940 case O_symbol_rva: name = "O_symbol_rva"; break;
941 case O_register: name = "O_register"; break;
942 case O_big: name = "O_big"; break;
943 case O_uminus: name = "O_uminus"; break;
944 case O_bit_not: name = "O_bit_not"; break;
945 case O_logical_not: name = "O_logical_not"; break;
946 case O_multiply: name = "O_multiply"; break;
947 case O_divide: name = "O_divide"; break;
948 case O_modulus: name = "O_modulus"; break;
949 case O_left_shift: name = "O_left_shift"; break;
950 case O_right_shift: name = "O_right_shift"; break;
951 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
952 case O_bit_or_not: name = "O_bit_or_not"; break;
953 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
954 case O_bit_and: name = "O_bit_and"; break;
955 case O_add: name = "O_add"; break;
956 case O_subtract: name = "O_subtract"; break;
957 case O_eq: name = "O_eq"; break;
958 case O_ne: name = "O_ne"; break;
959 case O_lt: name = "O_lt"; break;
960 case O_le: name = "O_le"; break;
961 case O_ge: name = "O_ge"; break;
962 case O_gt: name = "O_gt"; break;
963 case O_logical_and: name = "O_logical_and"; break;
964 case O_logical_or: name = "O_logical_or"; break;
965 case O_index: name = "O_index"; break;
966 case O_bracket: name = "O_bracket"; break;
971 default: namemd = "unknown"; break;
972 case O_gotoff: namemd = "O_gotoff"; break;
973 case O_gotpc: namemd = "O_gotpc"; break;
974 case O_plt: namemd = "O_plt"; break;
975 case O_sda: namemd = "O_sda"; break;
976 case O_pcl: namemd = "O_pcl"; break;
977 case O_tlsgd: namemd = "O_tlsgd"; break;
978 case O_tlsie: namemd = "O_tlsie"; break;
979 case O_tpoff9: namemd = "O_tpoff9"; break;
980 case O_tpoff: namemd = "O_tpoff"; break;
981 case O_dtpoff9: namemd = "O_dtpoff9"; break;
982 case O_dtpoff: namemd = "O_dtpoff"; break;
985 pr_debug ("%s (%s, %s, %d, %s)", name,
986 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
987 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
988 (int) t->X_add_number,
989 (t->X_md) ? namemd : "--");
994 /* Parse the arguments to an opcode. */
997 tokenize_arguments (char *str,
1001 char *old_input_line_pointer;
1002 bfd_boolean saw_comma = FALSE;
1003 bfd_boolean saw_arg = FALSE;
1008 const struct arc_reloc_op_tag *r;
1010 char *reloc_name, c;
1012 memset (tok, 0, sizeof (*tok) * ntok);
1014 /* Save and restore input_line_pointer around this function. */
1015 old_input_line_pointer = input_line_pointer;
1016 input_line_pointer = str;
1018 while (*input_line_pointer)
1021 switch (*input_line_pointer)
1027 input_line_pointer++;
1028 if (saw_comma || !saw_arg)
1035 ++input_line_pointer;
1039 tok->X_op = O_bracket;
1046 input_line_pointer++;
1050 tok->X_op = O_bracket;
1056 /* We have labels, function names and relocations, all
1057 starting with @ symbol. Sort them out. */
1058 if (saw_arg && !saw_comma)
1062 tok->X_op = O_symbol;
1063 tok->X_md = O_absent;
1065 if (*input_line_pointer != '@')
1066 goto normalsymbol; /* This is not a relocation. */
1070 /* A relocation opernad has the following form
1071 @identifier@relocation_type. The identifier is already
1073 if (tok->X_op != O_symbol)
1075 as_bad (_("No valid label relocation operand"));
1079 /* Parse @relocation_type. */
1080 input_line_pointer++;
1081 c = get_symbol_name (&reloc_name);
1082 len = input_line_pointer - reloc_name;
1085 as_bad (_("No relocation operand"));
1089 /* Go through known relocation and try to find a match. */
1090 r = &arc_reloc_op[0];
1091 for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
1092 if (len == r->length
1093 && memcmp (reloc_name, r->name, len) == 0)
1097 as_bad (_("Unknown relocation operand: @%s"), reloc_name);
1101 *input_line_pointer = c;
1102 SKIP_WHITESPACE_AFTER_NAME ();
1103 /* Extra check for TLS: base. */
1104 if (*input_line_pointer == '@')
1107 if (tok->X_op_symbol != NULL
1108 || tok->X_op != O_symbol)
1110 as_bad (_("Unable to parse TLS base: %s"),
1111 input_line_pointer);
1114 input_line_pointer++;
1116 c = get_symbol_name (&sym_name);
1117 base = symbol_find_or_make (sym_name);
1118 tok->X_op = O_subtract;
1119 tok->X_op_symbol = base;
1120 restore_line_pointer (c);
1121 tmpE.X_add_number = 0;
1123 else if ((*input_line_pointer != '+')
1124 && (*input_line_pointer != '-'))
1126 tmpE.X_add_number = 0;
1130 /* Parse the constant of a complex relocation expression
1131 like @identifier@reloc +/- const. */
1132 if (! r->complex_expr)
1134 as_bad (_("@%s is not a complex relocation."), r->name);
1138 if (tmpE.X_op != O_constant)
1140 as_bad (_("Bad expression: @%s + %s."),
1141 r->name, input_line_pointer);
1147 tok->X_add_number = tmpE.X_add_number;
1158 /* Can be a register. */
1159 ++input_line_pointer;
1163 if (saw_arg && !saw_comma)
1166 tok->X_op = O_absent;
1167 tok->X_md = O_absent;
1170 /* Legacy: There are cases when we have
1171 identifier@relocation_type, if it is the case parse the
1172 relocation type as well. */
1173 if (*input_line_pointer == '@')
1179 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1191 if (saw_comma || brk_lvl)
1193 input_line_pointer = old_input_line_pointer;
1199 as_bad (_("Brackets in operand field incorrect"));
1201 as_bad (_("extra comma"));
1203 as_bad (_("missing argument"));
1205 as_bad (_("missing comma or colon"));
1206 input_line_pointer = old_input_line_pointer;
1210 /* Parse the flags to a structure. */
1213 tokenize_flags (const char *str,
1214 struct arc_flags flags[],
1217 char *old_input_line_pointer;
1218 bfd_boolean saw_flg = FALSE;
1219 bfd_boolean saw_dot = FALSE;
1223 memset (flags, 0, sizeof (*flags) * nflg);
1225 /* Save and restore input_line_pointer around this function. */
1226 old_input_line_pointer = input_line_pointer;
1227 input_line_pointer = (char *) str;
1229 while (*input_line_pointer)
1231 switch (*input_line_pointer)
1238 input_line_pointer++;
1246 if (saw_flg && !saw_dot)
1249 if (num_flags >= nflg)
1252 flgnamelen = strspn (input_line_pointer,
1253 "abcdefghijklmnopqrstuvwxyz0123456789");
1254 if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1257 memcpy (flags->name, input_line_pointer, flgnamelen);
1259 input_line_pointer += flgnamelen;
1269 input_line_pointer = old_input_line_pointer;
1274 as_bad (_("extra dot"));
1276 as_bad (_("unrecognized flag"));
1278 as_bad (_("failed to parse flags"));
1279 input_line_pointer = old_input_line_pointer;
1283 /* Apply the fixups in order. */
1286 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1290 for (i = 0; i < insn->nfixups; i++)
1292 struct arc_fixup *fixup = &insn->fixups[i];
1293 int size, pcrel, offset = 0;
1295 /* FIXME! the reloc size is wrong in the BFD file.
1296 When it is fixed please delete me. */
1297 size = (insn->short_insn && !fixup->islong) ? 2 : 4;
1300 offset = (insn->short_insn) ? 2 : 4;
1302 /* Some fixups are only used internally, thus no howto. */
1303 if ((int) fixup->reloc == 0)
1304 as_fatal (_("Unhandled reloc type"));
1306 if ((int) fixup->reloc < 0)
1308 /* FIXME! the reloc size is wrong in the BFD file.
1309 When it is fixed please enable me.
1310 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1311 pcrel = fixup->pcrel;
1315 reloc_howto_type *reloc_howto =
1316 bfd_reloc_type_lookup (stdoutput,
1317 (bfd_reloc_code_real_type) fixup->reloc);
1318 gas_assert (reloc_howto);
1320 /* FIXME! the reloc size is wrong in the BFD file.
1321 When it is fixed please enable me.
1322 size = bfd_get_reloc_size (reloc_howto); */
1323 pcrel = reloc_howto->pc_relative;
1326 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1328 fragP->fr_file, fragP->fr_line,
1329 (fixup->reloc < 0) ? "Internal" :
1330 bfd_get_reloc_code_name (fixup->reloc),
1333 fix_new_exp (fragP, fix + offset,
1334 size, &fixup->exp, pcrel, fixup->reloc);
1336 /* Check for ZOLs, and update symbol info if any. */
1337 if (LP_INSN (insn->insn))
1339 gas_assert (fixup->exp.X_add_symbol);
1340 ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
1345 /* Actually output an instruction with its fixup. */
1348 emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax)
1352 pr_debug ("Emit insn : 0x%x\n", insn->insn);
1353 pr_debug ("\tShort : 0x%d\n", insn->short_insn);
1354 pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
1356 /* Write out the instruction. */
1357 if (insn->short_insn)
1363 md_number_to_chars (f, insn->insn, 2);
1364 md_number_to_chars_midend (f + 2, insn->limm, 4);
1365 dwarf2_emit_insn (6);
1371 md_number_to_chars (f, insn->insn, 2);
1372 dwarf2_emit_insn (2);
1381 md_number_to_chars_midend (f, insn->insn, 4);
1382 md_number_to_chars_midend (f + 4, insn->limm, 4);
1383 dwarf2_emit_insn (8);
1389 md_number_to_chars_midend (f, insn->insn, 4);
1390 dwarf2_emit_insn (4);
1395 apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
1399 emit_insn1 (struct arc_insn *insn)
1401 /* How frag_var's args are currently configured:
1402 - rs_machine_dependent, to dictate it's a relaxation frag.
1403 - FRAG_MAX_GROWTH, maximum size of instruction
1404 - 0, variable size that might grow...unused by generic relaxation.
1405 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1406 - s, opand expression.
1407 - 0, offset but it's unused.
1408 - 0, opcode but it's unused. */
1409 symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
1410 frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
1412 if (frag_room () < FRAG_MAX_GROWTH)
1414 /* Handle differently when frag literal memory is exhausted.
1415 This is used because when there's not enough memory left in
1416 the current frag, a new frag is created and the information
1417 we put into frag_now->tc_frag_data is disregarded. */
1419 struct arc_relax_type relax_info_copy;
1420 relax_substateT subtype = frag_now->fr_subtype;
1422 memcpy (&relax_info_copy, &frag_now->tc_frag_data,
1423 sizeof (struct arc_relax_type));
1425 frag_wane (frag_now);
1426 frag_grow (FRAG_MAX_GROWTH);
1428 memcpy (&frag_now->tc_frag_data, &relax_info_copy,
1429 sizeof (struct arc_relax_type));
1431 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1435 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1436 frag_now->fr_subtype, s, 0, 0);
1440 emit_insn (struct arc_insn *insn)
1445 emit_insn0 (insn, NULL, FALSE);
1448 /* Check whether a symbol involves a register. */
1451 contains_register (symbolS *sym)
1455 expressionS *ex = symbol_get_value_expression (sym);
1457 return ((O_register == ex->X_op)
1458 && !contains_register (ex->X_add_symbol)
1459 && !contains_register (ex->X_op_symbol));
1465 /* Returns the register number within a symbol. */
1468 get_register (symbolS *sym)
1470 if (!contains_register (sym))
1473 expressionS *ex = symbol_get_value_expression (sym);
1474 return regno (ex->X_add_number);
1477 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1478 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1481 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
1488 case BFD_RELOC_ARC_SDA_LDST:
1489 case BFD_RELOC_ARC_SDA_LDST1:
1490 case BFD_RELOC_ARC_SDA_LDST2:
1491 case BFD_RELOC_ARC_SDA16_LD:
1492 case BFD_RELOC_ARC_SDA16_LD1:
1493 case BFD_RELOC_ARC_SDA16_LD2:
1494 case BFD_RELOC_ARC_SDA16_ST2:
1495 case BFD_RELOC_ARC_SDA32_ME:
1502 /* Allocates a tok entry. */
1505 allocate_tok (expressionS *tok, int ntok, int cidx)
1507 if (ntok > MAX_INSN_ARGS - 2)
1508 return 0; /* No space left. */
1511 return 0; /* Incorect args. */
1513 memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
1516 return 1; /* Success. */
1517 return allocate_tok (tok, ntok - 1, cidx);
1520 /* Check if an particular ARC feature is enabled. */
1523 check_cpu_feature (insn_subclass_t sc)
1525 if (!(arc_features & ARC_CD)
1526 && is_code_density_p (sc))
1529 if (!(arc_features & ARC_SPFP)
1533 if (!(arc_features & ARC_DPFP)
1537 if (!(arc_features & ARC_FPUDA)
1544 /* Search forward through all variants of an opcode looking for a
1547 static const struct arc_opcode *
1548 find_opcode_match (const struct arc_opcode_hash_entry *entry,
1551 struct arc_flags *first_pflag,
1555 const struct arc_opcode *opcode;
1556 struct arc_opcode_hash_entry_iterator iter;
1558 int got_cpu_match = 0;
1559 expressionS bktok[MAX_INSN_ARGS];
1563 arc_opcode_hash_entry_iterator_init (&iter);
1564 memset (&emptyE, 0, sizeof (emptyE));
1565 memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
1568 for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter);
1570 opcode = arc_opcode_hash_entry_iterator_next (entry, &iter))
1572 const unsigned char *opidx;
1573 const unsigned char *flgidx;
1574 int tokidx = 0, lnflg, i;
1575 const expressionS *t = &emptyE;
1577 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1578 frag_now->fr_file, frag_now->fr_line, opcode->opcode);
1580 /* Don't match opcodes that don't exist on this
1582 if (!(opcode->cpu & arc_target))
1585 if (!check_cpu_feature (opcode->subclass))
1591 /* Check the operands. */
1592 for (opidx = opcode->operands; *opidx; ++opidx)
1594 const struct arc_operand *operand = &arc_operands[*opidx];
1596 /* Only take input from real operands. */
1597 if ((operand->flags & ARC_OPERAND_FAKE)
1598 && !(operand->flags & ARC_OPERAND_BRAKET))
1601 /* When we expect input, make sure we have it. */
1605 /* Match operand type with expression type. */
1606 switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
1608 case ARC_OPERAND_IR:
1609 /* Check to be a register. */
1610 if ((tok[tokidx].X_op != O_register
1611 || !is_ir_num (tok[tokidx].X_add_number))
1612 && !(operand->flags & ARC_OPERAND_IGNORE))
1615 /* If expect duplicate, make sure it is duplicate. */
1616 if (operand->flags & ARC_OPERAND_DUPLICATE)
1618 /* Check for duplicate. */
1619 if (t->X_op != O_register
1620 || !is_ir_num (t->X_add_number)
1621 || (regno (t->X_add_number) !=
1622 regno (tok[tokidx].X_add_number)))
1626 /* Special handling? */
1627 if (operand->insert)
1629 const char *errmsg = NULL;
1630 (*operand->insert)(0,
1631 regno (tok[tokidx].X_add_number),
1635 if (operand->flags & ARC_OPERAND_IGNORE)
1637 /* Missing argument, create one. */
1638 if (!allocate_tok (tok, ntok - 1, tokidx))
1641 tok[tokidx].X_op = O_absent;
1652 case ARC_OPERAND_BRAKET:
1653 /* Check if bracket is also in opcode table as
1655 if (tok[tokidx].X_op != O_bracket)
1659 case ARC_OPERAND_LIMM:
1660 case ARC_OPERAND_SIGNED:
1661 case ARC_OPERAND_UNSIGNED:
1662 switch (tok[tokidx].X_op)
1670 /* Got an (too) early bracket, check if it is an
1671 ignored operand. N.B. This procedure works only
1672 when bracket is the last operand! */
1673 if (!(operand->flags & ARC_OPERAND_IGNORE))
1675 /* Insert the missing operand. */
1676 if (!allocate_tok (tok, ntok - 1, tokidx))
1679 tok[tokidx].X_op = O_absent;
1686 const struct arc_aux_reg *auxr;
1688 if (opcode->class != AUXREG)
1690 p = S_GET_NAME (tok[tokidx].X_add_symbol);
1692 auxr = hash_find (arc_aux_hash, p);
1695 /* We modify the token array here, safe in the
1696 knowledge, that if this was the wrong
1697 choice then the original contents will be
1698 restored from BKTOK. */
1699 tok[tokidx].X_op = O_constant;
1700 tok[tokidx].X_add_number = auxr->address;
1701 ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX);
1704 if (tok[tokidx].X_op != O_constant)
1709 /* Check the range. */
1710 if (operand->bits != 32
1711 && !(operand->flags & ARC_OPERAND_NCHK))
1713 offsetT min, max, val;
1714 val = tok[tokidx].X_add_number;
1716 if (operand->flags & ARC_OPERAND_SIGNED)
1718 max = (1 << (operand->bits - 1)) - 1;
1719 min = -(1 << (operand->bits - 1));
1723 max = (1 << operand->bits) - 1;
1727 if (val < min || val > max)
1730 /* Check alignmets. */
1731 if ((operand->flags & ARC_OPERAND_ALIGNED32)
1735 if ((operand->flags & ARC_OPERAND_ALIGNED16)
1739 else if (operand->flags & ARC_OPERAND_NCHK)
1741 if (operand->insert)
1743 const char *errmsg = NULL;
1744 (*operand->insert)(0,
1745 tok[tokidx].X_add_number,
1756 /* Check if it is register range. */
1757 if ((tok[tokidx].X_add_number == 0)
1758 && contains_register (tok[tokidx].X_add_symbol)
1759 && contains_register (tok[tokidx].X_op_symbol))
1763 regs = get_register (tok[tokidx].X_add_symbol);
1765 regs |= get_register (tok[tokidx].X_op_symbol);
1766 if (operand->insert)
1768 const char *errmsg = NULL;
1769 (*operand->insert)(0,
1781 if (operand->default_reloc == 0)
1782 goto match_failed; /* The operand needs relocation. */
1784 /* Relocs requiring long immediate. FIXME! make it
1785 generic and move it to a function. */
1786 switch (tok[tokidx].X_md)
1795 if (!(operand->flags & ARC_OPERAND_LIMM))
1798 if (!generic_reloc_p (operand->default_reloc))
1805 /* If expect duplicate, make sure it is duplicate. */
1806 if (operand->flags & ARC_OPERAND_DUPLICATE)
1808 if (t->X_op == O_illegal
1809 || t->X_op == O_absent
1810 || t->X_op == O_register
1811 || (t->X_add_number != tok[tokidx].X_add_number))
1818 /* Everything else should have been fake. */
1826 /* Setup ready for flag parsing. */
1828 for (i = 0; i < nflgs; i++)
1829 first_pflag[i].flgp = NULL;
1831 /* Check the flags. Iterate over the valid flag classes. */
1832 for (flgidx = opcode->flags; *flgidx; ++flgidx)
1834 /* Get a valid flag class. */
1835 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
1836 const unsigned *flgopridx;
1838 struct arc_flags *pflag = NULL;
1840 /* Check for extension conditional codes. */
1841 if (ext_condcode.arc_ext_condcode
1842 && cl_flags->class & F_CLASS_EXTEND)
1844 struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode;
1847 pflag = first_pflag;
1848 for (i = 0; i < nflgs; i++, pflag++)
1850 if (!strcmp (pf->name, pflag->name))
1852 if (pflag->flgp != NULL)
1865 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
1867 const struct arc_flag_operand *flg_operand;
1869 pflag = first_pflag;
1870 flg_operand = &arc_flag_operands[*flgopridx];
1871 for (i = 0; i < nflgs; i++, pflag++)
1873 /* Match against the parsed flags. */
1874 if (!strcmp (flg_operand->name, pflag->name))
1876 if (pflag->flgp != NULL)
1879 pflag->flgp = (struct arc_flag_operand *) flg_operand;
1881 break; /* goto next flag class and parsed flag. */
1886 if ((cl_flags->class & F_CLASS_REQUIRED) && cl_matches == 0)
1888 if ((cl_flags->class & F_CLASS_OPTIONAL) && cl_matches > 1)
1891 /* Did I check all the parsed flags? */
1896 /* Possible match -- did we use all of our input? */
1906 /* Restore the original parameters. */
1907 memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
1912 *pcpumatch = got_cpu_match;
1917 /* Swap operand tokens. */
1920 swap_operand (expressionS *operand_array,
1922 unsigned destination)
1924 expressionS cpy_operand;
1925 expressionS *src_operand;
1926 expressionS *dst_operand;
1929 if (source == destination)
1932 src_operand = &operand_array[source];
1933 dst_operand = &operand_array[destination];
1934 size = sizeof (expressionS);
1936 /* Make copy of operand to swap with and swap. */
1937 memcpy (&cpy_operand, dst_operand, size);
1938 memcpy (dst_operand, src_operand, size);
1939 memcpy (src_operand, &cpy_operand, size);
1942 /* Check if *op matches *tok type.
1943 Returns FALSE if they don't match, TRUE if they match. */
1946 pseudo_operand_match (const expressionS *tok,
1947 const struct arc_operand_operation *op)
1949 offsetT min, max, val;
1951 const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
1957 if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
1959 else if (!(operand_real->flags & ARC_OPERAND_IR))
1961 val = tok->X_add_number + op->count;
1962 if (operand_real->flags & ARC_OPERAND_SIGNED)
1964 max = (1 << (operand_real->bits - 1)) - 1;
1965 min = -(1 << (operand_real->bits - 1));
1969 max = (1 << operand_real->bits) - 1;
1972 if (min <= val && val <= max)
1978 /* Handle all symbols as long immediates or signed 9. */
1979 if (operand_real->flags & ARC_OPERAND_LIMM ||
1980 ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
1985 if (operand_real->flags & ARC_OPERAND_IR)
1990 if (operand_real->flags & ARC_OPERAND_BRAKET)
2001 /* Find pseudo instruction in array. */
2003 static const struct arc_pseudo_insn *
2004 find_pseudo_insn (const char *opname,
2006 const expressionS *tok)
2008 const struct arc_pseudo_insn *pseudo_insn = NULL;
2009 const struct arc_operand_operation *op;
2013 for (i = 0; i < arc_num_pseudo_insn; ++i)
2015 pseudo_insn = &arc_pseudo_insns[i];
2016 if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
2018 op = pseudo_insn->operand;
2019 for (j = 0; j < ntok; ++j)
2020 if (!pseudo_operand_match (&tok[j], &op[j]))
2023 /* Found the right instruction. */
2031 /* Assumes the expressionS *tok is of sufficient size. */
2033 static const struct arc_opcode_hash_entry *
2034 find_special_case_pseudo (const char *opname,
2038 struct arc_flags *pflags)
2040 const struct arc_pseudo_insn *pseudo_insn = NULL;
2041 const struct arc_operand_operation *operand_pseudo;
2042 const struct arc_operand *operand_real;
2044 char construct_operand[MAX_CONSTR_STR];
2046 /* Find whether opname is in pseudo instruction array. */
2047 pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
2049 if (pseudo_insn == NULL)
2052 /* Handle flag, Limited to one flag at the moment. */
2053 if (pseudo_insn->flag_r != NULL)
2054 *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
2055 MAX_INSN_FLGS - *nflgs);
2057 /* Handle operand operations. */
2058 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2060 operand_pseudo = &pseudo_insn->operand[i];
2061 operand_real = &arc_operands[operand_pseudo->operand_idx];
2063 if (operand_real->flags & ARC_OPERAND_BRAKET &&
2064 !operand_pseudo->needs_insert)
2067 /* Has to be inserted (i.e. this token does not exist yet). */
2068 if (operand_pseudo->needs_insert)
2070 if (operand_real->flags & ARC_OPERAND_BRAKET)
2072 tok[i].X_op = O_bracket;
2077 /* Check if operand is a register or constant and handle it
2079 if (operand_real->flags & ARC_OPERAND_IR)
2080 snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
2081 operand_pseudo->count);
2083 snprintf (construct_operand, MAX_CONSTR_STR, "%d",
2084 operand_pseudo->count);
2086 tokenize_arguments (construct_operand, &tok[i], 1);
2090 else if (operand_pseudo->count)
2092 /* Operand number has to be adjusted accordingly (by operand
2094 switch (tok[i].X_op)
2097 tok[i].X_add_number += operand_pseudo->count;
2110 /* Swap operands if necessary. Only supports one swap at the
2112 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2114 operand_pseudo = &pseudo_insn->operand[i];
2116 if (operand_pseudo->swap_operand_idx == i)
2119 swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2121 /* Prevent a swap back later by breaking out. */
2125 return arc_find_opcode (pseudo_insn->mnemonic_r);
2128 static const struct arc_opcode_hash_entry *
2129 find_special_case_flag (const char *opname,
2131 struct arc_flags *pflags)
2135 unsigned flag_idx, flag_arr_idx;
2136 size_t flaglen, oplen;
2137 const struct arc_flag_special *arc_flag_special_opcode;
2138 const struct arc_opcode_hash_entry *entry;
2140 /* Search for special case instruction. */
2141 for (i = 0; i < arc_num_flag_special; i++)
2143 arc_flag_special_opcode = &arc_flag_special_cases[i];
2144 oplen = strlen (arc_flag_special_opcode->name);
2146 if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2149 /* Found a potential special case instruction, now test for
2151 for (flag_arr_idx = 0;; ++flag_arr_idx)
2153 flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2155 break; /* End of array, nothing found. */
2157 flagnm = arc_flag_operands[flag_idx].name;
2158 flaglen = strlen (flagnm);
2159 if (strcmp (opname + oplen, flagnm) == 0)
2161 entry = arc_find_opcode (arc_flag_special_opcode->name);
2163 if (*nflgs + 1 > MAX_INSN_FLGS)
2165 memcpy (pflags[*nflgs].name, flagnm, flaglen);
2166 pflags[*nflgs].name[flaglen] = '\0';
2175 /* Used to find special case opcode. */
2177 static const struct arc_opcode_hash_entry *
2178 find_special_case (const char *opname,
2180 struct arc_flags *pflags,
2184 const struct arc_opcode_hash_entry *entry;
2186 entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
2189 entry = find_special_case_flag (opname, nflgs, pflags);
2194 /* Given an opcode name, pre-tockenized set of argumenst and the
2195 opcode flags, take it all the way through emission. */
2198 assemble_tokens (const char *opname,
2201 struct arc_flags *pflags,
2204 bfd_boolean found_something = FALSE;
2205 const struct arc_opcode_hash_entry *entry;
2208 /* Search opcodes. */
2209 entry = arc_find_opcode (opname);
2211 /* Couldn't find opcode conventional way, try special cases. */
2213 entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
2217 const struct arc_opcode *opcode;
2219 pr_debug ("%s:%d: assemble_tokens: %s\n",
2220 frag_now->fr_file, frag_now->fr_line, opname);
2221 found_something = TRUE;
2222 opcode = find_opcode_match (entry, tok, &ntok, pflags,
2226 struct arc_insn insn;
2228 assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
2234 if (found_something)
2237 as_bad (_("inappropriate arguments for opcode '%s'"), opname);
2239 as_bad (_("opcode '%s' not supported for target %s"), opname,
2243 as_bad (_("unknown opcode '%s'"), opname);
2246 /* The public interface to the instruction assembler. */
2249 md_assemble (char *str)
2252 expressionS tok[MAX_INSN_ARGS];
2255 struct arc_flags flags[MAX_INSN_FLGS];
2257 /* Split off the opcode. */
2258 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
2259 opname = xmalloc (opnamelen + 1);
2260 memcpy (opname, str, opnamelen);
2261 opname[opnamelen] = '\0';
2263 /* Signalize we are assmbling the instructions. */
2264 assembling_insn = TRUE;
2266 /* Tokenize the flags. */
2267 if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2269 as_bad (_("syntax error"));
2273 /* Scan up to the end of the mnemonic which must end in space or end
2276 for (; *str != '\0'; str++)
2280 /* Tokenize the rest of the line. */
2281 if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2283 as_bad (_("syntax error"));
2287 /* Finish it off. */
2288 assemble_tokens (opname, tok, ntok, flags, nflg);
2289 assembling_insn = FALSE;
2292 /* Callback to insert a register into the hash table. */
2295 declare_register (const char *name, int number)
2298 symbolS *regS = symbol_create (name, reg_section,
2299 number, &zero_address_frag);
2301 err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
2303 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2307 /* Construct symbols for each of the general registers. */
2310 declare_register_set (void)
2313 for (i = 0; i < 64; ++i)
2317 sprintf (name, "r%d", i);
2318 declare_register (name, i);
2319 if ((i & 0x01) == 0)
2321 sprintf (name, "r%dr%d", i, i+1);
2322 declare_register (name, i);
2327 /* Port-specific assembler initialization. This function is called
2328 once, at assembler startup time. */
2333 const struct arc_opcode *opcode = arc_opcodes;
2335 if (!mach_type_specified_p)
2336 arc_select_cpu ("arc700");
2338 /* The endianness can be chosen "at the factory". */
2339 target_big_endian = byte_order == BIG_ENDIAN;
2341 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
2342 as_warn (_("could not set architecture and machine"));
2344 /* Set elf header flags. */
2345 bfd_set_private_flags (stdoutput, arc_eflag);
2347 /* Set up a hash table for the instructions. */
2348 arc_opcode_hash = hash_new ();
2349 if (arc_opcode_hash == NULL)
2350 as_fatal (_("Virtual memory exhausted"));
2352 /* Initialize the hash table with the insns. */
2355 const char *name = opcode->name;
2357 arc_insert_opcode (opcode);
2359 while (++opcode && opcode->name
2360 && (opcode->name == name
2361 || !strcmp (opcode->name, name)))
2363 }while (opcode->name);
2365 /* Register declaration. */
2366 arc_reg_hash = hash_new ();
2367 if (arc_reg_hash == NULL)
2368 as_fatal (_("Virtual memory exhausted"));
2370 declare_register_set ();
2371 declare_register ("gp", 26);
2372 declare_register ("fp", 27);
2373 declare_register ("sp", 28);
2374 declare_register ("ilink", 29);
2375 declare_register ("ilink1", 29);
2376 declare_register ("ilink2", 30);
2377 declare_register ("blink", 31);
2379 declare_register ("mlo", 57);
2380 declare_register ("mmid", 58);
2381 declare_register ("mhi", 59);
2383 declare_register ("acc1", 56);
2384 declare_register ("acc2", 57);
2386 declare_register ("lp_count", 60);
2387 declare_register ("pcl", 63);
2389 /* Initialize the last instructions. */
2390 memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2392 /* Aux register declaration. */
2393 arc_aux_hash = hash_new ();
2394 if (arc_aux_hash == NULL)
2395 as_fatal (_("Virtual memory exhausted"));
2397 const struct arc_aux_reg *auxr = &arc_aux_regs[0];
2399 for (i = 0; i < arc_num_aux_regs; i++, auxr++)
2403 if (!(auxr->cpu & arc_target))
2406 if ((auxr->subclass != NONE)
2407 && !check_cpu_feature (auxr->subclass))
2410 retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr);
2412 as_fatal (_("internal error: can't hash aux register '%s': %s"),
2413 auxr->name, retval);
2417 /* Write a value out to the object file, using the appropriate
2421 md_number_to_chars (char *buf,
2425 if (target_big_endian)
2426 number_to_chars_bigendian (buf, val, n);
2428 number_to_chars_littleendian (buf, val, n);
2431 /* Round up a section size to the appropriate boundary. */
2434 md_section_align (segT segment,
2437 int align = bfd_get_section_alignment (stdoutput, segment);
2439 return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
2442 /* The location from which a PC relative jump should be calculated,
2443 given a PC relative reloc. */
2446 md_pcrel_from_section (fixS *fixP,
2449 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
2451 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
2453 if (fixP->fx_addsy != (symbolS *) NULL
2454 && (!S_IS_DEFINED (fixP->fx_addsy)
2455 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2457 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
2459 /* The symbol is undefined (or is defined but not in this section).
2460 Let the linker figure it out. */
2464 if ((int) fixP->fx_r_type < 0)
2466 /* These are the "internal" relocations. Align them to
2467 32 bit boundary (PCL), for the moment. */
2472 switch (fixP->fx_r_type)
2474 case BFD_RELOC_ARC_PC32:
2475 /* The hardware calculates relative to the start of the
2476 insn, but this relocation is relative to location of the
2477 LIMM, compensate. The base always needs to be
2478 substracted by 4 as we do not support this type of PCrel
2479 relocation for short instructions. */
2482 case BFD_RELOC_ARC_PLT32:
2483 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2484 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2485 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2486 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2488 case BFD_RELOC_ARC_S21H_PCREL:
2489 case BFD_RELOC_ARC_S25H_PCREL:
2490 case BFD_RELOC_ARC_S13_PCREL:
2491 case BFD_RELOC_ARC_S21W_PCREL:
2492 case BFD_RELOC_ARC_S25W_PCREL:
2496 as_bad_where (fixP->fx_file, fixP->fx_line,
2497 _("unhandled reloc %s in md_pcrel_from_section"),
2498 bfd_get_reloc_code_name (fixP->fx_r_type));
2503 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
2504 fixP->fx_frag->fr_address, fixP->fx_where, base,
2505 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
2506 fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
2511 /* Given a BFD relocation find the coresponding operand. */
2513 static const struct arc_operand *
2514 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
2518 for (i = 0; i < arc_num_operands; i++)
2519 if (arc_operands[i].default_reloc == reloc)
2520 return &arc_operands[i];
2524 /* Insert an operand value into an instruction. */
2527 insert_operand (unsigned insn,
2528 const struct arc_operand *operand,
2533 offsetT min = 0, max = 0;
2535 if (operand->bits != 32
2536 && !(operand->flags & ARC_OPERAND_NCHK)
2537 && !(operand->flags & ARC_OPERAND_FAKE))
2539 if (operand->flags & ARC_OPERAND_SIGNED)
2541 max = (1 << (operand->bits - 1)) - 1;
2542 min = -(1 << (operand->bits - 1));
2546 max = (1 << operand->bits) - 1;
2550 if (val < min || val > max)
2551 as_bad_value_out_of_range (_("operand"),
2552 val, min, max, file, line);
2555 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2556 min, val, max, insn);
2558 if ((operand->flags & ARC_OPERAND_ALIGNED32)
2560 as_bad_where (file, line,
2561 _("Unaligned operand. Needs to be 32bit aligned"));
2563 if ((operand->flags & ARC_OPERAND_ALIGNED16)
2565 as_bad_where (file, line,
2566 _("Unaligned operand. Needs to be 16bit aligned"));
2568 if (operand->insert)
2570 const char *errmsg = NULL;
2572 insn = (*operand->insert) (insn, val, &errmsg);
2574 as_warn_where (file, line, "%s", errmsg);
2578 if (operand->flags & ARC_OPERAND_TRUNCATE)
2580 if (operand->flags & ARC_OPERAND_ALIGNED32)
2582 if (operand->flags & ARC_OPERAND_ALIGNED16)
2585 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2590 /* Apply a fixup to the object code. At this point all symbol values
2591 should be fully resolved, and we attempt to completely resolve the
2592 reloc. If we can not do that, we determine the correct reloc code
2593 and put it back in the fixup. To indicate that a fixup has been
2594 eliminated, set fixP->fx_done. */
2597 md_apply_fix (fixS *fixP,
2601 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
2602 valueT value = *valP;
2604 symbolS *fx_addsy, *fx_subsy;
2606 segT add_symbol_segment = absolute_section;
2607 segT sub_symbol_segment = absolute_section;
2608 const struct arc_operand *operand = NULL;
2609 extended_bfd_reloc_code_real_type reloc;
2611 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2612 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2613 ((int) fixP->fx_r_type < 0) ? "Internal":
2614 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2617 fx_addsy = fixP->fx_addsy;
2618 fx_subsy = fixP->fx_subsy;
2623 add_symbol_segment = S_GET_SEGMENT (fx_addsy);
2627 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
2628 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
2629 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
2631 resolve_symbol_value (fx_subsy);
2632 sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
2634 if (sub_symbol_segment == absolute_section)
2636 /* The symbol is really a constant. */
2637 fx_offset -= S_GET_VALUE (fx_subsy);
2642 as_bad_where (fixP->fx_file, fixP->fx_line,
2643 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2644 fx_addsy ? S_GET_NAME (fx_addsy) : "0",
2645 segment_name (add_symbol_segment),
2646 S_GET_NAME (fx_subsy),
2647 segment_name (sub_symbol_segment));
2653 && !S_IS_WEAK (fx_addsy))
2655 if (add_symbol_segment == seg
2658 value += S_GET_VALUE (fx_addsy);
2659 value -= md_pcrel_from_section (fixP, seg);
2661 fixP->fx_pcrel = FALSE;
2663 else if (add_symbol_segment == absolute_section)
2665 value = fixP->fx_offset;
2666 fx_offset += S_GET_VALUE (fixP->fx_addsy);
2668 fixP->fx_pcrel = FALSE;
2673 fixP->fx_done = TRUE;
2678 && ((S_IS_DEFINED (fx_addsy)
2679 && S_GET_SEGMENT (fx_addsy) != seg)
2680 || S_IS_WEAK (fx_addsy)))
2681 value += md_pcrel_from_section (fixP, seg);
2683 switch (fixP->fx_r_type)
2685 case BFD_RELOC_ARC_32_ME:
2686 /* This is a pc-relative value in a LIMM. Adjust it to the
2687 address of the instruction not to the address of the
2688 LIMM. Note: it is not anylonger valid this afirmation as
2689 the linker consider ARC_PC32 a fixup to entire 64 bit
2691 fixP->fx_offset += fixP->fx_frag->fr_address;
2694 fixP->fx_r_type = BFD_RELOC_ARC_PC32;
2696 case BFD_RELOC_ARC_PC32:
2697 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2700 if ((int) fixP->fx_r_type < 0)
2701 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2707 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2708 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2709 ((int) fixP->fx_r_type < 0) ? "Internal":
2710 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2714 /* Now check for TLS relocations. */
2715 reloc = fixP->fx_r_type;
2718 case BFD_RELOC_ARC_TLS_DTPOFF:
2719 case BFD_RELOC_ARC_TLS_LE_32:
2723 case BFD_RELOC_ARC_TLS_GD_GOT:
2724 case BFD_RELOC_ARC_TLS_IE_GOT:
2725 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2728 case BFD_RELOC_ARC_TLS_GD_LD:
2729 gas_assert (!fixP->fx_offset);
2732 = (S_GET_VALUE (fixP->fx_subsy)
2733 - fixP->fx_frag->fr_address- fixP->fx_where);
2734 fixP->fx_subsy = NULL;
2736 case BFD_RELOC_ARC_TLS_GD_CALL:
2737 /* These two relocs are there just to allow ld to change the tls
2738 model for this symbol, by patching the code. The offset -
2739 and scale, if any - will be installed by the linker. */
2740 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2743 case BFD_RELOC_ARC_TLS_LE_S9:
2744 case BFD_RELOC_ARC_TLS_DTPOFF_S9:
2745 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2757 /* Addjust the value if we have a constant. */
2760 /* For hosts with longs bigger than 32-bits make sure that the top
2761 bits of a 32-bit negative value read in by the parser are set,
2762 so that the correct comparisons are made. */
2763 if (value & 0x80000000)
2764 value |= (-1L << 31);
2766 reloc = fixP->fx_r_type;
2774 case BFD_RELOC_ARC_32_PCREL:
2775 md_number_to_chars (fixpos, value, fixP->fx_size);
2778 case BFD_RELOC_ARC_GOTPC32:
2779 /* I cannot fix an GOTPC relocation because I need to relax it
2780 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2781 as_bad (_("Unsupported operation on reloc"));
2784 case BFD_RELOC_ARC_TLS_DTPOFF:
2785 case BFD_RELOC_ARC_TLS_LE_32:
2786 gas_assert (!fixP->fx_addsy);
2787 gas_assert (!fixP->fx_subsy);
2789 case BFD_RELOC_ARC_GOTOFF:
2790 case BFD_RELOC_ARC_32_ME:
2791 case BFD_RELOC_ARC_PC32:
2792 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2795 case BFD_RELOC_ARC_PLT32:
2796 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2799 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2800 reloc = BFD_RELOC_ARC_S25W_PCREL;
2803 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2804 reloc = BFD_RELOC_ARC_S21H_PCREL;
2807 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2808 reloc = BFD_RELOC_ARC_S25W_PCREL;
2811 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2812 reloc = BFD_RELOC_ARC_S21W_PCREL;
2814 case BFD_RELOC_ARC_S25W_PCREL:
2815 case BFD_RELOC_ARC_S21W_PCREL:
2816 case BFD_RELOC_ARC_S21H_PCREL:
2817 case BFD_RELOC_ARC_S25H_PCREL:
2818 case BFD_RELOC_ARC_S13_PCREL:
2820 operand = find_operand_for_reloc (reloc);
2821 gas_assert (operand);
2826 if ((int) fixP->fx_r_type >= 0)
2827 as_fatal (_("unhandled relocation type %s"),
2828 bfd_get_reloc_code_name (fixP->fx_r_type));
2830 /* The rest of these fixups needs to be completely resolved as
2832 if (fixP->fx_addsy != 0
2833 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
2834 as_bad_where (fixP->fx_file, fixP->fx_line,
2835 _("non-absolute expression in constant field"));
2837 gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
2838 operand = &arc_operands[-(int) fixP->fx_r_type];
2843 if (target_big_endian)
2845 switch (fixP->fx_size)
2848 insn = bfd_getb32 (fixpos);
2851 insn = bfd_getb16 (fixpos);
2854 as_bad_where (fixP->fx_file, fixP->fx_line,
2855 _("unknown fixup size"));
2861 switch (fixP->fx_size)
2864 insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
2867 insn = bfd_getl16 (fixpos);
2870 as_bad_where (fixP->fx_file, fixP->fx_line,
2871 _("unknown fixup size"));
2875 insn = insert_operand (insn, operand, (offsetT) value,
2876 fixP->fx_file, fixP->fx_line);
2878 md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
2881 /* Prepare machine-dependent frags for relaxation.
2883 Called just before relaxation starts. Any symbol that is now undefined
2884 will not become defined.
2886 Return the correct fr_subtype in the frag.
2888 Return the initial "guess for fr_var" to caller. The guess for fr_var
2889 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
2890 or fr_var contributes to our returned value.
2892 Although it may not be explicit in the frag, pretend
2893 fr_var starts with a value. */
2896 md_estimate_size_before_relax (fragS *fragP,
2901 /* If the symbol is not located within the same section AND it's not
2902 an absolute section, use the maximum. OR if the symbol is a
2903 constant AND the insn is by nature not pc-rel, use the maximum.
2904 OR if the symbol is being equated against another symbol, use the
2905 maximum. OR if the symbol is weak use the maximum. */
2906 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
2907 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2908 || (symbol_constant_p (fragP->fr_symbol)
2909 && !fragP->tc_frag_data.pcrel)
2910 || symbol_equated_p (fragP->fr_symbol)
2911 || S_IS_WEAK (fragP->fr_symbol))
2913 while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
2914 ++fragP->fr_subtype;
2917 growth = md_relax_table[fragP->fr_subtype].rlx_length;
2918 fragP->fr_var = growth;
2920 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
2921 fragP->fr_file, fragP->fr_line, growth);
2926 /* Translate internal representation of relocation info to BFD target
2930 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
2934 bfd_reloc_code_real_type code;
2936 reloc = (arelent *) xmalloc (sizeof (* reloc));
2937 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2938 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
2939 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2941 /* Make sure none of our internal relocations make it this far.
2942 They'd better have been fully resolved by this point. */
2943 gas_assert ((int) fixP->fx_r_type > 0);
2945 code = fixP->fx_r_type;
2947 /* if we have something like add gp, pcl,
2948 _GLOBAL_OFFSET_TABLE_@gotpc. */
2949 if (code == BFD_RELOC_ARC_GOTPC32
2951 && fixP->fx_addsy == GOT_symbol)
2952 code = BFD_RELOC_ARC_GOTPC;
2954 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2955 if (reloc->howto == NULL)
2957 as_bad_where (fixP->fx_file, fixP->fx_line,
2958 _("cannot represent `%s' relocation in object file"),
2959 bfd_get_reloc_code_name (code));
2963 if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
2964 as_fatal (_("internal error? cannot generate `%s' relocation"),
2965 bfd_get_reloc_code_name (code));
2967 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
2969 if (code == BFD_RELOC_ARC_TLS_DTPOFF
2970 || code == BFD_RELOC_ARC_TLS_DTPOFF_S9)
2973 = fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL;
2974 /* We just want to store a 24 bit index, but we have to wait
2975 till after write_contents has been called via
2976 bfd_map_over_sections before we can get the index from
2977 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
2978 function is elf32-arc.c has to pick up the slack.
2979 Unfortunately, this leads to problems with hosts that have
2980 pointers wider than long (bfd_vma). There would be various
2981 ways to handle this, all error-prone :-( */
2982 reloc->addend = (bfd_vma) sym;
2983 if ((asymbol *) reloc->addend != sym)
2985 as_bad ("Can't store pointer\n");
2990 reloc->addend = fixP->fx_offset;
2995 /* Perform post-processing of machine-dependent frags after relaxation.
2996 Called after relaxation is finished.
2997 In: Address of frag.
2998 fr_type == rs_machine_dependent.
2999 fr_subtype is what the address relaxed to.
3001 Out: Any fixS:s and constants are set up. */
3004 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
3005 segT segment ATTRIBUTE_UNUSED,
3008 const relax_typeS *table_entry;
3010 const struct arc_opcode *opcode;
3011 struct arc_insn insn;
3013 struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
3015 fix = (fragP->fr_fix < 0 ? 0 : fragP->fr_fix);
3016 dest = fragP->fr_literal + fix;
3017 table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
3019 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
3020 fragP->fr_file, fragP->fr_line,
3021 fragP->fr_subtype, fix, fragP->fr_var);
3023 if (fragP->fr_subtype <= 0
3024 && fragP->fr_subtype >= arc_num_relax_opcodes)
3025 as_fatal (_("no relaxation found for this instruction."));
3027 opcode = &arc_relax_opcodes[fragP->fr_subtype];
3029 assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
3030 relax_arg->nflg, &insn);
3032 apply_fixups (&insn, fragP, fix);
3034 size = insn.short_insn ? (insn.has_limm ? 6 : 2) : (insn.has_limm ? 8 : 4);
3035 gas_assert (table_entry->rlx_length == size);
3036 emit_insn0 (&insn, dest, TRUE);
3038 fragP->fr_fix += table_entry->rlx_length;
3042 /* We have no need to default values of symbols. We could catch
3043 register names here, but that is handled by inserting them all in
3044 the symbol table to begin with. */
3047 md_undefined_symbol (char *name)
3049 /* The arc abi demands that a GOT[0] should be referencible as
3050 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3051 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3053 && (*(name+1) == 'G')
3054 && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))
3056 && (*(name+1) == 'D')
3057 && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0)))
3061 if (symbol_find (name))
3062 as_bad ("GOT already in symbol table");
3064 GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
3065 (valueT) 0, &zero_address_frag);
3072 /* Turn a string in input_line_pointer into a floating point constant
3073 of type type, and store the appropriate bytes in *litP. The number
3074 of LITTLENUMS emitted is stored in *sizeP. An error message is
3075 returned, or NULL on OK. */
3078 md_atof (int type, char *litP, int *sizeP)
3080 return ieee_md_atof (type, litP, sizeP, target_big_endian);
3083 /* Called for any expression that can not be recognized. When the
3084 function is called, `input_line_pointer' will point to the start of
3088 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
3090 char *p = input_line_pointer;
3093 input_line_pointer++;
3094 expressionP->X_op = O_symbol;
3095 expression (expressionP);
3099 /* This function is called from the function 'expression', it attempts
3100 to parse special names (in our case register names). It fills in
3101 the expression with the identified register. It returns TRUE if
3102 it is a register and FALSE otherwise. */
3105 arc_parse_name (const char *name,
3106 struct expressionS *e)
3110 if (!assembling_insn)
3113 /* Handle only registers. */
3114 if (e->X_op != O_absent)
3117 sym = hash_find (arc_reg_hash, name);
3120 e->X_op = O_register;
3121 e->X_add_number = S_GET_VALUE (sym);
3128 Invocation line includes a switch not recognized by the base assembler.
3129 See if it's a processor-specific option.
3131 New options (supported) are:
3133 -mcpu=<cpu name> Assemble for selected processor
3134 -EB/-mbig-endian Big-endian
3135 -EL/-mlittle-endian Little-endian
3136 -mrelax Enable relaxation
3138 The following CPU names are recognized:
3139 arc700, av2em, av2hs. */
3142 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
3148 return md_parse_option (OPTION_MCPU, "arc600");
3151 return md_parse_option (OPTION_MCPU, "arc700");
3154 return md_parse_option (OPTION_MCPU, "arcem");
3157 return md_parse_option (OPTION_MCPU, "archs");
3161 arc_select_cpu (arg);
3162 mach_type_specified_p = TRUE;
3167 arc_target_format = "elf32-bigarc";
3168 byte_order = BIG_ENDIAN;
3172 arc_target_format = "elf32-littlearc";
3173 byte_order = LITTLE_ENDIAN;
3177 /* This option has an effect only on ARC EM. */
3178 if (arc_target & ARC_OPCODE_ARCv2EM)
3179 arc_features |= ARC_CD;
3181 as_warn (_("Code density option invalid for selected CPU"));
3185 relaxation_state = 1;
3188 case OPTION_USER_MODE:
3189 case OPTION_LD_EXT_MASK:
3192 case OPTION_BARREL_SHIFT:
3193 case OPTION_MIN_MAX:
3198 /* Dummy options are accepted but have no effect. */
3202 arc_features |= ARC_SPFP;
3206 arc_features |= ARC_DPFP;
3209 case OPTION_XMAC_D16:
3210 case OPTION_XMAC_24:
3211 case OPTION_DSP_PACKA:
3214 case OPTION_TELEPHONY:
3215 case OPTION_XYMEMORY:
3219 /* Dummy options are accepted but have no effect. */
3223 /* This option has an effect only on ARC EM. */
3224 if (arc_target & ARC_OPCODE_ARCv2EM)
3225 arc_features |= ARC_FPUDA;
3227 as_warn (_("FPUDA invalid for selected CPU"));
3238 md_show_usage (FILE *stream)
3240 fprintf (stream, _("ARC-specific assembler options:\n"));
3242 fprintf (stream, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
3244 " -mcode-density\t enable code density option for ARC EM\n");
3246 fprintf (stream, _("\
3247 -EB assemble code for a big-endian cpu\n"));
3248 fprintf (stream, _("\
3249 -EL assemble code for a little-endian cpu\n"));
3250 fprintf (stream, _("\
3251 -mrelax Enable relaxation\n"));
3255 /* Find the proper relocation for the given opcode. */
3257 static extended_bfd_reloc_code_real_type
3258 find_reloc (const char *name,
3259 const char *opcodename,
3260 const struct arc_flags *pflags,
3262 extended_bfd_reloc_code_real_type reloc)
3266 bfd_boolean found_flag, tmp;
3267 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
3269 for (i = 0; i < arc_num_equiv_tab; i++)
3271 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
3273 /* Find the entry. */
3274 if (strcmp (name, r->name))
3276 if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
3283 unsigned * psflg = (unsigned *)r->flags;
3287 for (j = 0; j < nflg; j++)
3288 if (!strcmp (pflags[j].name,
3289 arc_flag_operands[*psflg].name))
3310 if (reloc != r->oldreloc)
3317 if (ret == BFD_RELOC_UNUSED)
3318 as_bad (_("Unable to find %s relocation for instruction %s"),
3323 /* All the symbol types that are allowed to be used for
3327 may_relax_expr (expressionS tok)
3329 /* Check if we have unrelaxable relocs. */
3354 /* Checks if flags are in line with relaxable insn. */
3357 relaxable_flag (const struct arc_relaxable_ins *ins,
3358 const struct arc_flags *pflags,
3361 unsigned flag_class,
3366 const struct arc_flag_operand *flag_opand;
3367 int i, counttrue = 0;
3369 /* Iterate through flags classes. */
3370 while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
3372 /* Iterate through flags in flag class. */
3373 while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
3376 flag_opand = &arc_flag_operands[flag];
3377 /* Iterate through flags in ins to compare. */
3378 for (i = 0; i < nflgs; ++i)
3380 if (strcmp (flag_opand->name, pflags[i].name) == 0)
3391 /* If counttrue == nflgs, then all flags have been found. */
3392 return (counttrue == nflgs ? TRUE : FALSE);
3395 /* Checks if operands are in line with relaxable insn. */
3398 relaxable_operand (const struct arc_relaxable_ins *ins,
3399 const expressionS *tok,
3402 const enum rlx_operand_type *operand = &ins->operands[0];
3405 while (*operand != EMPTY)
3407 const expressionS *epr = &tok[i];
3409 if (i != 0 && i >= ntok)
3415 if (!(epr->X_op == O_multiply
3416 || epr->X_op == O_divide
3417 || epr->X_op == O_modulus
3418 || epr->X_op == O_add
3419 || epr->X_op == O_subtract
3420 || epr->X_op == O_symbol))
3426 || (epr->X_add_number != tok[i - 1].X_add_number))
3430 if (epr->X_op != O_register)
3435 if (epr->X_op != O_register)
3438 switch (epr->X_add_number)
3440 case 0: case 1: case 2: case 3:
3441 case 12: case 13: case 14: case 15:
3448 case REGISTER_NO_GP:
3449 if ((epr->X_op != O_register)
3450 || (epr->X_add_number == 26)) /* 26 is the gp register. */
3455 if (epr->X_op != O_bracket)
3460 /* Don't understand, bail out. */
3466 operand = &ins->operands[i];
3469 return (i == ntok ? TRUE : FALSE);
3472 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3475 relax_insn_p (const struct arc_opcode *opcode,
3476 const expressionS *tok,
3478 const struct arc_flags *pflags,
3482 bfd_boolean rv = FALSE;
3484 /* Check the relaxation table. */
3485 for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
3487 const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
3489 if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
3490 && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
3491 && relaxable_operand (arc_rlx_ins, tok, ntok)
3492 && relaxable_flag (arc_rlx_ins, pflags, nflg))
3495 frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
3496 memcpy (&frag_now->tc_frag_data.tok, tok,
3497 sizeof (expressionS) * ntok);
3498 memcpy (&frag_now->tc_frag_data.pflags, pflags,
3499 sizeof (struct arc_flags) * nflg);
3500 frag_now->tc_frag_data.nflg = nflg;
3501 frag_now->tc_frag_data.ntok = ntok;
3509 /* Turn an opcode description and a set of arguments into
3510 an instruction and a fixup. */
3513 assemble_insn (const struct arc_opcode *opcode,
3514 const expressionS *tok,
3516 const struct arc_flags *pflags,
3518 struct arc_insn *insn)
3520 const expressionS *reloc_exp = NULL;
3522 const unsigned char *argidx;
3525 unsigned char pcrel = 0;
3526 bfd_boolean needGOTSymbol;
3527 bfd_boolean has_delay_slot = FALSE;
3528 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3530 memset (insn, 0, sizeof (*insn));
3531 image = opcode->opcode;
3533 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3534 frag_now->fr_file, frag_now->fr_line, opcode->name,
3537 /* Handle operands. */
3538 for (argidx = opcode->operands; *argidx; ++argidx)
3540 const struct arc_operand *operand = &arc_operands[*argidx];
3541 const expressionS *t = (const expressionS *) 0;
3543 if ((operand->flags & ARC_OPERAND_FAKE)
3544 && !(operand->flags & ARC_OPERAND_BRAKET))
3547 if (operand->flags & ARC_OPERAND_DUPLICATE)
3549 /* Duplicate operand, already inserted. */
3561 /* Regardless if we have a reloc or not mark the instruction
3562 limm if it is the case. */
3563 if (operand->flags & ARC_OPERAND_LIMM)
3564 insn->has_limm = TRUE;
3569 image = insert_operand (image, operand, regno (t->X_add_number),
3574 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
3576 if (operand->flags & ARC_OPERAND_LIMM)
3577 insn->limm = t->X_add_number;
3581 /* Ignore brackets. */
3585 gas_assert (operand->flags & ARC_OPERAND_IGNORE);
3589 /* Maybe register range. */
3590 if ((t->X_add_number == 0)
3591 && contains_register (t->X_add_symbol)
3592 && contains_register (t->X_op_symbol))
3596 regs = get_register (t->X_add_symbol);
3598 regs |= get_register (t->X_op_symbol);
3599 image = insert_operand (image, operand, regs, NULL, 0);
3604 /* This operand needs a relocation. */
3605 needGOTSymbol = FALSE;
3610 if (opcode->class == JUMP)
3611 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3612 _("Unable to use @plt relocatio for insn %s"),
3614 needGOTSymbol = TRUE;
3615 reloc = find_reloc ("plt", opcode->name,
3617 operand->default_reloc);
3622 needGOTSymbol = TRUE;
3623 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3626 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3627 if (ARC_SHORT (opcode->mask) || opcode->class == JUMP)
3628 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3629 _("Unable to use @pcl relocation for insn %s"),
3633 reloc = find_reloc ("sda", opcode->name,
3635 operand->default_reloc);
3639 needGOTSymbol = TRUE;
3644 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3647 case O_tpoff9: /*FIXME! Check for the conditionality of
3649 case O_dtpoff9: /*FIXME! Check for the conditionality of
3651 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3655 /* Just consider the default relocation. */
3656 reloc = operand->default_reloc;
3660 if (needGOTSymbol && (GOT_symbol == NULL))
3661 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
3668 /* sanity checks. */
3669 reloc_howto_type *reloc_howto
3670 = bfd_reloc_type_lookup (stdoutput,
3671 (bfd_reloc_code_real_type) reloc);
3672 unsigned reloc_bitsize = reloc_howto->bitsize;
3673 if (reloc_howto->rightshift)
3674 reloc_bitsize -= reloc_howto->rightshift;
3675 if (reloc_bitsize != operand->bits)
3677 as_bad (_("invalid relocation %s for field"),
3678 bfd_get_reloc_code_name (reloc));
3683 if (insn->nfixups >= MAX_INSN_FIXUPS)
3684 as_fatal (_("too many fixups"));
3686 struct arc_fixup *fixup;
3687 fixup = &insn->fixups[insn->nfixups++];
3689 fixup->reloc = reloc;
3690 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
3691 fixup->pcrel = pcrel;
3692 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
3699 for (i = 0; i < nflg; i++)
3701 const struct arc_flag_operand *flg_operand = pflags[i].flgp;
3703 /* Check if the instruction has a delay slot. */
3704 if (!strcmp (flg_operand->name, "d"))
3705 has_delay_slot = TRUE;
3707 /* There is an exceptional case when we cannot insert a flag
3708 just as it is. The .T flag must be handled in relation with
3709 the relative address. */
3710 if (!strcmp (flg_operand->name, "t")
3711 || !strcmp (flg_operand->name, "nt"))
3713 unsigned bitYoperand = 0;
3714 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3715 if (!strcmp (flg_operand->name, "t"))
3716 if (!strcmp (opcode->name, "bbit0")
3717 || !strcmp (opcode->name, "bbit1"))
3718 bitYoperand = arc_NToperand;
3720 bitYoperand = arc_Toperand;
3722 if (!strcmp (opcode->name, "bbit0")
3723 || !strcmp (opcode->name, "bbit1"))
3724 bitYoperand = arc_Toperand;
3726 bitYoperand = arc_NToperand;
3728 gas_assert (reloc_exp != NULL);
3729 if (reloc_exp->X_op == O_constant)
3731 /* Check if we have a constant and solved it
3733 offsetT val = reloc_exp->X_add_number;
3734 image |= insert_operand (image, &arc_operands[bitYoperand],
3739 struct arc_fixup *fixup;
3741 if (insn->nfixups >= MAX_INSN_FIXUPS)
3742 as_fatal (_("too many fixups"));
3744 fixup = &insn->fixups[insn->nfixups++];
3745 fixup->exp = *reloc_exp;
3746 fixup->reloc = -bitYoperand;
3747 fixup->pcrel = pcrel;
3748 fixup->islong = FALSE;
3752 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
3753 << flg_operand->shift;
3756 insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
3758 /* Short instruction? */
3759 insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
3763 /* Update last insn status. */
3764 arc_last_insns[1] = arc_last_insns[0];
3765 arc_last_insns[0].opcode = opcode;
3766 arc_last_insns[0].has_limm = insn->has_limm;
3767 arc_last_insns[0].has_delay_slot = has_delay_slot;
3769 /* Check if the current instruction is legally used. */
3770 if (arc_last_insns[1].has_delay_slot
3771 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3772 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3773 _("A jump/branch instruction in delay slot."));
3777 arc_handle_align (fragS* fragP)
3779 if ((fragP)->fr_type == rs_align_code)
3781 char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
3782 valueT count = ((fragP)->fr_next->fr_address
3783 - (fragP)->fr_address - (fragP)->fr_fix);
3785 (fragP)->fr_var = 2;
3787 if (count & 1)/* Padding in the gap till the next 2-byte
3788 boundary with 0s. */
3793 /* Writing nop_s. */
3794 md_number_to_chars (dest, NOP_OPCODE_S, 2);
3798 /* Here we decide which fixups can be adjusted to make them relative
3799 to the beginning of the section instead of the symbol. Basically
3800 we need to make sure that the dynamic relocations are done
3801 correctly, so in some cases we force the original symbol to be
3805 tc_arc_fix_adjustable (fixS *fixP)
3808 /* Prevent all adjustments to global symbols. */
3809 if (S_IS_EXTERNAL (fixP->fx_addsy))
3811 if (S_IS_WEAK (fixP->fx_addsy))
3814 /* Adjust_reloc_syms doesn't know about the GOT. */
3815 switch (fixP->fx_r_type)
3817 case BFD_RELOC_ARC_GOTPC32:
3818 case BFD_RELOC_ARC_PLT32:
3819 case BFD_RELOC_ARC_S25H_PCREL_PLT:
3820 case BFD_RELOC_ARC_S21H_PCREL_PLT:
3821 case BFD_RELOC_ARC_S25W_PCREL_PLT:
3822 case BFD_RELOC_ARC_S21W_PCREL_PLT:
3832 /* Compute the reloc type of an expression EXP. */
3835 arc_check_reloc (expressionS *exp,
3836 bfd_reloc_code_real_type *r_type_p)
3838 if (*r_type_p == BFD_RELOC_32
3839 && exp->X_op == O_subtract
3840 && exp->X_op_symbol != NULL
3841 && exp->X_op_symbol->bsym->section == now_seg)
3842 *r_type_p = BFD_RELOC_ARC_32_PCREL;
3846 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3849 arc_cons_fix_new (fragS *frag,
3853 bfd_reloc_code_real_type r_type)
3855 r_type = BFD_RELOC_UNUSED;
3860 r_type = BFD_RELOC_8;
3864 r_type = BFD_RELOC_16;
3868 r_type = BFD_RELOC_24;
3872 r_type = BFD_RELOC_32;
3873 arc_check_reloc (exp, &r_type);
3877 r_type = BFD_RELOC_64;
3881 as_bad (_("unsupported BFD relocation size %u"), size);
3882 r_type = BFD_RELOC_UNUSED;
3885 fix_new_exp (frag, off, size, exp, 0, r_type);
3888 /* The actual routine that checks the ZOL conditions. */
3891 check_zol (symbolS *s)
3893 switch (arc_mach_type)
3895 case bfd_mach_arc_arcv2:
3896 if (arc_target & ARC_OPCODE_ARCv2EM)
3899 if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
3900 || arc_last_insns[1].has_delay_slot)
3901 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3905 case bfd_mach_arc_arc600:
3907 if (is_kernel_insn_p (arc_last_insns[0].opcode))
3908 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3911 if (arc_last_insns[0].has_limm
3912 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3913 as_bad (_("A jump instruction with long immediate detected at the \
3914 end of the ZOL label @%s"), S_GET_NAME (s));
3917 case bfd_mach_arc_nps400:
3918 case bfd_mach_arc_arc700:
3919 if (arc_last_insns[0].has_delay_slot)
3920 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3929 /* If ZOL end check the last two instruction for illegals. */
3931 arc_frob_label (symbolS * sym)
3933 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
3936 dwarf2_emit_label (sym);
3939 /* Used because generic relaxation assumes a pc-rel value whilst we
3940 also relax instructions that use an absolute value resolved out of
3941 relative values (if that makes any sense). An example: 'add r1,
3942 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
3943 but if they're in the same section we can subtract the section
3944 offset relocation which ends up in a resolved value. So if @.L2 is
3945 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
3946 .text + 0x40 = 0x10. */
3948 arc_pcrel_adjust (fragS *fragP)
3950 if (!fragP->tc_frag_data.pcrel)
3951 return fragP->fr_address + fragP->fr_fix;
3956 /* Initialize the DWARF-2 unwind information for this procedure. */
3959 tc_arc_frame_initial_instructions (void)
3961 /* Stack pointer is register 28. */
3962 cfi_add_CFA_def_cfa_register (28);
3966 tc_arc_regname_to_dw2regnum (char *regname)
3970 sym = hash_find (arc_reg_hash, regname);
3972 return S_GET_VALUE (sym);
3977 /* Adjust the symbol table. Delete found AUX register symbols. */
3980 arc_adjust_symtab (void)
3984 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
3986 /* I've created a symbol during parsing process. Now, remove
3987 the symbol as it is found to be an AUX register. */
3988 if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX)
3989 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
3992 /* Now do generic ELF adjustments. */
3993 elf_adjust_symtab ();
3997 tokenize_extinsn (extInstruction_t *einsn)
4001 unsigned char major_opcode;
4002 unsigned char sub_opcode;
4003 unsigned char syntax_class = 0;
4004 unsigned char syntax_class_modifiers = 0;
4005 unsigned char suffix_class = 0;
4010 /* 1st: get instruction name. */
4011 p = input_line_pointer;
4012 c = get_symbol_name (&p);
4014 insn_name = xstrdup (p);
4015 restore_line_pointer (c);
4017 /* 2nd: get major opcode. */
4018 if (*input_line_pointer != ',')
4020 as_bad (_("expected comma after instruction name"));
4021 ignore_rest_of_line ();
4024 input_line_pointer++;
4025 major_opcode = get_absolute_expression ();
4027 /* 3rd: get sub-opcode. */
4030 if (*input_line_pointer != ',')
4032 as_bad (_("expected comma after major opcode"));
4033 ignore_rest_of_line ();
4036 input_line_pointer++;
4037 sub_opcode = get_absolute_expression ();
4039 /* 4th: get suffix class. */
4042 if (*input_line_pointer != ',')
4044 as_bad ("expected comma after sub opcode");
4045 ignore_rest_of_line ();
4048 input_line_pointer++;
4054 for (i = 0; i < ARRAY_SIZE (suffixclass); i++)
4056 if (!strncmp (suffixclass[i].name, input_line_pointer,
4057 suffixclass[i].len))
4059 suffix_class |= suffixclass[i].class;
4060 input_line_pointer += suffixclass[i].len;
4065 if (i == ARRAY_SIZE (suffixclass))
4067 as_bad ("invalid suffix class");
4068 ignore_rest_of_line ();
4074 if (*input_line_pointer == '|')
4075 input_line_pointer++;
4080 /* 5th: get syntax class and syntax class modifiers. */
4081 if (*input_line_pointer != ',')
4083 as_bad ("expected comma after suffix class");
4084 ignore_rest_of_line ();
4087 input_line_pointer++;
4093 for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++)
4095 if (!strncmp (syntaxclassmod[i].name,
4097 syntaxclassmod[i].len))
4099 syntax_class_modifiers |= syntaxclassmod[i].class;
4100 input_line_pointer += syntaxclassmod[i].len;
4105 if (i == ARRAY_SIZE (syntaxclassmod))
4107 for (i = 0; i < ARRAY_SIZE (syntaxclass); i++)
4109 if (!strncmp (syntaxclass[i].name,
4111 syntaxclass[i].len))
4113 syntax_class |= syntaxclass[i].class;
4114 input_line_pointer += syntaxclass[i].len;
4119 if (i == ARRAY_SIZE (syntaxclass))
4121 as_bad ("missing syntax class");
4122 ignore_rest_of_line ();
4129 if (*input_line_pointer == '|')
4130 input_line_pointer++;
4135 demand_empty_rest_of_line ();
4137 einsn->name = insn_name;
4138 einsn->major = major_opcode;
4139 einsn->minor = sub_opcode;
4140 einsn->syntax = syntax_class;
4141 einsn->modsyn = syntax_class_modifiers;
4142 einsn->suffix = suffix_class;
4143 einsn->flags = syntax_class
4144 | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0);
4147 /* Generate an extension section. */
4150 arc_set_ext_seg (void)
4152 if (!arcext_section)
4154 arcext_section = subseg_new (".arcextmap", 0);
4155 bfd_set_section_flags (stdoutput, arcext_section,
4156 SEC_READONLY | SEC_HAS_CONTENTS);
4159 subseg_set (arcext_section, 0);
4163 /* Create an extension instruction description in the arc extension
4164 section of the output file.
4165 The structure for an instruction is like this:
4166 [0]: Length of the record.
4167 [1]: Type of the record.
4171 [4]: Syntax (flags).
4172 [5]+ Name instruction.
4174 The sequence is terminated by an empty entry. */
4177 create_extinst_section (extInstruction_t *einsn)
4180 segT old_sec = now_seg;
4181 int old_subsec = now_subseg;
4183 int name_len = strlen (einsn->name);
4188 *p = 5 + name_len + 1;
4190 *p = EXT_INSTRUCTION;
4197 p = frag_more (name_len + 1);
4198 strcpy (p, einsn->name);
4200 subseg_set (old_sec, old_subsec);
4203 /* Handler .extinstruction pseudo-op. */
4206 arc_extinsn (int ignore ATTRIBUTE_UNUSED)
4208 extInstruction_t einsn;
4209 struct arc_opcode *arc_ext_opcodes;
4210 const char *errmsg = NULL;
4211 unsigned char moplow, mophigh;
4213 memset (&einsn, 0, sizeof (einsn));
4214 tokenize_extinsn (&einsn);
4216 /* Check if the name is already used. */
4217 if (arc_find_opcode (einsn.name))
4218 as_warn (_("Pseudocode already used %s"), einsn.name);
4220 /* Check the opcode ranges. */
4222 mophigh = (arc_target & (ARC_OPCODE_ARCv2EM
4223 | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a;
4225 if ((einsn.major > mophigh) || (einsn.major < moplow))
4226 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh);
4228 if ((einsn.minor > 0x3f) && (einsn.major != 0x0a)
4229 && (einsn.major != 5) && (einsn.major != 9))
4230 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4232 switch (einsn.syntax & (ARC_SYNTAX_3OP | ARC_SYNTAX_2OP))
4234 case ARC_SYNTAX_3OP:
4235 if (einsn.modsyn & ARC_OP1_IMM_IMPLIED)
4236 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4238 case ARC_SYNTAX_2OP:
4239 if (einsn.modsyn & ARC_OP1_MUST_BE_IMM)
4240 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4246 arc_ext_opcodes = arcExtMap_genOpcode (&einsn, arc_target, &errmsg);
4247 if (arc_ext_opcodes == NULL)
4250 as_fatal ("%s", errmsg);
4252 as_fatal (_("Couldn't generate extension instruction opcodes"));
4255 as_warn ("%s", errmsg);
4257 /* Insert the extension instruction. */
4258 arc_insert_opcode ((const struct arc_opcode *) arc_ext_opcodes);
4260 create_extinst_section (&einsn);
4264 tokenize_extregister (extRegister_t *ereg, int opertype)
4270 int number, imode = 0;
4271 bfd_boolean isCore_p = (opertype == EXT_CORE_REGISTER) ? TRUE : FALSE;
4272 bfd_boolean isReg_p = (opertype == EXT_CORE_REGISTER
4273 || opertype == EXT_AUX_REGISTER) ? TRUE : FALSE;
4275 /* 1st: get register name. */
4277 p = input_line_pointer;
4278 c = get_symbol_name (&p);
4281 restore_line_pointer (c);
4283 /* 2nd: get register number. */
4286 if (*input_line_pointer != ',')
4288 as_bad (_("expected comma after register name"));
4289 ignore_rest_of_line ();
4293 input_line_pointer++;
4294 number = get_absolute_expression ();
4298 as_bad (_("negative operand number %d"), number);
4299 ignore_rest_of_line ();
4306 /* 3rd: get register mode. */
4309 if (*input_line_pointer != ',')
4311 as_bad (_("expected comma after register number"));
4312 ignore_rest_of_line ();
4317 input_line_pointer++;
4318 mode = input_line_pointer;
4320 if (!strncmp (mode, "r|w", 3))
4323 input_line_pointer += 3;
4325 else if (!strncmp (mode, "r", 1))
4327 imode = ARC_REGISTER_READONLY;
4328 input_line_pointer += 1;
4330 else if (strncmp (mode, "w", 1))
4332 as_bad (_("invalid mode"));
4333 ignore_rest_of_line ();
4339 imode = ARC_REGISTER_WRITEONLY;
4340 input_line_pointer += 1;
4346 /* 4th: get core register shortcut. */
4348 if (*input_line_pointer != ',')
4350 as_bad (_("expected comma after register mode"));
4351 ignore_rest_of_line ();
4356 input_line_pointer++;
4358 if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
4360 imode |= ARC_REGISTER_NOSHORT_CUT;
4361 input_line_pointer += 15;
4363 else if (strncmp (input_line_pointer, "can_shortcut", 12))
4365 as_bad (_("shortcut designator invalid"));
4366 ignore_rest_of_line ();
4372 input_line_pointer += 12;
4375 demand_empty_rest_of_line ();
4378 ereg->number = number;
4379 ereg->imode = imode;
4382 /* Create an extension register/condition description in the arc
4383 extension section of the output file.
4385 The structure for an instruction is like this:
4386 [0]: Length of the record.
4387 [1]: Type of the record.
4389 For core regs and condition codes:
4393 For auxilirary registers:
4397 The sequence is terminated by an empty entry. */
4400 create_extcore_section (extRegister_t *ereg, int opertype)
4402 segT old_sec = now_seg;
4403 int old_subsec = now_subseg;
4405 int name_len = strlen (ereg->name);
4412 case EXT_CORE_REGISTER:
4414 *p = 3 + name_len + 1;
4420 case EXT_AUX_REGISTER:
4422 *p = 6 + name_len + 1;
4424 *p = EXT_AUX_REGISTER;
4426 *p = (ereg->number >> 24) & 0xff;
4428 *p = (ereg->number >> 16) & 0xff;
4430 *p = (ereg->number >> 8) & 0xff;
4432 *p = (ereg->number) & 0xff;
4438 p = frag_more (name_len + 1);
4439 strcpy (p, ereg->name);
4441 subseg_set (old_sec, old_subsec);
4444 /* Handler .extCoreRegister pseudo-op. */
4447 arc_extcorereg (int opertype)
4450 struct arc_aux_reg *auxr;
4452 struct arc_flag_operand *ccode;
4454 memset (&ereg, 0, sizeof (ereg));
4455 tokenize_extregister (&ereg, opertype);
4459 case EXT_CORE_REGISTER:
4460 /* Core register. */
4461 if (ereg.number > 60)
4462 as_bad (_("core register %s value (%d) too large"), ereg.name,
4464 declare_register (ereg.name, ereg.number);
4466 case EXT_AUX_REGISTER:
4467 /* Auxiliary register. */
4468 auxr = xmalloc (sizeof (struct arc_aux_reg));
4469 auxr->name = ereg.name;
4470 auxr->cpu = arc_target;
4471 auxr->subclass = NONE;
4472 auxr->address = ereg.number;
4473 retval = hash_insert (arc_aux_hash, auxr->name, (void *) auxr);
4475 as_fatal (_("internal error: can't hash aux register '%s': %s"),
4476 auxr->name, retval);
4479 /* Condition code. */
4480 if (ereg.number > 31)
4481 as_bad (_("condition code %s value (%d) too large"), ereg.name,
4483 ext_condcode.size ++;
4484 ext_condcode.arc_ext_condcode =
4485 xrealloc (ext_condcode.arc_ext_condcode,
4486 (ext_condcode.size + 1) * sizeof (struct arc_flag_operand));
4487 if (ext_condcode.arc_ext_condcode == NULL)
4488 as_fatal (_("Virtual memory exhausted"));
4490 ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1;
4491 ccode->name = ereg.name;
4492 ccode->code = ereg.number;
4495 ccode->favail = 0; /* not used. */
4497 memset (ccode, 0, sizeof (struct arc_flag_operand));
4500 as_bad (_("Unknown extension"));
4503 create_extcore_section (&ereg, opertype);
4507 eval: (c-set-style "gnu")