1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2020 Free Software Foundation, Inc.
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
25 #include "dwarf2dbg.h"
26 #include "dw2gencfi.h"
27 #include "safe-ctype.h"
29 #include "opcode/arc.h"
30 #include "opcode/arc-attrs.h"
32 #include "../opcodes/arc-ext.h"
34 /* Defines section. */
36 #define MAX_INSN_FIXUPS 2
37 #define MAX_CONSTR_STR 20
38 #define FRAG_MAX_GROWTH 8
41 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
43 # define pr_debug(fmt, args...)
46 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
47 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
48 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) \
49 && (SUB_OPCODE (x) == 0x28))
51 #ifndef TARGET_WITH_CPU
52 #define TARGET_WITH_CPU "arc700"
53 #endif /* TARGET_WITH_CPU */
55 #define ARC_GET_FLAG(s) (*symbol_get_tc (s))
56 #define ARC_SET_FLAG(s,v) (*symbol_get_tc (s) |= (v))
57 #define streq(a, b) (strcmp (a, b) == 0)
59 /* Enum used to enumerate the relaxable ins operands. */
64 REGISTER_S
, /* Register for short instruction(s). */
65 REGISTER_NO_GP
, /* Is a register but not gp register specifically. */
66 REGISTER_DUP
, /* Duplication of previous operand of type register. */
100 #define regno(x) ((x) & 0x3F)
101 #define is_ir_num(x) (((x) & ~0x3F) == 0)
102 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
103 #define is_spfp_p(op) (((sc) == SPX))
104 #define is_dpfp_p(op) (((sc) == DPX))
105 #define is_fpuda_p(op) (((sc) == DPA))
106 #define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH \
107 || (op)->insn_class == JUMP \
108 || (op)->insn_class == BRCC \
109 || (op)->insn_class == BBIT0 \
110 || (op)->insn_class == BBIT1 \
111 || (op)->insn_class == BI \
112 || (op)->insn_class == EI \
113 || (op)->insn_class == ENTER \
114 || (op)->insn_class == JLI \
115 || (op)->insn_class == LOOP \
116 || (op)->insn_class == LEAVE \
118 #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL))
119 #define is_nps400_p(op) (((sc) == NPS400))
121 /* Generic assembler global variables which must be defined by all
124 /* Characters which always start a comment. */
125 const char comment_chars
[] = "#;";
127 /* Characters which start a comment at the beginning of a line. */
128 const char line_comment_chars
[] = "#";
130 /* Characters which may be used to separate multiple commands on a
132 const char line_separator_chars
[] = "`";
134 /* Characters which are used to indicate an exponent in a floating
136 const char EXP_CHARS
[] = "eE";
138 /* Chars that mean this number is a floating point constant
139 As in 0f12.456 or 0d1.2345e12. */
140 const char FLT_CHARS
[] = "rRsSfFdD";
143 extern int target_big_endian
;
144 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
145 static int byte_order
= DEFAULT_BYTE_ORDER
;
147 /* Arc extension section. */
148 static segT arcext_section
;
150 /* By default relaxation is disabled. */
151 static int relaxation_state
= 0;
153 extern int arc_get_mach (char *);
155 /* Forward declarations. */
156 static void arc_lcomm (int);
157 static void arc_option (int);
158 static void arc_extra_reloc (int);
159 static void arc_extinsn (int);
160 static void arc_extcorereg (int);
161 static void arc_attribute (int);
163 const pseudo_typeS md_pseudo_table
[] =
165 /* Make sure that .word is 32 bits. */
168 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
169 { "lcomm", arc_lcomm
, 0 },
170 { "lcommon", arc_lcomm
, 0 },
171 { "cpu", arc_option
, 0 },
173 { "arc_attribute", arc_attribute
, 0 },
174 { "extinstruction", arc_extinsn
, 0 },
175 { "extcoreregister", arc_extcorereg
, EXT_CORE_REGISTER
},
176 { "extauxregister", arc_extcorereg
, EXT_AUX_REGISTER
},
177 { "extcondcode", arc_extcorereg
, EXT_COND_CODE
},
179 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
180 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
185 const char *md_shortopts
= "";
189 OPTION_EB
= OPTION_MD_BASE
,
207 /* The following options are deprecated and provided here only for
208 compatibility reasons. */
231 struct option md_longopts
[] =
233 { "EB", no_argument
, NULL
, OPTION_EB
},
234 { "EL", no_argument
, NULL
, OPTION_EL
},
235 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
236 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
237 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
238 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
239 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
240 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
241 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
242 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
243 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
244 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
245 { "mnps400", no_argument
, NULL
, OPTION_NPS400
},
247 /* Floating point options */
248 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
249 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
250 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
251 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
252 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
253 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
254 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
255 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
256 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
257 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
258 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
260 /* The following options are deprecated and provided here only for
261 compatibility reasons. */
262 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
263 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
264 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
265 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
266 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
267 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
268 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
269 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
270 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
271 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
272 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
273 { "mea", no_argument
, NULL
, OPTION_EA
},
274 { "mEA", no_argument
, NULL
, OPTION_EA
},
275 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
276 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
277 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
278 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
279 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
280 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
281 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
282 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
283 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
284 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
285 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
286 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
287 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
288 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
289 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
291 { NULL
, no_argument
, NULL
, 0 }
294 size_t md_longopts_size
= sizeof (md_longopts
);
296 /* Local data and data types. */
298 /* Used since new relocation types are introduced in this
299 file (DUMMY_RELOC_LITUSE_*). */
300 typedef int extended_bfd_reloc_code_real_type
;
306 extended_bfd_reloc_code_real_type reloc
;
308 /* index into arc_operands. */
309 unsigned int opindex
;
311 /* PC-relative, used by internals fixups. */
314 /* TRUE if this fixup is for LIMM operand. */
320 unsigned long long int insn
;
322 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
324 unsigned int len
; /* Length of instruction in bytes. */
325 bfd_boolean has_limm
; /* Boolean value: TRUE if limm field is
327 bfd_boolean relax
; /* Boolean value: TRUE if needs
331 /* Structure to hold any last two instructions. */
332 static struct arc_last_insn
334 /* Saved instruction opcode. */
335 const struct arc_opcode
*opcode
;
337 /* Boolean value: TRUE if current insn is short. */
338 bfd_boolean has_limm
;
340 /* Boolean value: TRUE if current insn has delay slot. */
341 bfd_boolean has_delay_slot
;
344 /* Extension instruction suffix classes. */
352 static const attributes_t suffixclass
[] =
354 { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG
},
355 { "SUFFIX_COND", 11, ARC_SUFFIX_COND
},
356 { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE
}
359 /* Extension instruction syntax classes. */
360 static const attributes_t syntaxclass
[] =
362 { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP
},
363 { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP
},
364 { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP
},
365 { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP
}
368 /* Extension instruction syntax classes modifiers. */
369 static const attributes_t syntaxclassmod
[] =
371 { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED
},
372 { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM
}
375 /* Extension register type. */
383 /* A structure to hold the additional conditional codes. */
386 struct arc_flag_operand
*arc_ext_condcode
;
388 } ext_condcode
= { NULL
, 0 };
390 /* Structure to hold an entry in ARC_OPCODE_HASH. */
391 struct arc_opcode_hash_entry
393 /* The number of pointers in the OPCODE list. */
396 /* Points to a list of opcode pointers. */
397 const struct arc_opcode
**opcode
;
400 /* Structure used for iterating through an arc_opcode_hash_entry. */
401 struct arc_opcode_hash_entry_iterator
403 /* Index into the OPCODE element of the arc_opcode_hash_entry. */
406 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
407 returned by this iterator. */
408 const struct arc_opcode
*opcode
;
411 /* Forward declaration. */
412 static void assemble_insn
413 (const struct arc_opcode
*, const expressionS
*, int,
414 const struct arc_flags
*, int, struct arc_insn
*);
416 /* The selection of the machine type can come from different sources. This
417 enum is used to track how the selection was made in order to perform
419 enum mach_selection_type
422 MACH_SELECTION_FROM_DEFAULT
,
423 MACH_SELECTION_FROM_CPU_DIRECTIVE
,
424 MACH_SELECTION_FROM_COMMAND_LINE
427 /* How the current machine type was selected. */
428 static enum mach_selection_type mach_selection_mode
= MACH_SELECTION_NONE
;
430 /* The hash table of instruction opcodes. */
431 static struct hash_control
*arc_opcode_hash
;
433 /* The hash table of register symbols. */
434 static struct hash_control
*arc_reg_hash
;
436 /* The hash table of aux register symbols. */
437 static struct hash_control
*arc_aux_hash
;
439 /* The hash table of address types. */
440 static struct hash_control
*arc_addrtype_hash
;
442 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \
443 { #NAME, ARC_OPCODE_ARC600, bfd_mach_arc_arc600, \
444 E_ARC_MACH_ARC600, EXTRA}
445 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \
446 { #NAME, ARC_OPCODE_ARC700, bfd_mach_arc_arc700, \
447 E_ARC_MACH_ARC700, EXTRA}
448 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \
449 { #NAME, ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2, \
450 EF_ARC_CPU_ARCV2EM, EXTRA}
451 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \
452 { #NAME, ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2, \
453 EF_ARC_CPU_ARCV2HS, EXTRA}
454 #define ARC_CPU_TYPE_NONE \
457 /* A table of CPU names and opcode sets. */
458 static const struct cpu_type
468 #include "elf/arc-cpu.def"
471 /* Information about the cpu/variant we're assembling for. */
472 static struct cpu_type selected_cpu
= { 0, 0, 0, E_ARC_OSABI_CURRENT
, 0 };
474 /* TRUE if current assembly code uses RF16 only registers. */
475 static bfd_boolean rf16_only
= TRUE
;
478 static unsigned mpy_option
= 0;
481 static unsigned pic_option
= 0;
483 /* Use small data. */
484 static unsigned sda_option
= 0;
487 static unsigned tls_option
= 0;
489 /* Command line given features. */
490 static unsigned cl_features
= 0;
492 /* Used by the arc_reloc_op table. Order is important. */
493 #define O_gotoff O_md1 /* @gotoff relocation. */
494 #define O_gotpc O_md2 /* @gotpc relocation. */
495 #define O_plt O_md3 /* @plt relocation. */
496 #define O_sda O_md4 /* @sda relocation. */
497 #define O_pcl O_md5 /* @pcl relocation. */
498 #define O_tlsgd O_md6 /* @tlsgd relocation. */
499 #define O_tlsie O_md7 /* @tlsie relocation. */
500 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
501 #define O_tpoff O_md9 /* @tpoff relocation. */
502 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
503 #define O_dtpoff O_md11 /* @dtpoff relocation. */
504 #define O_last O_dtpoff
506 /* Used to define a bracket as operand in tokens. */
507 #define O_bracket O_md32
509 /* Used to define a colon as an operand in tokens. */
510 #define O_colon O_md31
512 /* Used to define address types in nps400. */
513 #define O_addrtype O_md30
515 /* Dummy relocation, to be sorted out. */
516 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
518 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
520 /* A table to map the spelling of a relocation operand into an appropriate
521 bfd_reloc_code_real_type type. The table is assumed to be ordered such
522 that op-O_literal indexes into it. */
523 #define ARC_RELOC_TABLE(op) \
524 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
526 : (int) (op) - (int) O_gotoff) ])
528 #define DEF(NAME, RELOC, REQ) \
529 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
531 static const struct arc_reloc_op_tag
533 /* String to lookup. */
535 /* Size of the string. */
537 /* Which operator to use. */
539 extended_bfd_reloc_code_real_type reloc
;
540 /* Allows complex relocation expression like identifier@reloc +
542 unsigned int complex_expr
: 1;
546 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
547 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
548 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
549 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
550 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
551 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
552 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
553 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
554 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
555 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
556 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 1),
559 static const int arc_num_reloc_op
560 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
562 /* Structure for relaxable instruction that have to be swapped with a
563 smaller alternative instruction. */
564 struct arc_relaxable_ins
566 /* Mnemonic that should be checked. */
567 const char *mnemonic_r
;
569 /* Operands that should be checked.
570 Indexes of operands from operand array. */
571 enum rlx_operand_type operands
[6];
573 /* Flags that should be checked. */
574 unsigned flag_classes
[5];
576 /* Mnemonic (smaller) alternative to be used later for relaxation. */
577 const char *mnemonic_alt
;
579 /* Index of operand that generic relaxation has to check. */
582 /* Base subtype index used. */
583 enum arc_rlx_types subtype
;
586 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
587 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
588 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
592 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
593 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
594 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
599 /* ARC relaxation table. */
600 const relax_typeS md_relax_table
[] =
607 RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL
),
608 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE
),
612 RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B
),
613 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE
),
618 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6
),
619 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM
),
620 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
622 /* LD_S a, [b, u7] ->
623 LD<zz><.x><.aa><.di> a, [b, s9] ->
624 LD<zz><.x><.aa><.di> a, [b, limm] */
625 RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9
),
626 RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM
),
627 RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE
),
632 RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12
),
633 RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM
),
634 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
638 SUB<.f> a, b, limm. */
639 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6
),
640 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM
),
641 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
643 /* MPY<.f> a, b, u6 ->
644 MPY<.f> a, b, limm. */
645 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM
),
646 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
648 /* MOV<.f><.cc> b, u6 ->
649 MOV<.f><.cc> b, limm. */
650 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM
),
651 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
653 /* ADD<.f><.cc> b, b, u6 ->
654 ADD<.f><.cc> b, b, limm. */
655 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM
),
656 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
659 /* Order of this table's entries matters! */
660 const struct arc_relaxable_ins arc_relaxable_insns
[] =
662 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
663 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
664 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
665 2, ARC_RLX_ADD_RRU6
},
666 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
668 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
670 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
671 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
672 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
673 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
674 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
675 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
676 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
677 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
679 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
681 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
685 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
687 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
688 symbolS
* GOT_symbol
= 0;
690 /* Set to TRUE when we assemble instructions. */
691 static bfd_boolean assembling_insn
= FALSE
;
693 /* List with attributes set explicitly. */
694 static bfd_boolean attributes_set_explicitly
[NUM_KNOWN_OBJ_ATTRIBUTES
];
696 /* Functions implementation. */
698 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
699 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
700 are no matching entries in ARC_OPCODE_HASH. */
702 static const struct arc_opcode_hash_entry
*
703 arc_find_opcode (const char *name
)
705 const struct arc_opcode_hash_entry
*entry
;
707 entry
= hash_find (arc_opcode_hash
, name
);
711 /* Initialise the iterator ITER. */
714 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator
*iter
)
720 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
721 calls to this function. Return NULL when all ARC_OPCODE entries have
724 static const struct arc_opcode
*
725 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry
*entry
,
726 struct arc_opcode_hash_entry_iterator
*iter
)
728 if (iter
->opcode
== NULL
&& iter
->index
== 0)
730 gas_assert (entry
->count
> 0);
731 iter
->opcode
= entry
->opcode
[iter
->index
];
733 else if (iter
->opcode
!= NULL
)
735 const char *old_name
= iter
->opcode
->name
;
738 if (iter
->opcode
->name
== NULL
739 || strcmp (old_name
, iter
->opcode
->name
) != 0)
742 if (iter
->index
== entry
->count
)
745 iter
->opcode
= entry
->opcode
[iter
->index
];
752 /* Insert an opcode into opcode hash structure. */
755 arc_insert_opcode (const struct arc_opcode
*opcode
)
757 const char *name
, *retval
;
758 struct arc_opcode_hash_entry
*entry
;
761 entry
= hash_find (arc_opcode_hash
, name
);
764 entry
= XNEW (struct arc_opcode_hash_entry
);
766 entry
->opcode
= NULL
;
768 retval
= hash_insert (arc_opcode_hash
, name
, (void *) entry
);
770 as_fatal (_("internal error: can't hash opcode '%s': %s"),
774 entry
->opcode
= XRESIZEVEC (const struct arc_opcode
*, entry
->opcode
,
777 if (entry
->opcode
== NULL
)
778 as_fatal (_("Virtual memory exhausted"));
780 entry
->opcode
[entry
->count
] = opcode
;
785 /* Like md_number_to_chars but for middle-endian values. The 4-byte limm
786 value, is encoded as 'middle-endian' for a little-endian target. This
787 function is used for regular 4, 6, and 8 byte instructions as well. */
790 md_number_to_chars_midend (char *buf
, unsigned long long val
, int n
)
795 md_number_to_chars (buf
, val
, n
);
798 md_number_to_chars (buf
, (val
& 0xffff00000000ull
) >> 32, 2);
799 md_number_to_chars_midend (buf
+ 2, (val
& 0xffffffff), 4);
802 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
803 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
806 md_number_to_chars_midend (buf
, (val
& 0xffffffff00000000ull
) >> 32, 4);
807 md_number_to_chars_midend (buf
+ 4, (val
& 0xffffffff), 4);
814 /* Check if a feature is allowed for a specific CPU. */
817 arc_check_feature (void)
821 if (!selected_cpu
.features
822 || !selected_cpu
.name
)
825 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
826 if ((selected_cpu
.features
& feature_list
[i
].feature
)
827 && !(selected_cpu
.flags
& feature_list
[i
].cpus
))
828 as_bad (_("invalid %s option for %s cpu"), feature_list
[i
].name
,
831 for (i
= 0; i
< ARRAY_SIZE (conflict_list
); i
++)
832 if ((selected_cpu
.features
& conflict_list
[i
]) == conflict_list
[i
])
833 as_bad(_("conflicting ISA extension attributes."));
836 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
837 the relevant static global variables. Parameter SEL describes where
838 this selection originated from. */
841 arc_select_cpu (const char *arg
, enum mach_selection_type sel
)
844 static struct cpu_type old_cpu
= { 0, 0, 0, E_ARC_OSABI_CURRENT
, 0 };
846 /* We should only set a default if we've not made a selection from some
848 gas_assert (sel
!= MACH_SELECTION_FROM_DEFAULT
849 || mach_selection_mode
== MACH_SELECTION_NONE
);
851 if ((mach_selection_mode
== MACH_SELECTION_FROM_CPU_DIRECTIVE
)
852 && (sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
))
853 as_bad (_("Multiple .cpu directives found"));
855 /* Look for a matching entry in CPU_TYPES array. */
856 for (i
= 0; cpu_types
[i
].name
; ++i
)
858 if (!strcasecmp (cpu_types
[i
].name
, arg
))
860 /* If a previous selection was made on the command line, then we
861 allow later selections on the command line to override earlier
862 ones. However, a selection from a '.cpu NAME' directive must
863 match the command line selection, or we give a warning. */
864 if (mach_selection_mode
== MACH_SELECTION_FROM_COMMAND_LINE
)
866 gas_assert (sel
== MACH_SELECTION_FROM_COMMAND_LINE
867 || sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
);
868 if (sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
869 && selected_cpu
.mach
!= cpu_types
[i
].mach
)
871 as_warn (_("Command-line value overrides \".cpu\" directive"));
875 /* Initialise static global data about selected machine type. */
876 selected_cpu
.flags
= cpu_types
[i
].flags
;
877 selected_cpu
.name
= cpu_types
[i
].name
;
878 selected_cpu
.features
= cpu_types
[i
].features
| cl_features
;
879 selected_cpu
.mach
= cpu_types
[i
].mach
;
880 selected_cpu
.eflags
= ((selected_cpu
.eflags
& ~EF_ARC_MACH_MSK
)
881 | cpu_types
[i
].eflags
);
886 if (!cpu_types
[i
].name
)
887 as_fatal (_("unknown architecture: %s\n"), arg
);
889 /* Check if set features are compatible with the chosen CPU. */
890 arc_check_feature ();
892 /* If we change the CPU, we need to re-init the bfd. */
893 if (mach_selection_mode
!= MACH_SELECTION_NONE
894 && (old_cpu
.mach
!= selected_cpu
.mach
))
896 bfd_find_target (arc_target_format
, stdoutput
);
897 if (! bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
898 as_warn (_("Could not set architecture and machine"));
901 mach_selection_mode
= sel
;
902 old_cpu
= selected_cpu
;
905 /* Here ends all the ARCompact extension instruction assembling
909 arc_extra_reloc (int r_type
)
912 symbolS
*sym
, *lab
= NULL
;
914 if (*input_line_pointer
== '@')
915 input_line_pointer
++;
916 c
= get_symbol_name (&sym_name
);
917 sym
= symbol_find_or_make (sym_name
);
918 restore_line_pointer (c
);
919 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
921 ++input_line_pointer
;
923 c
= get_symbol_name (&lab_name
);
924 lab
= symbol_find_or_make (lab_name
);
925 restore_line_pointer (c
);
928 /* These relocations exist as a mechanism for the compiler to tell the
929 linker how to patch the code if the tls model is optimised. However,
930 the relocation itself does not require any space within the assembler
931 fragment, and so we pass a size of 0.
933 The lines that generate these relocations look like this:
935 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
937 The '.tls_gd_ld @.tdata' is processed first and generates the
938 additional relocation, while the 'bl __tls_get_addr@plt' is processed
939 second and generates the additional branch.
941 It is possible that the additional relocation generated by the
942 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
943 while the 'bl __tls_get_addr@plt' will be generated as the first thing
944 in the next fragment. This will be fine; both relocations will still
945 appear to be at the same address in the generated object file.
946 However, this only works as the additional relocation is generated
947 with size of 0 bytes. */
949 = fix_new (frag_now
, /* Which frag? */
950 frag_now_fix (), /* Where in that frag? */
951 0, /* size: 1, 2, or 4 usually. */
952 sym
, /* X_add_symbol. */
953 0, /* X_add_number. */
954 FALSE
, /* TRUE if PC-relative relocation. */
955 r_type
/* Relocation type. */);
956 fixP
->fx_subsy
= lab
;
960 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
961 symbolS
*symbolP
, addressT size
)
966 if (*input_line_pointer
== ',')
968 align
= parse_align (1);
970 if (align
== (addressT
) -1)
985 bss_alloc (symbolP
, size
, align
);
986 S_CLEAR_EXTERNAL (symbolP
);
992 arc_lcomm (int ignore
)
994 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
997 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1000 /* Select the cpu we're assembling for. */
1003 arc_option (int ignore ATTRIBUTE_UNUSED
)
1007 const char *cpu_name
;
1009 c
= get_symbol_name (&cpu
);
1012 if ((!strcmp ("ARC600", cpu
))
1013 || (!strcmp ("ARC601", cpu
))
1014 || (!strcmp ("A6", cpu
)))
1015 cpu_name
= "arc600";
1016 else if ((!strcmp ("ARC700", cpu
))
1017 || (!strcmp ("A7", cpu
)))
1018 cpu_name
= "arc700";
1019 else if (!strcmp ("EM", cpu
))
1021 else if (!strcmp ("HS", cpu
))
1023 else if (!strcmp ("NPS400", cpu
))
1024 cpu_name
= "nps400";
1026 arc_select_cpu (cpu_name
, MACH_SELECTION_FROM_CPU_DIRECTIVE
);
1028 restore_line_pointer (c
);
1029 demand_empty_rest_of_line ();
1032 /* Smartly print an expression. */
1035 debug_exp (expressionS
*t
)
1037 const char *name ATTRIBUTE_UNUSED
;
1038 const char *namemd ATTRIBUTE_UNUSED
;
1040 pr_debug ("debug_exp: ");
1044 default: name
= "unknown"; break;
1045 case O_illegal
: name
= "O_illegal"; break;
1046 case O_absent
: name
= "O_absent"; break;
1047 case O_constant
: name
= "O_constant"; break;
1048 case O_symbol
: name
= "O_symbol"; break;
1049 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1050 case O_register
: name
= "O_register"; break;
1051 case O_big
: name
= "O_big"; break;
1052 case O_uminus
: name
= "O_uminus"; break;
1053 case O_bit_not
: name
= "O_bit_not"; break;
1054 case O_logical_not
: name
= "O_logical_not"; break;
1055 case O_multiply
: name
= "O_multiply"; break;
1056 case O_divide
: name
= "O_divide"; break;
1057 case O_modulus
: name
= "O_modulus"; break;
1058 case O_left_shift
: name
= "O_left_shift"; break;
1059 case O_right_shift
: name
= "O_right_shift"; break;
1060 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1061 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1062 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1063 case O_bit_and
: name
= "O_bit_and"; break;
1064 case O_add
: name
= "O_add"; break;
1065 case O_subtract
: name
= "O_subtract"; break;
1066 case O_eq
: name
= "O_eq"; break;
1067 case O_ne
: name
= "O_ne"; break;
1068 case O_lt
: name
= "O_lt"; break;
1069 case O_le
: name
= "O_le"; break;
1070 case O_ge
: name
= "O_ge"; break;
1071 case O_gt
: name
= "O_gt"; break;
1072 case O_logical_and
: name
= "O_logical_and"; break;
1073 case O_logical_or
: name
= "O_logical_or"; break;
1074 case O_index
: name
= "O_index"; break;
1075 case O_bracket
: name
= "O_bracket"; break;
1076 case O_colon
: name
= "O_colon"; break;
1077 case O_addrtype
: name
= "O_addrtype"; break;
1082 default: namemd
= "unknown"; break;
1083 case O_gotoff
: namemd
= "O_gotoff"; break;
1084 case O_gotpc
: namemd
= "O_gotpc"; break;
1085 case O_plt
: namemd
= "O_plt"; break;
1086 case O_sda
: namemd
= "O_sda"; break;
1087 case O_pcl
: namemd
= "O_pcl"; break;
1088 case O_tlsgd
: namemd
= "O_tlsgd"; break;
1089 case O_tlsie
: namemd
= "O_tlsie"; break;
1090 case O_tpoff9
: namemd
= "O_tpoff9"; break;
1091 case O_tpoff
: namemd
= "O_tpoff"; break;
1092 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
1093 case O_dtpoff
: namemd
= "O_dtpoff"; break;
1096 pr_debug ("%s (%s, %s, %d, %s)", name
,
1097 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1098 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1099 (int) t
->X_add_number
,
1100 (t
->X_md
) ? namemd
: "--");
1105 /* Helper for parsing an argument, used for sorting out the relocation
1109 parse_reloc_symbol (expressionS
*resultP
)
1111 char *reloc_name
, c
, *sym_name
;
1114 const struct arc_reloc_op_tag
*r
;
1118 /* A relocation operand has the following form
1119 @identifier@relocation_type. The identifier is already in
1121 if (resultP
->X_op
!= O_symbol
)
1123 as_bad (_("No valid label relocation operand"));
1124 resultP
->X_op
= O_illegal
;
1128 /* Parse @relocation_type. */
1129 input_line_pointer
++;
1130 c
= get_symbol_name (&reloc_name
);
1131 len
= input_line_pointer
- reloc_name
;
1134 as_bad (_("No relocation operand"));
1135 resultP
->X_op
= O_illegal
;
1139 /* Go through known relocation and try to find a match. */
1140 r
= &arc_reloc_op
[0];
1141 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1142 if (len
== r
->length
1143 && memcmp (reloc_name
, r
->name
, len
) == 0)
1147 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
1148 resultP
->X_op
= O_illegal
;
1152 *input_line_pointer
= c
;
1153 SKIP_WHITESPACE_AFTER_NAME ();
1154 /* Extra check for TLS: base. */
1155 if (*input_line_pointer
== '@')
1157 if (resultP
->X_op_symbol
!= NULL
1158 || resultP
->X_op
!= O_symbol
)
1160 as_bad (_("Unable to parse TLS base: %s"),
1161 input_line_pointer
);
1162 resultP
->X_op
= O_illegal
;
1165 input_line_pointer
++;
1166 c
= get_symbol_name (&sym_name
);
1167 base
= symbol_find_or_make (sym_name
);
1168 resultP
->X_op
= O_subtract
;
1169 resultP
->X_op_symbol
= base
;
1170 restore_line_pointer (c
);
1171 right
.X_add_number
= 0;
1174 if ((*input_line_pointer
!= '+')
1175 && (*input_line_pointer
!= '-'))
1176 right
.X_add_number
= 0;
1179 /* Parse the constant of a complex relocation expression
1180 like @identifier@reloc +/- const. */
1181 if (! r
->complex_expr
)
1183 as_bad (_("@%s is not a complex relocation."), r
->name
);
1184 resultP
->X_op
= O_illegal
;
1187 expression (&right
);
1188 if (right
.X_op
!= O_constant
)
1190 as_bad (_("Bad expression: @%s + %s."),
1191 r
->name
, input_line_pointer
);
1192 resultP
->X_op
= O_illegal
;
1197 resultP
->X_md
= r
->op
;
1198 resultP
->X_add_number
= right
.X_add_number
;
1201 /* Parse the arguments to an opcode. */
1204 tokenize_arguments (char *str
,
1208 char *old_input_line_pointer
;
1209 bfd_boolean saw_comma
= FALSE
;
1210 bfd_boolean saw_arg
= FALSE
;
1214 memset (tok
, 0, sizeof (*tok
) * ntok
);
1216 /* Save and restore input_line_pointer around this function. */
1217 old_input_line_pointer
= input_line_pointer
;
1218 input_line_pointer
= str
;
1220 while (*input_line_pointer
)
1223 switch (*input_line_pointer
)
1229 input_line_pointer
++;
1230 if (saw_comma
|| !saw_arg
)
1237 ++input_line_pointer
;
1239 if (!saw_arg
|| num_args
== ntok
)
1241 tok
->X_op
= O_bracket
;
1248 input_line_pointer
++;
1249 if (brk_lvl
|| num_args
== ntok
)
1252 tok
->X_op
= O_bracket
;
1258 input_line_pointer
++;
1259 if (!saw_arg
|| num_args
== ntok
)
1261 tok
->X_op
= O_colon
;
1268 /* We have labels, function names and relocations, all
1269 starting with @ symbol. Sort them out. */
1270 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1274 input_line_pointer
++;
1275 tok
->X_op
= O_symbol
;
1276 tok
->X_md
= O_absent
;
1279 if (*input_line_pointer
== '@')
1280 parse_reloc_symbol (tok
);
1284 if (tok
->X_op
== O_illegal
1285 || tok
->X_op
== O_absent
1286 || num_args
== ntok
)
1296 /* Can be a register. */
1297 ++input_line_pointer
;
1301 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1304 tok
->X_op
= O_absent
;
1305 tok
->X_md
= O_absent
;
1308 /* Legacy: There are cases when we have
1309 identifier@relocation_type, if it is the case parse the
1310 relocation type as well. */
1311 if (*input_line_pointer
== '@')
1312 parse_reloc_symbol (tok
);
1316 if (tok
->X_op
== O_illegal
1317 || tok
->X_op
== O_absent
1318 || num_args
== ntok
)
1330 if (saw_comma
|| brk_lvl
)
1332 input_line_pointer
= old_input_line_pointer
;
1338 as_bad (_("Brackets in operand field incorrect"));
1340 as_bad (_("extra comma"));
1342 as_bad (_("missing argument"));
1344 as_bad (_("missing comma or colon"));
1345 input_line_pointer
= old_input_line_pointer
;
1349 /* Parse the flags to a structure. */
1352 tokenize_flags (const char *str
,
1353 struct arc_flags flags
[],
1356 char *old_input_line_pointer
;
1357 bfd_boolean saw_flg
= FALSE
;
1358 bfd_boolean saw_dot
= FALSE
;
1362 memset (flags
, 0, sizeof (*flags
) * nflg
);
1364 /* Save and restore input_line_pointer around this function. */
1365 old_input_line_pointer
= input_line_pointer
;
1366 input_line_pointer
= (char *) str
;
1368 while (*input_line_pointer
)
1370 switch (*input_line_pointer
)
1377 input_line_pointer
++;
1385 if (saw_flg
&& !saw_dot
)
1388 if (num_flags
>= nflg
)
1391 flgnamelen
= strspn (input_line_pointer
,
1392 "abcdefghijklmnopqrstuvwxyz0123456789");
1393 if (flgnamelen
> MAX_FLAG_NAME_LENGTH
)
1396 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1398 input_line_pointer
+= flgnamelen
;
1408 input_line_pointer
= old_input_line_pointer
;
1413 as_bad (_("extra dot"));
1415 as_bad (_("unrecognized flag"));
1417 as_bad (_("failed to parse flags"));
1418 input_line_pointer
= old_input_line_pointer
;
1422 /* Apply the fixups in order. */
1425 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1429 for (i
= 0; i
< insn
->nfixups
; i
++)
1431 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1432 int size
, pcrel
, offset
= 0;
1434 /* FIXME! the reloc size is wrong in the BFD file.
1435 When it is fixed please delete me. */
1436 size
= ((insn
->len
== 2) && !fixup
->islong
) ? 2 : 4;
1441 /* Some fixups are only used internally, thus no howto. */
1442 if ((int) fixup
->reloc
== 0)
1443 as_fatal (_("Unhandled reloc type"));
1445 if ((int) fixup
->reloc
< 0)
1447 /* FIXME! the reloc size is wrong in the BFD file.
1448 When it is fixed please enable me.
1449 size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
1450 pcrel
= fixup
->pcrel
;
1454 reloc_howto_type
*reloc_howto
=
1455 bfd_reloc_type_lookup (stdoutput
,
1456 (bfd_reloc_code_real_type
) fixup
->reloc
);
1457 gas_assert (reloc_howto
);
1459 /* FIXME! the reloc size is wrong in the BFD file.
1460 When it is fixed please enable me.
1461 size = bfd_get_reloc_size (reloc_howto); */
1462 pcrel
= reloc_howto
->pc_relative
;
1465 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1467 fragP
->fr_file
, fragP
->fr_line
,
1468 (fixup
->reloc
< 0) ? "Internal" :
1469 bfd_get_reloc_code_name (fixup
->reloc
),
1472 fix_new_exp (fragP
, fix
+ offset
,
1473 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1475 /* Check for ZOLs, and update symbol info if any. */
1476 if (LP_INSN (insn
->insn
))
1478 gas_assert (fixup
->exp
.X_add_symbol
);
1479 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1484 /* Actually output an instruction with its fixup. */
1487 emit_insn0 (struct arc_insn
*insn
, char *where
, bfd_boolean relax
)
1492 pr_debug ("Emit insn : 0x%llx\n", insn
->insn
);
1493 pr_debug ("\tLength : 0x%d\n", insn
->len
);
1494 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1496 /* Write out the instruction. */
1497 total_len
= insn
->len
+ (insn
->has_limm
? 4 : 0);
1499 f
= frag_more (total_len
);
1501 md_number_to_chars_midend(f
, insn
->insn
, insn
->len
);
1504 md_number_to_chars_midend (f
+ insn
->len
, insn
->limm
, 4);
1505 dwarf2_emit_insn (total_len
);
1508 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1512 emit_insn1 (struct arc_insn
*insn
)
1514 /* How frag_var's args are currently configured:
1515 - rs_machine_dependent, to dictate it's a relaxation frag.
1516 - FRAG_MAX_GROWTH, maximum size of instruction
1517 - 0, variable size that might grow...unused by generic relaxation.
1518 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1519 - s, opand expression.
1520 - 0, offset but it's unused.
1521 - 0, opcode but it's unused. */
1522 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1523 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1525 if (frag_room () < FRAG_MAX_GROWTH
)
1527 /* Handle differently when frag literal memory is exhausted.
1528 This is used because when there's not enough memory left in
1529 the current frag, a new frag is created and the information
1530 we put into frag_now->tc_frag_data is disregarded. */
1532 struct arc_relax_type relax_info_copy
;
1533 relax_substateT subtype
= frag_now
->fr_subtype
;
1535 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1536 sizeof (struct arc_relax_type
));
1538 frag_wane (frag_now
);
1539 frag_grow (FRAG_MAX_GROWTH
);
1541 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1542 sizeof (struct arc_relax_type
));
1544 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1548 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1549 frag_now
->fr_subtype
, s
, 0, 0);
1553 emit_insn (struct arc_insn
*insn
)
1558 emit_insn0 (insn
, NULL
, FALSE
);
1561 /* Check whether a symbol involves a register. */
1564 contains_register (symbolS
*sym
)
1568 expressionS
*ex
= symbol_get_value_expression (sym
);
1570 return ((O_register
== ex
->X_op
)
1571 && !contains_register (ex
->X_add_symbol
)
1572 && !contains_register (ex
->X_op_symbol
));
1578 /* Returns the register number within a symbol. */
1581 get_register (symbolS
*sym
)
1583 if (!contains_register (sym
))
1586 expressionS
*ex
= symbol_get_value_expression (sym
);
1587 return regno (ex
->X_add_number
);
1590 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1591 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1594 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1601 case BFD_RELOC_ARC_SDA_LDST
:
1602 case BFD_RELOC_ARC_SDA_LDST1
:
1603 case BFD_RELOC_ARC_SDA_LDST2
:
1604 case BFD_RELOC_ARC_SDA16_LD
:
1605 case BFD_RELOC_ARC_SDA16_LD1
:
1606 case BFD_RELOC_ARC_SDA16_LD2
:
1607 case BFD_RELOC_ARC_SDA16_ST2
:
1608 case BFD_RELOC_ARC_SDA32_ME
:
1615 /* Allocates a tok entry. */
1618 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1620 if (ntok
> MAX_INSN_ARGS
- 2)
1621 return 0; /* No space left. */
1624 return 0; /* Incorrect args. */
1626 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1629 return 1; /* Success. */
1630 return allocate_tok (tok
, ntok
- 1, cidx
);
1633 /* Check if an particular ARC feature is enabled. */
1636 check_cpu_feature (insn_subclass_t sc
)
1638 if (is_code_density_p (sc
) && !(selected_cpu
.features
& CD
))
1641 if (is_spfp_p (sc
) && !(selected_cpu
.features
& SPX
))
1644 if (is_dpfp_p (sc
) && !(selected_cpu
.features
& DPX
))
1647 if (is_fpuda_p (sc
) && !(selected_cpu
.features
& DPA
))
1650 if (is_nps400_p (sc
) && !(selected_cpu
.features
& NPS400
))
1656 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1657 operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG
1658 array and returns TRUE if the flag operands all match, otherwise,
1659 returns FALSE, in which case the FIRST_PFLAG array may have been
1663 parse_opcode_flags (const struct arc_opcode
*opcode
,
1665 struct arc_flags
*first_pflag
)
1668 const unsigned char *flgidx
;
1671 for (i
= 0; i
< nflgs
; i
++)
1672 first_pflag
[i
].flgp
= NULL
;
1674 /* Check the flags. Iterate over the valid flag classes. */
1675 for (flgidx
= opcode
->flags
; *flgidx
; ++flgidx
)
1677 /* Get a valid flag class. */
1678 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1679 const unsigned *flgopridx
;
1681 struct arc_flags
*pflag
= NULL
;
1683 /* Check if opcode has implicit flag classes. */
1684 if (cl_flags
->flag_class
& F_CLASS_IMPLICIT
)
1687 /* Check for extension conditional codes. */
1688 if (ext_condcode
.arc_ext_condcode
1689 && cl_flags
->flag_class
& F_CLASS_EXTEND
)
1691 struct arc_flag_operand
*pf
= ext_condcode
.arc_ext_condcode
;
1694 pflag
= first_pflag
;
1695 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1697 if (!strcmp (pf
->name
, pflag
->name
))
1699 if (pflag
->flgp
!= NULL
)
1712 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1714 const struct arc_flag_operand
*flg_operand
;
1716 pflag
= first_pflag
;
1717 flg_operand
= &arc_flag_operands
[*flgopridx
];
1718 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1720 /* Match against the parsed flags. */
1721 if (!strcmp (flg_operand
->name
, pflag
->name
))
1723 if (pflag
->flgp
!= NULL
)
1726 pflag
->flgp
= flg_operand
;
1728 break; /* goto next flag class and parsed flag. */
1733 if ((cl_flags
->flag_class
& F_CLASS_REQUIRED
) && cl_matches
== 0)
1735 if ((cl_flags
->flag_class
& F_CLASS_OPTIONAL
) && cl_matches
> 1)
1739 /* Did I check all the parsed flags? */
1740 return lnflg
? FALSE
: TRUE
;
1744 /* Search forward through all variants of an opcode looking for a
1747 static const struct arc_opcode
*
1748 find_opcode_match (const struct arc_opcode_hash_entry
*entry
,
1751 struct arc_flags
*first_pflag
,
1754 const char **errmsg
)
1756 const struct arc_opcode
*opcode
;
1757 struct arc_opcode_hash_entry_iterator iter
;
1759 int got_cpu_match
= 0;
1760 expressionS bktok
[MAX_INSN_ARGS
];
1761 int bkntok
, maxerridx
= 0;
1763 const char *tmpmsg
= NULL
;
1765 arc_opcode_hash_entry_iterator_init (&iter
);
1766 memset (&emptyE
, 0, sizeof (emptyE
));
1767 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1770 for (opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
);
1772 opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
))
1774 const unsigned char *opidx
;
1776 const expressionS
*t
= &emptyE
;
1778 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
1779 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1781 /* Don't match opcodes that don't exist on this
1783 if (!(opcode
->cpu
& selected_cpu
.flags
))
1786 if (!check_cpu_feature (opcode
->subclass
))
1792 /* Check the operands. */
1793 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1795 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1797 /* Only take input from real operands. */
1798 if (ARC_OPERAND_IS_FAKE (operand
))
1801 /* When we expect input, make sure we have it. */
1805 /* Match operand type with expression type. */
1806 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1808 case ARC_OPERAND_ADDRTYPE
:
1812 /* Check to be an address type. */
1813 if (tok
[tokidx
].X_op
!= O_addrtype
)
1816 /* All address type operands need to have an insert
1817 method in order to check that we have the correct
1819 gas_assert (operand
->insert
!= NULL
);
1820 (*operand
->insert
) (0, tok
[tokidx
].X_add_number
,
1827 case ARC_OPERAND_IR
:
1828 /* Check to be a register. */
1829 if ((tok
[tokidx
].X_op
!= O_register
1830 || !is_ir_num (tok
[tokidx
].X_add_number
))
1831 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1834 /* If expect duplicate, make sure it is duplicate. */
1835 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1837 /* Check for duplicate. */
1838 if (t
->X_op
!= O_register
1839 || !is_ir_num (t
->X_add_number
)
1840 || (regno (t
->X_add_number
) !=
1841 regno (tok
[tokidx
].X_add_number
)))
1845 /* Special handling? */
1846 if (operand
->insert
)
1849 (*operand
->insert
)(0,
1850 regno (tok
[tokidx
].X_add_number
),
1854 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1856 /* Missing argument, create one. */
1857 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1860 tok
[tokidx
].X_op
= O_absent
;
1871 case ARC_OPERAND_BRAKET
:
1872 /* Check if bracket is also in opcode table as
1874 if (tok
[tokidx
].X_op
!= O_bracket
)
1878 case ARC_OPERAND_COLON
:
1879 /* Check if colon is also in opcode table as operand. */
1880 if (tok
[tokidx
].X_op
!= O_colon
)
1884 case ARC_OPERAND_LIMM
:
1885 case ARC_OPERAND_SIGNED
:
1886 case ARC_OPERAND_UNSIGNED
:
1887 switch (tok
[tokidx
].X_op
)
1895 /* Got an (too) early bracket, check if it is an
1896 ignored operand. N.B. This procedure works only
1897 when bracket is the last operand! */
1898 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1900 /* Insert the missing operand. */
1901 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1904 tok
[tokidx
].X_op
= O_absent
;
1912 const struct arc_aux_reg
*auxr
;
1914 if (opcode
->insn_class
!= AUXREG
)
1916 p
= S_GET_NAME (tok
[tokidx
].X_add_symbol
);
1918 /* For compatibility reasons, an aux register can
1919 be spelled with upper or lower case
1922 for (pp
= tmpp
; *pp
; ++pp
) *pp
= TOLOWER (*pp
);
1924 auxr
= hash_find (arc_aux_hash
, tmpp
);
1927 /* We modify the token array here, safe in the
1928 knowledge, that if this was the wrong
1929 choice then the original contents will be
1930 restored from BKTOK. */
1931 tok
[tokidx
].X_op
= O_constant
;
1932 tok
[tokidx
].X_add_number
= auxr
->address
;
1933 ARC_SET_FLAG (tok
[tokidx
].X_add_symbol
, ARC_FLAG_AUX
);
1937 if (tok
[tokidx
].X_op
!= O_constant
)
1942 /* Check the range. */
1943 if (operand
->bits
!= 32
1944 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1946 offsetT min
, max
, val
;
1947 val
= tok
[tokidx
].X_add_number
;
1949 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1951 max
= (1 << (operand
->bits
- 1)) - 1;
1952 min
= -(1 << (operand
->bits
- 1));
1956 max
= (1 << operand
->bits
) - 1;
1960 if (val
< min
|| val
> max
)
1962 tmpmsg
= _("immediate is out of bounds");
1966 /* Check alignments. */
1967 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1970 tmpmsg
= _("immediate is not 32bit aligned");
1974 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1977 tmpmsg
= _("immediate is not 16bit aligned");
1981 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1983 if (operand
->insert
)
1986 (*operand
->insert
)(0,
1987 tok
[tokidx
].X_add_number
,
1992 else if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1998 /* Check if it is register range. */
1999 if ((tok
[tokidx
].X_add_number
== 0)
2000 && contains_register (tok
[tokidx
].X_add_symbol
)
2001 && contains_register (tok
[tokidx
].X_op_symbol
))
2005 regs
= get_register (tok
[tokidx
].X_add_symbol
);
2007 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
2008 if (operand
->insert
)
2011 (*operand
->insert
)(0,
2024 if (operand
->default_reloc
== 0)
2025 goto match_failed
; /* The operand needs relocation. */
2027 /* Relocs requiring long immediate. FIXME! make it
2028 generic and move it to a function. */
2029 switch (tok
[tokidx
].X_md
)
2038 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
2042 if (!generic_reloc_p (operand
->default_reloc
))
2050 /* If expect duplicate, make sure it is duplicate. */
2051 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
2053 if (t
->X_op
== O_illegal
2054 || t
->X_op
== O_absent
2055 || t
->X_op
== O_register
2056 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
2058 tmpmsg
= _("operand is not duplicate of the "
2067 /* Everything else should have been fake. */
2075 /* Setup ready for flag parsing. */
2076 if (!parse_opcode_flags (opcode
, nflgs
, first_pflag
))
2078 tmpmsg
= _("flag mismatch");
2083 /* Possible match -- did we use all of our input? */
2090 tmpmsg
= _("too many arguments");
2094 /* Restore the original parameters. */
2095 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
2097 if (tokidx
>= maxerridx
2106 *pcpumatch
= got_cpu_match
;
2111 /* Swap operand tokens. */
2114 swap_operand (expressionS
*operand_array
,
2116 unsigned destination
)
2118 expressionS cpy_operand
;
2119 expressionS
*src_operand
;
2120 expressionS
*dst_operand
;
2123 if (source
== destination
)
2126 src_operand
= &operand_array
[source
];
2127 dst_operand
= &operand_array
[destination
];
2128 size
= sizeof (expressionS
);
2130 /* Make copy of operand to swap with and swap. */
2131 memcpy (&cpy_operand
, dst_operand
, size
);
2132 memcpy (dst_operand
, src_operand
, size
);
2133 memcpy (src_operand
, &cpy_operand
, size
);
2136 /* Check if *op matches *tok type.
2137 Returns FALSE if they don't match, TRUE if they match. */
2140 pseudo_operand_match (const expressionS
*tok
,
2141 const struct arc_operand_operation
*op
)
2143 offsetT min
, max
, val
;
2145 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
2151 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
2153 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
2155 val
= tok
->X_add_number
+ op
->count
;
2156 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
2158 max
= (1 << (operand_real
->bits
- 1)) - 1;
2159 min
= -(1 << (operand_real
->bits
- 1));
2163 max
= (1 << operand_real
->bits
) - 1;
2166 if (min
<= val
&& val
<= max
)
2172 /* Handle all symbols as long immediates or signed 9. */
2173 if (operand_real
->flags
& ARC_OPERAND_LIMM
2174 || ((operand_real
->flags
& ARC_OPERAND_SIGNED
)
2175 && operand_real
->bits
== 9))
2180 if (operand_real
->flags
& ARC_OPERAND_IR
)
2185 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2196 /* Find pseudo instruction in array. */
2198 static const struct arc_pseudo_insn
*
2199 find_pseudo_insn (const char *opname
,
2201 const expressionS
*tok
)
2203 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2204 const struct arc_operand_operation
*op
;
2208 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
2210 pseudo_insn
= &arc_pseudo_insns
[i
];
2211 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
2213 op
= pseudo_insn
->operand
;
2214 for (j
= 0; j
< ntok
; ++j
)
2215 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
2218 /* Found the right instruction. */
2226 /* Assumes the expressionS *tok is of sufficient size. */
2228 static const struct arc_opcode_hash_entry
*
2229 find_special_case_pseudo (const char *opname
,
2233 struct arc_flags
*pflags
)
2235 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2236 const struct arc_operand_operation
*operand_pseudo
;
2237 const struct arc_operand
*operand_real
;
2239 char construct_operand
[MAX_CONSTR_STR
];
2241 /* Find whether opname is in pseudo instruction array. */
2242 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
2244 if (pseudo_insn
== NULL
)
2247 /* Handle flag, Limited to one flag at the moment. */
2248 if (pseudo_insn
->flag_r
!= NULL
)
2249 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
2250 MAX_INSN_FLGS
- *nflgs
);
2252 /* Handle operand operations. */
2253 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2255 operand_pseudo
= &pseudo_insn
->operand
[i
];
2256 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
2258 if (operand_real
->flags
& ARC_OPERAND_BRAKET
2259 && !operand_pseudo
->needs_insert
)
2262 /* Has to be inserted (i.e. this token does not exist yet). */
2263 if (operand_pseudo
->needs_insert
)
2265 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2267 tok
[i
].X_op
= O_bracket
;
2272 /* Check if operand is a register or constant and handle it
2274 if (operand_real
->flags
& ARC_OPERAND_IR
)
2275 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
2276 operand_pseudo
->count
);
2278 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
2279 operand_pseudo
->count
);
2281 tokenize_arguments (construct_operand
, &tok
[i
], 1);
2285 else if (operand_pseudo
->count
)
2287 /* Operand number has to be adjusted accordingly (by operand
2289 switch (tok
[i
].X_op
)
2292 tok
[i
].X_add_number
+= operand_pseudo
->count
;
2305 /* Swap operands if necessary. Only supports one swap at the
2307 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2309 operand_pseudo
= &pseudo_insn
->operand
[i
];
2311 if (operand_pseudo
->swap_operand_idx
== i
)
2314 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
2316 /* Prevent a swap back later by breaking out. */
2320 return arc_find_opcode (pseudo_insn
->mnemonic_r
);
2323 static const struct arc_opcode_hash_entry
*
2324 find_special_case_flag (const char *opname
,
2326 struct arc_flags
*pflags
)
2330 unsigned flag_idx
, flag_arr_idx
;
2331 size_t flaglen
, oplen
;
2332 const struct arc_flag_special
*arc_flag_special_opcode
;
2333 const struct arc_opcode_hash_entry
*entry
;
2335 /* Search for special case instruction. */
2336 for (i
= 0; i
< arc_num_flag_special
; i
++)
2338 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
2339 oplen
= strlen (arc_flag_special_opcode
->name
);
2341 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
2344 /* Found a potential special case instruction, now test for
2346 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
2348 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
2350 break; /* End of array, nothing found. */
2352 flagnm
= arc_flag_operands
[flag_idx
].name
;
2353 flaglen
= strlen (flagnm
);
2354 if (strcmp (opname
+ oplen
, flagnm
) == 0)
2356 entry
= arc_find_opcode (arc_flag_special_opcode
->name
);
2358 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
2360 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
2361 pflags
[*nflgs
].name
[flaglen
] = '\0';
2370 /* Used to find special case opcode. */
2372 static const struct arc_opcode_hash_entry
*
2373 find_special_case (const char *opname
,
2375 struct arc_flags
*pflags
,
2379 const struct arc_opcode_hash_entry
*entry
;
2381 entry
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
2384 entry
= find_special_case_flag (opname
, nflgs
, pflags
);
2389 /* Autodetect cpu attribute list. */
2392 autodetect_attributes (const struct arc_opcode
*opcode
,
2393 const expressionS
*tok
,
2401 } mpy_list
[] = {{ MPY1E
, 1 }, { MPY6E
, 6 }, { MPY7E
, 7 }, { MPY8E
, 8 },
2404 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
2405 if (opcode
->subclass
== feature_list
[i
].feature
)
2406 selected_cpu
.features
|= feature_list
[i
].feature
;
2408 for (i
= 0; i
< ARRAY_SIZE (mpy_list
); i
++)
2409 if (opcode
->subclass
== mpy_list
[i
].feature
)
2410 mpy_option
= mpy_list
[i
].encoding
;
2412 for (i
= 0; i
< (unsigned) ntok
; i
++)
2414 switch (tok
[i
].X_md
)
2436 switch (tok
[i
].X_op
)
2439 if ((tok
[i
].X_add_number
>= 4 && tok
[i
].X_add_number
<= 9)
2440 || (tok
[i
].X_add_number
>= 16 && tok
[i
].X_add_number
<= 25))
2449 /* Given an opcode name, pre-tockenized set of argumenst and the
2450 opcode flags, take it all the way through emission. */
2453 assemble_tokens (const char *opname
,
2456 struct arc_flags
*pflags
,
2459 bfd_boolean found_something
= FALSE
;
2460 const struct arc_opcode_hash_entry
*entry
;
2462 const char *errmsg
= NULL
;
2464 /* Search opcodes. */
2465 entry
= arc_find_opcode (opname
);
2467 /* Couldn't find opcode conventional way, try special cases. */
2469 entry
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
2473 const struct arc_opcode
*opcode
;
2475 pr_debug ("%s:%d: assemble_tokens: %s\n",
2476 frag_now
->fr_file
, frag_now
->fr_line
, opname
);
2477 found_something
= TRUE
;
2478 opcode
= find_opcode_match (entry
, tok
, &ntok
, pflags
,
2479 nflgs
, &cpumatch
, &errmsg
);
2482 struct arc_insn insn
;
2484 autodetect_attributes (opcode
, tok
, ntok
);
2485 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
2491 if (found_something
)
2495 as_bad (_("%s for instruction '%s'"), errmsg
, opname
);
2497 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
2499 as_bad (_("opcode '%s' not supported for target %s"), opname
,
2503 as_bad (_("unknown opcode '%s'"), opname
);
2506 /* The public interface to the instruction assembler. */
2509 md_assemble (char *str
)
2512 expressionS tok
[MAX_INSN_ARGS
];
2515 struct arc_flags flags
[MAX_INSN_FLGS
];
2517 /* Split off the opcode. */
2518 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
2519 opname
= xmemdup0 (str
, opnamelen
);
2521 /* Signalize we are assembling the instructions. */
2522 assembling_insn
= TRUE
;
2524 /* Tokenize the flags. */
2525 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2527 as_bad (_("syntax error"));
2531 /* Scan up to the end of the mnemonic which must end in space or end
2534 for (; *str
!= '\0'; str
++)
2538 /* Tokenize the rest of the line. */
2539 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2541 as_bad (_("syntax error"));
2545 /* Finish it off. */
2546 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2547 assembling_insn
= FALSE
;
2550 /* Callback to insert a register into the hash table. */
2553 declare_register (const char *name
, int number
)
2556 symbolS
*regS
= symbol_create (name
, reg_section
,
2557 number
, &zero_address_frag
);
2559 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
2561 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2565 /* Construct symbols for each of the general registers. */
2568 declare_register_set (void)
2571 for (i
= 0; i
< 64; ++i
)
2575 sprintf (name
, "r%d", i
);
2576 declare_register (name
, i
);
2577 if ((i
& 0x01) == 0)
2579 sprintf (name
, "r%dr%d", i
, i
+1);
2580 declare_register (name
, i
);
2585 /* Construct a symbol for an address type. */
2588 declare_addrtype (const char *name
, int number
)
2591 symbolS
*addrtypeS
= symbol_create (name
, undefined_section
,
2592 number
, &zero_address_frag
);
2594 err
= hash_insert (arc_addrtype_hash
, S_GET_NAME (addrtypeS
),
2595 (void *) addrtypeS
);
2597 as_fatal (_("Inserting \"%s\" into address type table failed: %s"),
2601 /* Port-specific assembler initialization. This function is called
2602 once, at assembler startup time. */
2607 const struct arc_opcode
*opcode
= arc_opcodes
;
2609 if (mach_selection_mode
== MACH_SELECTION_NONE
)
2610 arc_select_cpu (TARGET_WITH_CPU
, MACH_SELECTION_FROM_DEFAULT
);
2612 /* The endianness can be chosen "at the factory". */
2613 target_big_endian
= byte_order
== BIG_ENDIAN
;
2615 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
2616 as_warn (_("could not set architecture and machine"));
2618 /* Set elf header flags. */
2619 bfd_set_private_flags (stdoutput
, selected_cpu
.eflags
);
2621 /* Set up a hash table for the instructions. */
2622 arc_opcode_hash
= hash_new ();
2623 if (arc_opcode_hash
== NULL
)
2624 as_fatal (_("Virtual memory exhausted"));
2626 /* Initialize the hash table with the insns. */
2629 const char *name
= opcode
->name
;
2631 arc_insert_opcode (opcode
);
2633 while (++opcode
&& opcode
->name
2634 && (opcode
->name
== name
2635 || !strcmp (opcode
->name
, name
)))
2637 }while (opcode
->name
);
2639 /* Register declaration. */
2640 arc_reg_hash
= hash_new ();
2641 if (arc_reg_hash
== NULL
)
2642 as_fatal (_("Virtual memory exhausted"));
2644 declare_register_set ();
2645 declare_register ("gp", 26);
2646 declare_register ("fp", 27);
2647 declare_register ("sp", 28);
2648 declare_register ("ilink", 29);
2649 declare_register ("ilink1", 29);
2650 declare_register ("ilink2", 30);
2651 declare_register ("blink", 31);
2653 /* XY memory registers. */
2654 declare_register ("x0_u0", 32);
2655 declare_register ("x0_u1", 33);
2656 declare_register ("x1_u0", 34);
2657 declare_register ("x1_u1", 35);
2658 declare_register ("x2_u0", 36);
2659 declare_register ("x2_u1", 37);
2660 declare_register ("x3_u0", 38);
2661 declare_register ("x3_u1", 39);
2662 declare_register ("y0_u0", 40);
2663 declare_register ("y0_u1", 41);
2664 declare_register ("y1_u0", 42);
2665 declare_register ("y1_u1", 43);
2666 declare_register ("y2_u0", 44);
2667 declare_register ("y2_u1", 45);
2668 declare_register ("y3_u0", 46);
2669 declare_register ("y3_u1", 47);
2670 declare_register ("x0_nu", 48);
2671 declare_register ("x1_nu", 49);
2672 declare_register ("x2_nu", 50);
2673 declare_register ("x3_nu", 51);
2674 declare_register ("y0_nu", 52);
2675 declare_register ("y1_nu", 53);
2676 declare_register ("y2_nu", 54);
2677 declare_register ("y3_nu", 55);
2679 declare_register ("mlo", 57);
2680 declare_register ("mmid", 58);
2681 declare_register ("mhi", 59);
2683 declare_register ("acc1", 56);
2684 declare_register ("acc2", 57);
2686 declare_register ("lp_count", 60);
2687 declare_register ("pcl", 63);
2689 /* Initialize the last instructions. */
2690 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2692 /* Aux register declaration. */
2693 arc_aux_hash
= hash_new ();
2694 if (arc_aux_hash
== NULL
)
2695 as_fatal (_("Virtual memory exhausted"));
2697 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
2699 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
2703 if (!(auxr
->cpu
& selected_cpu
.flags
))
2706 if ((auxr
->subclass
!= NONE
)
2707 && !check_cpu_feature (auxr
->subclass
))
2710 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
2712 as_fatal (_("internal error: can't hash aux register '%s': %s"),
2713 auxr
->name
, retval
);
2716 /* Address type declaration. */
2717 arc_addrtype_hash
= hash_new ();
2718 if (arc_addrtype_hash
== NULL
)
2719 as_fatal (_("Virtual memory exhausted"));
2721 declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD
);
2722 declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID
);
2723 declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD
);
2724 declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD
);
2725 declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD
);
2726 declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM
);
2727 declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA
);
2728 declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD
);
2729 declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD
);
2730 declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD
);
2731 declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID
);
2732 declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD
);
2733 declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM
);
2734 declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD
);
2735 declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA
);
2736 declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD
);
2739 /* Write a value out to the object file, using the appropriate
2743 md_number_to_chars (char *buf
,
2747 if (target_big_endian
)
2748 number_to_chars_bigendian (buf
, val
, n
);
2750 number_to_chars_littleendian (buf
, val
, n
);
2753 /* Round up a section size to the appropriate boundary. */
2756 md_section_align (segT segment
,
2759 int align
= bfd_section_alignment (segment
);
2761 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2764 /* The location from which a PC relative jump should be calculated,
2765 given a PC relative reloc. */
2768 md_pcrel_from_section (fixS
*fixP
,
2771 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2773 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2775 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2776 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2777 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2779 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2781 /* The symbol is undefined (or is defined but not in this section).
2782 Let the linker figure it out. */
2786 if ((int) fixP
->fx_r_type
< 0)
2788 /* These are the "internal" relocations. Align them to
2789 32 bit boundary (PCL), for the moment. */
2794 switch (fixP
->fx_r_type
)
2796 case BFD_RELOC_ARC_PC32
:
2797 /* The hardware calculates relative to the start of the
2798 insn, but this relocation is relative to location of the
2799 LIMM, compensate. The base always needs to be
2800 subtracted by 4 as we do not support this type of PCrel
2801 relocation for short instructions. */
2804 case BFD_RELOC_ARC_PLT32
:
2805 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2806 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2807 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2808 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2810 case BFD_RELOC_ARC_S21H_PCREL
:
2811 case BFD_RELOC_ARC_S25H_PCREL
:
2812 case BFD_RELOC_ARC_S13_PCREL
:
2813 case BFD_RELOC_ARC_S21W_PCREL
:
2814 case BFD_RELOC_ARC_S25W_PCREL
:
2818 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2819 _("unhandled reloc %s in md_pcrel_from_section"),
2820 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2825 pr_debug ("pcrel from %"BFD_VMA_FMT
"x + %lx = %"BFD_VMA_FMT
"x, "
2826 "symbol: %s (%"BFD_VMA_FMT
"x)\n",
2827 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
2828 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2829 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
2834 /* Given a BFD relocation find the corresponding operand. */
2836 static const struct arc_operand
*
2837 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2841 for (i
= 0; i
< arc_num_operands
; i
++)
2842 if (arc_operands
[i
].default_reloc
== reloc
)
2843 return &arc_operands
[i
];
2847 /* Insert an operand value into an instruction. */
2849 static unsigned long long
2850 insert_operand (unsigned long long insn
,
2851 const struct arc_operand
*operand
,
2856 offsetT min
= 0, max
= 0;
2858 if (operand
->bits
!= 32
2859 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2860 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2862 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2864 max
= (1 << (operand
->bits
- 1)) - 1;
2865 min
= -(1 << (operand
->bits
- 1));
2869 max
= (1 << operand
->bits
) - 1;
2873 if (val
< min
|| val
> max
)
2874 as_bad_value_out_of_range (_("operand"),
2875 val
, min
, max
, file
, line
);
2878 pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
2879 min
, val
, max
, insn
);
2881 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2883 as_bad_where (file
, line
,
2884 _("Unaligned operand. Needs to be 32bit aligned"));
2886 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2888 as_bad_where (file
, line
,
2889 _("Unaligned operand. Needs to be 16bit aligned"));
2891 if (operand
->insert
)
2893 const char *errmsg
= NULL
;
2895 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2897 as_warn_where (file
, line
, "%s", errmsg
);
2901 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2903 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2905 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2908 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2913 /* Apply a fixup to the object code. At this point all symbol values
2914 should be fully resolved, and we attempt to completely resolve the
2915 reloc. If we can not do that, we determine the correct reloc code
2916 and put it back in the fixup. To indicate that a fixup has been
2917 eliminated, set fixP->fx_done. */
2920 md_apply_fix (fixS
*fixP
,
2924 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2925 valueT value
= *valP
;
2927 symbolS
*fx_addsy
, *fx_subsy
;
2929 segT add_symbol_segment
= absolute_section
;
2930 segT sub_symbol_segment
= absolute_section
;
2931 const struct arc_operand
*operand
= NULL
;
2932 extended_bfd_reloc_code_real_type reloc
;
2934 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2935 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2936 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2937 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2940 fx_addsy
= fixP
->fx_addsy
;
2941 fx_subsy
= fixP
->fx_subsy
;
2946 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2950 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2951 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2952 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2954 resolve_symbol_value (fx_subsy
);
2955 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2957 if (sub_symbol_segment
== absolute_section
)
2959 /* The symbol is really a constant. */
2960 fx_offset
-= S_GET_VALUE (fx_subsy
);
2965 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2966 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2967 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
2968 segment_name (add_symbol_segment
),
2969 S_GET_NAME (fx_subsy
),
2970 segment_name (sub_symbol_segment
));
2976 && !S_IS_WEAK (fx_addsy
))
2978 if (add_symbol_segment
== seg
2981 value
+= S_GET_VALUE (fx_addsy
);
2982 value
-= md_pcrel_from_section (fixP
, seg
);
2984 fixP
->fx_pcrel
= FALSE
;
2986 else if (add_symbol_segment
== absolute_section
)
2988 value
= fixP
->fx_offset
;
2989 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2991 fixP
->fx_pcrel
= FALSE
;
2996 fixP
->fx_done
= TRUE
;
3001 && ((S_IS_DEFINED (fx_addsy
)
3002 && S_GET_SEGMENT (fx_addsy
) != seg
)
3003 || S_IS_WEAK (fx_addsy
)))
3004 value
+= md_pcrel_from_section (fixP
, seg
);
3006 switch (fixP
->fx_r_type
)
3008 case BFD_RELOC_ARC_32_ME
:
3009 /* This is a pc-relative value in a LIMM. Adjust it to the
3010 address of the instruction not to the address of the
3011 LIMM. Note: it is not any longer valid this affirmation as
3012 the linker consider ARC_PC32 a fixup to entire 64 bit
3014 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
3017 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
3019 case BFD_RELOC_ARC_PC32
:
3020 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
3023 if ((int) fixP
->fx_r_type
< 0)
3024 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3025 _("PC relative relocation not allowed for (internal)"
3032 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
3033 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
3034 ((int) fixP
->fx_r_type
< 0) ? "Internal":
3035 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
3039 /* Now check for TLS relocations. */
3040 reloc
= fixP
->fx_r_type
;
3043 case BFD_RELOC_ARC_TLS_DTPOFF
:
3044 case BFD_RELOC_ARC_TLS_LE_32
:
3048 case BFD_RELOC_ARC_TLS_GD_GOT
:
3049 case BFD_RELOC_ARC_TLS_IE_GOT
:
3050 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
3053 case BFD_RELOC_ARC_TLS_GD_LD
:
3054 gas_assert (!fixP
->fx_offset
);
3057 = (S_GET_VALUE (fixP
->fx_subsy
)
3058 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
3059 fixP
->fx_subsy
= NULL
;
3061 case BFD_RELOC_ARC_TLS_GD_CALL
:
3062 /* These two relocs are there just to allow ld to change the tls
3063 model for this symbol, by patching the code. The offset -
3064 and scale, if any - will be installed by the linker. */
3065 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
3068 case BFD_RELOC_ARC_TLS_LE_S9
:
3069 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
3070 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3082 /* Adjust the value if we have a constant. */
3085 /* For hosts with longs bigger than 32-bits make sure that the top
3086 bits of a 32-bit negative value read in by the parser are set,
3087 so that the correct comparisons are made. */
3088 if (value
& 0x80000000)
3089 value
|= (-1UL << 31);
3091 reloc
= fixP
->fx_r_type
;
3099 case BFD_RELOC_ARC_32_PCREL
:
3100 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
3103 case BFD_RELOC_ARC_GOTPC32
:
3104 /* I cannot fix an GOTPC relocation because I need to relax it
3105 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
3106 as_bad (_("Unsupported operation on reloc"));
3109 case BFD_RELOC_ARC_TLS_DTPOFF
:
3110 case BFD_RELOC_ARC_TLS_LE_32
:
3111 gas_assert (!fixP
->fx_addsy
);
3112 gas_assert (!fixP
->fx_subsy
);
3115 case BFD_RELOC_ARC_GOTOFF
:
3116 case BFD_RELOC_ARC_32_ME
:
3117 case BFD_RELOC_ARC_PC32
:
3118 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
3121 case BFD_RELOC_ARC_PLT32
:
3122 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
3125 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
3126 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
3129 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
3130 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
3133 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
3134 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
3137 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
3138 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
3141 case BFD_RELOC_ARC_S25W_PCREL
:
3142 case BFD_RELOC_ARC_S21W_PCREL
:
3143 case BFD_RELOC_ARC_S21H_PCREL
:
3144 case BFD_RELOC_ARC_S25H_PCREL
:
3145 case BFD_RELOC_ARC_S13_PCREL
:
3147 operand
= find_operand_for_reloc (reloc
);
3148 gas_assert (operand
);
3153 if ((int) fixP
->fx_r_type
>= 0)
3154 as_fatal (_("unhandled relocation type %s"),
3155 bfd_get_reloc_code_name (fixP
->fx_r_type
));
3157 /* The rest of these fixups needs to be completely resolved as
3159 if (fixP
->fx_addsy
!= 0
3160 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
3161 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3162 _("non-absolute expression in constant field"));
3164 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
3165 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
3170 if (target_big_endian
)
3172 switch (fixP
->fx_size
)
3175 insn
= bfd_getb32 (fixpos
);
3178 insn
= bfd_getb16 (fixpos
);
3181 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3182 _("unknown fixup size"));
3188 switch (fixP
->fx_size
)
3191 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
3194 insn
= bfd_getl16 (fixpos
);
3197 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3198 _("unknown fixup size"));
3202 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
3203 fixP
->fx_file
, fixP
->fx_line
);
3205 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
3208 /* Prepare machine-dependent frags for relaxation.
3210 Called just before relaxation starts. Any symbol that is now undefined
3211 will not become defined.
3213 Return the correct fr_subtype in the frag.
3215 Return the initial "guess for fr_var" to caller. The guess for fr_var
3216 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3217 or fr_var contributes to our returned value.
3219 Although it may not be explicit in the frag, pretend
3220 fr_var starts with a value. */
3223 md_estimate_size_before_relax (fragS
*fragP
,
3228 /* If the symbol is not located within the same section AND it's not
3229 an absolute section, use the maximum. OR if the symbol is a
3230 constant AND the insn is by nature not pc-rel, use the maximum.
3231 OR if the symbol is being equated against another symbol, use the
3232 maximum. OR if the symbol is weak use the maximum. */
3233 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
3234 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
3235 || (symbol_constant_p (fragP
->fr_symbol
)
3236 && !fragP
->tc_frag_data
.pcrel
)
3237 || symbol_equated_p (fragP
->fr_symbol
)
3238 || S_IS_WEAK (fragP
->fr_symbol
))
3240 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
3241 ++fragP
->fr_subtype
;
3244 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3245 fragP
->fr_var
= growth
;
3247 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3248 fragP
->fr_file
, fragP
->fr_line
, growth
);
3253 /* Translate internal representation of relocation info to BFD target
3257 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
3261 bfd_reloc_code_real_type code
;
3263 reloc
= XNEW (arelent
);
3264 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3265 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3266 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3268 /* Make sure none of our internal relocations make it this far.
3269 They'd better have been fully resolved by this point. */
3270 gas_assert ((int) fixP
->fx_r_type
> 0);
3272 code
= fixP
->fx_r_type
;
3274 /* if we have something like add gp, pcl,
3275 _GLOBAL_OFFSET_TABLE_@gotpc. */
3276 if (code
== BFD_RELOC_ARC_GOTPC32
3278 && fixP
->fx_addsy
== GOT_symbol
)
3279 code
= BFD_RELOC_ARC_GOTPC
;
3281 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
3282 if (reloc
->howto
== NULL
)
3284 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3285 _("cannot represent `%s' relocation in object file"),
3286 bfd_get_reloc_code_name (code
));
3290 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
3291 as_fatal (_("internal error? cannot generate `%s' relocation"),
3292 bfd_get_reloc_code_name (code
));
3294 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
3296 reloc
->addend
= fixP
->fx_offset
;
3301 /* Perform post-processing of machine-dependent frags after relaxation.
3302 Called after relaxation is finished.
3303 In: Address of frag.
3304 fr_type == rs_machine_dependent.
3305 fr_subtype is what the address relaxed to.
3307 Out: Any fixS:s and constants are set up. */
3310 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
3311 segT segment ATTRIBUTE_UNUSED
,
3314 const relax_typeS
*table_entry
;
3316 const struct arc_opcode
*opcode
;
3317 struct arc_insn insn
;
3319 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
3321 fix
= fragP
->fr_fix
;
3322 dest
= fragP
->fr_literal
+ fix
;
3323 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
3325 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3326 "var: %"BFD_VMA_FMT
"d\n",
3327 fragP
->fr_file
, fragP
->fr_line
,
3328 fragP
->fr_subtype
, fix
, fragP
->fr_var
);
3330 if (fragP
->fr_subtype
<= 0
3331 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
3332 as_fatal (_("no relaxation found for this instruction."));
3334 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
3336 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
3337 relax_arg
->nflg
, &insn
);
3339 apply_fixups (&insn
, fragP
, fix
);
3341 size
= insn
.len
+ (insn
.has_limm
? 4 : 0);
3342 gas_assert (table_entry
->rlx_length
== size
);
3343 emit_insn0 (&insn
, dest
, TRUE
);
3345 fragP
->fr_fix
+= table_entry
->rlx_length
;
3349 /* We have no need to default values of symbols. We could catch
3350 register names here, but that is handled by inserting them all in
3351 the symbol table to begin with. */
3354 md_undefined_symbol (char *name
)
3356 /* The arc abi demands that a GOT[0] should be referencible as
3357 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3358 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3360 && (*(name
+1) == 'G')
3361 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0)))
3365 if (symbol_find (name
))
3366 as_bad ("GOT already in symbol table");
3368 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
3369 (valueT
) 0, &zero_address_frag
);
3376 /* Turn a string in input_line_pointer into a floating point constant
3377 of type type, and store the appropriate bytes in *litP. The number
3378 of LITTLENUMS emitted is stored in *sizeP. An error message is
3379 returned, or NULL on OK. */
3382 md_atof (int type
, char *litP
, int *sizeP
)
3384 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
3387 /* Called for any expression that can not be recognized. When the
3388 function is called, `input_line_pointer' will point to the start of
3389 the expression. We use it when we have complex operations like
3390 @label1 - @label2. */
3393 md_operand (expressionS
*expressionP
)
3395 char *p
= input_line_pointer
;
3398 input_line_pointer
++;
3399 expressionP
->X_op
= O_symbol
;
3400 expressionP
->X_md
= O_absent
;
3401 expression (expressionP
);
3405 /* This function is called from the function 'expression', it attempts
3406 to parse special names (in our case register names). It fills in
3407 the expression with the identified register. It returns TRUE if
3408 it is a register and FALSE otherwise. */
3411 arc_parse_name (const char *name
,
3412 struct expressionS
*e
)
3416 if (!assembling_insn
)
3419 if (e
->X_op
== O_symbol
3420 && e
->X_md
== O_absent
)
3423 sym
= hash_find (arc_reg_hash
, name
);
3426 e
->X_op
= O_register
;
3427 e
->X_add_number
= S_GET_VALUE (sym
);
3431 sym
= hash_find (arc_addrtype_hash
, name
);
3434 e
->X_op
= O_addrtype
;
3435 e
->X_add_number
= S_GET_VALUE (sym
);
3443 Invocation line includes a switch not recognized by the base assembler.
3444 See if it's a processor-specific option.
3446 New options (supported) are:
3448 -mcpu=<cpu name> Assemble for selected processor
3449 -EB/-mbig-endian Big-endian
3450 -EL/-mlittle-endian Little-endian
3451 -mrelax Enable relaxation
3453 The following CPU names are recognized:
3454 arc600, arc700, arcem, archs, nps400. */
3457 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
3463 return md_parse_option (OPTION_MCPU
, "arc600");
3466 return md_parse_option (OPTION_MCPU
, "arc700");
3469 return md_parse_option (OPTION_MCPU
, "arcem");
3472 return md_parse_option (OPTION_MCPU
, "archs");
3476 arc_select_cpu (arg
, MACH_SELECTION_FROM_COMMAND_LINE
);
3481 arc_target_format
= "elf32-bigarc";
3482 byte_order
= BIG_ENDIAN
;
3486 arc_target_format
= "elf32-littlearc";
3487 byte_order
= LITTLE_ENDIAN
;
3491 selected_cpu
.features
|= CD
;
3493 arc_check_feature ();
3497 relaxation_state
= 1;
3501 selected_cpu
.features
|= NPS400
;
3502 cl_features
|= NPS400
;
3503 arc_check_feature ();
3507 selected_cpu
.features
|= SPX
;
3509 arc_check_feature ();
3513 selected_cpu
.features
|= DPX
;
3515 arc_check_feature ();
3519 selected_cpu
.features
|= DPA
;
3521 arc_check_feature ();
3524 /* Dummy options are accepted but have no effect. */
3525 case OPTION_USER_MODE
:
3526 case OPTION_LD_EXT_MASK
:
3529 case OPTION_BARREL_SHIFT
:
3530 case OPTION_MIN_MAX
:
3535 case OPTION_XMAC_D16
:
3536 case OPTION_XMAC_24
:
3537 case OPTION_DSP_PACKA
:
3540 case OPTION_TELEPHONY
:
3541 case OPTION_XYMEMORY
:
3554 /* Display the list of cpu names for use in the help text. */
3557 arc_show_cpu_list (FILE *stream
)
3560 static const char *space_buf
= " ";
3562 fprintf (stream
, "%s", space_buf
);
3563 offset
= strlen (space_buf
);
3564 for (i
= 0; cpu_types
[i
].name
!= NULL
; ++i
)
3566 bfd_boolean last
= (cpu_types
[i
+ 1].name
== NULL
);
3568 /* If displaying the new cpu name string, and the ', ' (for all
3569 but the last one) will take us past a target width of 80
3570 characters, then it's time for a new line. */
3571 if (offset
+ strlen (cpu_types
[i
].name
) + (last
? 0 : 2) > 80)
3573 fprintf (stream
, "\n%s", space_buf
);
3574 offset
= strlen (space_buf
);
3577 fprintf (stream
, "%s%s", cpu_types
[i
].name
, (last
? "\n" : ", "));
3578 offset
+= strlen (cpu_types
[i
].name
) + (last
? 0 : 2);
3583 md_show_usage (FILE *stream
)
3585 fprintf (stream
, _("ARC-specific assembler options:\n"));
3587 fprintf (stream
, " -mcpu=<cpu name>\t (default: %s), assemble for"
3588 " CPU <cpu name>, one of:\n", TARGET_WITH_CPU
);
3589 arc_show_cpu_list (stream
);
3590 fprintf (stream
, "\n");
3591 fprintf (stream
, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3592 fprintf (stream
, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3593 fprintf (stream
, " -mEM\t\t\t same as -mcpu=arcem\n");
3594 fprintf (stream
, " -mHS\t\t\t same as -mcpu=archs\n");
3596 fprintf (stream
, " -mnps400\t\t enable NPS-400 extended instructions\n");
3597 fprintf (stream
, " -mspfp\t\t enable single-precision floating point"
3599 fprintf (stream
, " -mdpfp\t\t enable double-precision floating point"
3601 fprintf (stream
, " -mfpuda\t\t enable double-precision assist floating "
3602 "point\n\t\t\t instructions for ARC EM\n");
3605 " -mcode-density\t enable code density option for ARC EM\n");
3607 fprintf (stream
, _("\
3608 -EB assemble code for a big-endian cpu\n"));
3609 fprintf (stream
, _("\
3610 -EL assemble code for a little-endian cpu\n"));
3611 fprintf (stream
, _("\
3612 -mrelax enable relaxation\n"));
3614 fprintf (stream
, _("The following ARC-specific assembler options are "
3615 "deprecated and are accepted\nfor compatibility only:\n"));
3617 fprintf (stream
, _(" -mEA\n"
3618 " -mbarrel-shifter\n"
3619 " -mbarrel_shifter\n"
3624 " -mld-extension-reg-mask\n"
3640 " -muser-mode-only\n"
3644 /* Find the proper relocation for the given opcode. */
3646 static extended_bfd_reloc_code_real_type
3647 find_reloc (const char *name
,
3648 const char *opcodename
,
3649 const struct arc_flags
*pflags
,
3651 extended_bfd_reloc_code_real_type reloc
)
3655 bfd_boolean found_flag
, tmp
;
3656 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
3658 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
3660 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3662 /* Find the entry. */
3663 if (strcmp (name
, r
->name
))
3665 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3672 unsigned * psflg
= (unsigned *)r
->flags
;
3676 for (j
= 0; j
< nflg
; j
++)
3677 if (!strcmp (pflags
[j
].name
,
3678 arc_flag_operands
[*psflg
].name
))
3699 if (reloc
!= r
->oldreloc
)
3706 if (ret
== BFD_RELOC_UNUSED
)
3707 as_bad (_("Unable to find %s relocation for instruction %s"),
3712 /* All the symbol types that are allowed to be used for
3716 may_relax_expr (expressionS tok
)
3718 /* Check if we have unrelaxable relocs. */
3743 /* Checks if flags are in line with relaxable insn. */
3746 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3747 const struct arc_flags
*pflags
,
3750 unsigned flag_class
,
3755 const struct arc_flag_operand
*flag_opand
;
3756 int i
, counttrue
= 0;
3758 /* Iterate through flags classes. */
3759 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3761 /* Iterate through flags in flag class. */
3762 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3765 flag_opand
= &arc_flag_operands
[flag
];
3766 /* Iterate through flags in ins to compare. */
3767 for (i
= 0; i
< nflgs
; ++i
)
3769 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3780 /* If counttrue == nflgs, then all flags have been found. */
3781 return (counttrue
== nflgs
? TRUE
: FALSE
);
3784 /* Checks if operands are in line with relaxable insn. */
3787 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3788 const expressionS
*tok
,
3791 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3794 while (*operand
!= EMPTY
)
3796 const expressionS
*epr
= &tok
[i
];
3798 if (i
!= 0 && i
>= ntok
)
3804 if (!(epr
->X_op
== O_multiply
3805 || epr
->X_op
== O_divide
3806 || epr
->X_op
== O_modulus
3807 || epr
->X_op
== O_add
3808 || epr
->X_op
== O_subtract
3809 || epr
->X_op
== O_symbol
))
3815 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3819 if (epr
->X_op
!= O_register
)
3824 if (epr
->X_op
!= O_register
)
3827 switch (epr
->X_add_number
)
3829 case 0: case 1: case 2: case 3:
3830 case 12: case 13: case 14: case 15:
3837 case REGISTER_NO_GP
:
3838 if ((epr
->X_op
!= O_register
)
3839 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3844 if (epr
->X_op
!= O_bracket
)
3849 /* Don't understand, bail out. */
3855 operand
= &ins
->operands
[i
];
3858 return (i
== ntok
? TRUE
: FALSE
);
3861 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3864 relax_insn_p (const struct arc_opcode
*opcode
,
3865 const expressionS
*tok
,
3867 const struct arc_flags
*pflags
,
3871 bfd_boolean rv
= FALSE
;
3873 /* Check the relaxation table. */
3874 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3876 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3878 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3879 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3880 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3881 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3884 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3885 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3886 sizeof (expressionS
) * ntok
);
3887 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3888 sizeof (struct arc_flags
) * nflg
);
3889 frag_now
->tc_frag_data
.nflg
= nflg
;
3890 frag_now
->tc_frag_data
.ntok
= ntok
;
3898 /* Turn an opcode description and a set of arguments into
3899 an instruction and a fixup. */
3902 assemble_insn (const struct arc_opcode
*opcode
,
3903 const expressionS
*tok
,
3905 const struct arc_flags
*pflags
,
3907 struct arc_insn
*insn
)
3909 const expressionS
*reloc_exp
= NULL
;
3910 unsigned long long image
;
3911 const unsigned char *argidx
;
3914 unsigned char pcrel
= 0;
3915 bfd_boolean needGOTSymbol
;
3916 bfd_boolean has_delay_slot
= FALSE
;
3917 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3919 memset (insn
, 0, sizeof (*insn
));
3920 image
= opcode
->opcode
;
3922 pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
3923 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3926 /* Handle operands. */
3927 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3929 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3930 const expressionS
*t
= (const expressionS
*) 0;
3932 if (ARC_OPERAND_IS_FAKE (operand
))
3935 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3937 /* Duplicate operand, already inserted. */
3949 /* Regardless if we have a reloc or not mark the instruction
3950 limm if it is the case. */
3951 if (operand
->flags
& ARC_OPERAND_LIMM
)
3952 insn
->has_limm
= TRUE
;
3957 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3962 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3964 if (operand
->flags
& ARC_OPERAND_LIMM
)
3965 insn
->limm
= t
->X_add_number
;
3971 /* Ignore brackets, colons, and address types. */
3975 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3979 /* Maybe register range. */
3980 if ((t
->X_add_number
== 0)
3981 && contains_register (t
->X_add_symbol
)
3982 && contains_register (t
->X_op_symbol
))
3986 regs
= get_register (t
->X_add_symbol
);
3988 regs
|= get_register (t
->X_op_symbol
);
3989 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3995 /* This operand needs a relocation. */
3996 needGOTSymbol
= FALSE
;
4001 if (opcode
->insn_class
== JUMP
)
4002 as_bad (_("Unable to use @plt relocation for insn %s"),
4004 needGOTSymbol
= TRUE
;
4005 reloc
= find_reloc ("plt", opcode
->name
,
4007 operand
->default_reloc
);
4012 needGOTSymbol
= TRUE
;
4013 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
4016 if (operand
->flags
& ARC_OPERAND_LIMM
)
4018 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
4019 if (arc_opcode_len (opcode
) == 2
4020 || opcode
->insn_class
== JUMP
)
4021 as_bad (_("Unable to use @pcl relocation for insn %s"),
4026 /* This is a relaxed operand which initially was
4027 limm, choose whatever we have defined in the
4029 reloc
= operand
->default_reloc
;
4033 reloc
= find_reloc ("sda", opcode
->name
,
4035 operand
->default_reloc
);
4039 needGOTSymbol
= TRUE
;
4044 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
4047 case O_tpoff9
: /*FIXME! Check for the conditionality of
4049 case O_dtpoff9
: /*FIXME! Check for the conditionality of
4051 as_bad (_("TLS_*_S9 relocs are not supported yet"));
4055 /* Just consider the default relocation. */
4056 reloc
= operand
->default_reloc
;
4060 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
4061 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
4068 /* sanity checks. */
4069 reloc_howto_type
*reloc_howto
4070 = bfd_reloc_type_lookup (stdoutput
,
4071 (bfd_reloc_code_real_type
) reloc
);
4072 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
4073 if (reloc_howto
->rightshift
)
4074 reloc_bitsize
-= reloc_howto
->rightshift
;
4075 if (reloc_bitsize
!= operand
->bits
)
4077 as_bad (_("invalid relocation %s for field"),
4078 bfd_get_reloc_code_name (reloc
));
4083 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
4084 as_fatal (_("too many fixups"));
4086 struct arc_fixup
*fixup
;
4087 fixup
= &insn
->fixups
[insn
->nfixups
++];
4089 fixup
->reloc
= reloc
;
4090 if ((int) reloc
< 0)
4091 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
4094 reloc_howto_type
*reloc_howto
=
4095 bfd_reloc_type_lookup (stdoutput
,
4096 (bfd_reloc_code_real_type
) fixup
->reloc
);
4097 pcrel
= reloc_howto
->pc_relative
;
4099 fixup
->pcrel
= pcrel
;
4100 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
4107 for (i
= 0; i
< nflg
; i
++)
4109 const struct arc_flag_operand
*flg_operand
= pflags
[i
].flgp
;
4111 /* Check if the instruction has a delay slot. */
4112 if (!strcmp (flg_operand
->name
, "d"))
4113 has_delay_slot
= TRUE
;
4115 /* There is an exceptional case when we cannot insert a flag just as
4116 it is. On ARCv2 the '.t' and '.nt' flags must be handled in
4117 relation with the relative address. Unfortunately, some of the
4118 ARC700 extensions (NPS400) also have a '.nt' flag that should be
4119 handled in the normal way.
4121 Flag operands don't have an architecture field, so we can't
4122 directly validate that FLAG_OPERAND is valid for the current
4123 architecture, what we do instead is just validate that we're
4124 assembling for an ARCv2 architecture. */
4125 if ((selected_cpu
.flags
& ARC_OPCODE_ARCV2
)
4126 && (!strcmp (flg_operand
->name
, "t")
4127 || !strcmp (flg_operand
->name
, "nt")))
4129 unsigned bitYoperand
= 0;
4130 /* FIXME! move selection bbit/brcc in arc-opc.c. */
4131 if (!strcmp (flg_operand
->name
, "t"))
4132 if (!strcmp (opcode
->name
, "bbit0")
4133 || !strcmp (opcode
->name
, "bbit1"))
4134 bitYoperand
= arc_NToperand
;
4136 bitYoperand
= arc_Toperand
;
4138 if (!strcmp (opcode
->name
, "bbit0")
4139 || !strcmp (opcode
->name
, "bbit1"))
4140 bitYoperand
= arc_Toperand
;
4142 bitYoperand
= arc_NToperand
;
4144 gas_assert (reloc_exp
!= NULL
);
4145 if (reloc_exp
->X_op
== O_constant
)
4147 /* Check if we have a constant and solved it
4149 offsetT val
= reloc_exp
->X_add_number
;
4150 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
4155 struct arc_fixup
*fixup
;
4157 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
4158 as_fatal (_("too many fixups"));
4160 fixup
= &insn
->fixups
[insn
->nfixups
++];
4161 fixup
->exp
= *reloc_exp
;
4162 fixup
->reloc
= -bitYoperand
;
4163 fixup
->pcrel
= pcrel
;
4164 fixup
->islong
= FALSE
;
4168 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
4169 << flg_operand
->shift
;
4172 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
4174 /* Instruction length. */
4175 insn
->len
= arc_opcode_len (opcode
);
4179 /* Update last insn status. */
4180 arc_last_insns
[1] = arc_last_insns
[0];
4181 arc_last_insns
[0].opcode
= opcode
;
4182 arc_last_insns
[0].has_limm
= insn
->has_limm
;
4183 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
4185 /* Check if the current instruction is legally used. */
4186 if (arc_last_insns
[1].has_delay_slot
4187 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4188 as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."),
4189 arc_last_insns
[1].opcode
->name
,
4190 arc_last_insns
[0].opcode
->name
);
4191 if (arc_last_insns
[1].has_delay_slot
4192 && arc_last_insns
[0].has_limm
)
4193 as_bad (_("Insn %s has an instruction %s with limm in its delay slot."),
4194 arc_last_insns
[1].opcode
->name
,
4195 arc_last_insns
[0].opcode
->name
);
4199 arc_handle_align (fragS
* fragP
)
4201 if ((fragP
)->fr_type
== rs_align_code
)
4203 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
4204 valueT count
= ((fragP
)->fr_next
->fr_address
4205 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
4207 (fragP
)->fr_var
= 2;
4209 if (count
& 1)/* Padding in the gap till the next 2-byte
4210 boundary with 0s. */
4215 /* Writing nop_s. */
4216 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
4220 /* Here we decide which fixups can be adjusted to make them relative
4221 to the beginning of the section instead of the symbol. Basically
4222 we need to make sure that the dynamic relocations are done
4223 correctly, so in some cases we force the original symbol to be
4227 tc_arc_fix_adjustable (fixS
*fixP
)
4230 /* Prevent all adjustments to global symbols. */
4231 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
4233 if (S_IS_WEAK (fixP
->fx_addsy
))
4236 /* Adjust_reloc_syms doesn't know about the GOT. */
4237 switch (fixP
->fx_r_type
)
4239 case BFD_RELOC_ARC_GOTPC32
:
4240 case BFD_RELOC_ARC_PLT32
:
4241 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
4242 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
4243 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
4244 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
4254 /* Compute the reloc type of an expression EXP. */
4257 arc_check_reloc (expressionS
*exp
,
4258 bfd_reloc_code_real_type
*r_type_p
)
4260 if (*r_type_p
== BFD_RELOC_32
4261 && exp
->X_op
== O_subtract
4262 && exp
->X_op_symbol
!= NULL
4263 && S_GET_SEGMENT (exp
->X_op_symbol
) == now_seg
)
4264 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
4268 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4271 arc_cons_fix_new (fragS
*frag
,
4275 bfd_reloc_code_real_type r_type
)
4277 r_type
= BFD_RELOC_UNUSED
;
4282 r_type
= BFD_RELOC_8
;
4286 r_type
= BFD_RELOC_16
;
4290 r_type
= BFD_RELOC_24
;
4294 r_type
= BFD_RELOC_32
;
4295 arc_check_reloc (exp
, &r_type
);
4299 r_type
= BFD_RELOC_64
;
4303 as_bad (_("unsupported BFD relocation size %u"), size
);
4304 r_type
= BFD_RELOC_UNUSED
;
4307 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
4310 /* The actual routine that checks the ZOL conditions. */
4313 check_zol (symbolS
*s
)
4315 switch (selected_cpu
.mach
)
4317 case bfd_mach_arc_arcv2
:
4318 if (selected_cpu
.flags
& ARC_OPCODE_ARCv2EM
)
4321 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
4322 || arc_last_insns
[1].has_delay_slot
)
4323 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4327 case bfd_mach_arc_arc600
:
4329 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
4330 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4333 if (arc_last_insns
[0].has_limm
4334 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4335 as_bad (_("A jump instruction with long immediate detected at the \
4336 end of the ZOL label @%s"), S_GET_NAME (s
));
4339 case bfd_mach_arc_arc700
:
4340 if (arc_last_insns
[0].has_delay_slot
)
4341 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4350 /* If ZOL end check the last two instruction for illegals. */
4352 arc_frob_label (symbolS
* sym
)
4354 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
4357 dwarf2_emit_label (sym
);
4360 /* Used because generic relaxation assumes a pc-rel value whilst we
4361 also relax instructions that use an absolute value resolved out of
4362 relative values (if that makes any sense). An example: 'add r1,
4363 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4364 but if they're in the same section we can subtract the section
4365 offset relocation which ends up in a resolved value. So if @.L2 is
4366 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4367 .text + 0x40 = 0x10. */
4369 arc_pcrel_adjust (fragS
*fragP
)
4371 pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
4372 fragP
->fr_address
, fragP
->fr_fix
,
4373 fragP
->tc_frag_data
.pcrel
? "Y" : "N");
4375 if (!fragP
->tc_frag_data
.pcrel
)
4376 return fragP
->fr_address
+ fragP
->fr_fix
;
4378 /* Take into account the PCL rounding. */
4379 return (fragP
->fr_address
+ fragP
->fr_fix
) & 0x03;
4382 /* Initialize the DWARF-2 unwind information for this procedure. */
4385 tc_arc_frame_initial_instructions (void)
4387 /* Stack pointer is register 28. */
4388 cfi_add_CFA_def_cfa (28, 0);
4392 tc_arc_regname_to_dw2regnum (char *regname
)
4396 sym
= hash_find (arc_reg_hash
, regname
);
4398 return S_GET_VALUE (sym
);
4403 /* Adjust the symbol table. Delete found AUX register symbols. */
4406 arc_adjust_symtab (void)
4410 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
4412 /* I've created a symbol during parsing process. Now, remove
4413 the symbol as it is found to be an AUX register. */
4414 if (ARC_GET_FLAG (sym
) & ARC_FLAG_AUX
)
4415 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
4418 /* Now do generic ELF adjustments. */
4419 elf_adjust_symtab ();
4423 tokenize_extinsn (extInstruction_t
*einsn
)
4427 unsigned char major_opcode
;
4428 unsigned char sub_opcode
;
4429 unsigned char syntax_class
= 0;
4430 unsigned char syntax_class_modifiers
= 0;
4431 unsigned char suffix_class
= 0;
4436 /* 1st: get instruction name. */
4437 p
= input_line_pointer
;
4438 c
= get_symbol_name (&p
);
4440 insn_name
= xstrdup (p
);
4441 restore_line_pointer (c
);
4443 /* Convert to lower case. */
4444 for (p
= insn_name
; *p
; ++p
)
4447 /* 2nd: get major opcode. */
4448 if (*input_line_pointer
!= ',')
4450 as_bad (_("expected comma after instruction name"));
4451 ignore_rest_of_line ();
4454 input_line_pointer
++;
4455 major_opcode
= get_absolute_expression ();
4457 /* 3rd: get sub-opcode. */
4460 if (*input_line_pointer
!= ',')
4462 as_bad (_("expected comma after major opcode"));
4463 ignore_rest_of_line ();
4466 input_line_pointer
++;
4467 sub_opcode
= get_absolute_expression ();
4469 /* 4th: get suffix class. */
4472 if (*input_line_pointer
!= ',')
4474 as_bad ("expected comma after sub opcode");
4475 ignore_rest_of_line ();
4478 input_line_pointer
++;
4484 for (i
= 0; i
< ARRAY_SIZE (suffixclass
); i
++)
4486 if (!strncmp (suffixclass
[i
].name
, input_line_pointer
,
4487 suffixclass
[i
].len
))
4489 suffix_class
|= suffixclass
[i
].attr_class
;
4490 input_line_pointer
+= suffixclass
[i
].len
;
4495 if (i
== ARRAY_SIZE (suffixclass
))
4497 as_bad ("invalid suffix class");
4498 ignore_rest_of_line ();
4504 if (*input_line_pointer
== '|')
4505 input_line_pointer
++;
4510 /* 5th: get syntax class and syntax class modifiers. */
4511 if (*input_line_pointer
!= ',')
4513 as_bad ("expected comma after suffix class");
4514 ignore_rest_of_line ();
4517 input_line_pointer
++;
4523 for (i
= 0; i
< ARRAY_SIZE (syntaxclassmod
); i
++)
4525 if (!strncmp (syntaxclassmod
[i
].name
,
4527 syntaxclassmod
[i
].len
))
4529 syntax_class_modifiers
|= syntaxclassmod
[i
].attr_class
;
4530 input_line_pointer
+= syntaxclassmod
[i
].len
;
4535 if (i
== ARRAY_SIZE (syntaxclassmod
))
4537 for (i
= 0; i
< ARRAY_SIZE (syntaxclass
); i
++)
4539 if (!strncmp (syntaxclass
[i
].name
,
4541 syntaxclass
[i
].len
))
4543 syntax_class
|= syntaxclass
[i
].attr_class
;
4544 input_line_pointer
+= syntaxclass
[i
].len
;
4549 if (i
== ARRAY_SIZE (syntaxclass
))
4551 as_bad ("missing syntax class");
4552 ignore_rest_of_line ();
4559 if (*input_line_pointer
== '|')
4560 input_line_pointer
++;
4565 demand_empty_rest_of_line ();
4567 einsn
->name
= insn_name
;
4568 einsn
->major
= major_opcode
;
4569 einsn
->minor
= sub_opcode
;
4570 einsn
->syntax
= syntax_class
;
4571 einsn
->modsyn
= syntax_class_modifiers
;
4572 einsn
->suffix
= suffix_class
;
4573 einsn
->flags
= syntax_class
4574 | (syntax_class_modifiers
& ARC_OP1_IMM_IMPLIED
? 0x10 : 0);
4577 /* Generate an extension section. */
4580 arc_set_ext_seg (void)
4582 if (!arcext_section
)
4584 arcext_section
= subseg_new (".arcextmap", 0);
4585 bfd_set_section_flags (arcext_section
, SEC_READONLY
| SEC_HAS_CONTENTS
);
4588 subseg_set (arcext_section
, 0);
4592 /* Create an extension instruction description in the arc extension
4593 section of the output file.
4594 The structure for an instruction is like this:
4595 [0]: Length of the record.
4596 [1]: Type of the record.
4600 [4]: Syntax (flags).
4601 [5]+ Name instruction.
4603 The sequence is terminated by an empty entry. */
4606 create_extinst_section (extInstruction_t
*einsn
)
4609 segT old_sec
= now_seg
;
4610 int old_subsec
= now_subseg
;
4612 int name_len
= strlen (einsn
->name
);
4617 *p
= 5 + name_len
+ 1;
4619 *p
= EXT_INSTRUCTION
;
4626 p
= frag_more (name_len
+ 1);
4627 strcpy (p
, einsn
->name
);
4629 subseg_set (old_sec
, old_subsec
);
4632 /* Handler .extinstruction pseudo-op. */
4635 arc_extinsn (int ignore ATTRIBUTE_UNUSED
)
4637 extInstruction_t einsn
;
4638 struct arc_opcode
*arc_ext_opcodes
;
4639 const char *errmsg
= NULL
;
4640 unsigned char moplow
, mophigh
;
4642 memset (&einsn
, 0, sizeof (einsn
));
4643 tokenize_extinsn (&einsn
);
4645 /* Check if the name is already used. */
4646 if (arc_find_opcode (einsn
.name
))
4647 as_warn (_("Pseudocode already used %s"), einsn
.name
);
4649 /* Check the opcode ranges. */
4651 mophigh
= (selected_cpu
.flags
& (ARC_OPCODE_ARCv2EM
4652 | ARC_OPCODE_ARCv2HS
)) ? 0x07 : 0x0a;
4654 if ((einsn
.major
> mophigh
) || (einsn
.major
< moplow
))
4655 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow
, mophigh
);
4657 if ((einsn
.minor
> 0x3f) && (einsn
.major
!= 0x0a)
4658 && (einsn
.major
!= 5) && (einsn
.major
!= 9))
4659 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4661 switch (einsn
.syntax
& ARC_SYNTAX_MASK
)
4663 case ARC_SYNTAX_3OP
:
4664 if (einsn
.modsyn
& ARC_OP1_IMM_IMPLIED
)
4665 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4667 case ARC_SYNTAX_2OP
:
4668 case ARC_SYNTAX_1OP
:
4669 case ARC_SYNTAX_NOP
:
4670 if (einsn
.modsyn
& ARC_OP1_MUST_BE_IMM
)
4671 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4677 arc_ext_opcodes
= arcExtMap_genOpcode (&einsn
, selected_cpu
.flags
, &errmsg
);
4678 if (arc_ext_opcodes
== NULL
)
4681 as_fatal ("%s", errmsg
);
4683 as_fatal (_("Couldn't generate extension instruction opcodes"));
4686 as_warn ("%s", errmsg
);
4688 /* Insert the extension instruction. */
4689 arc_insert_opcode ((const struct arc_opcode
*) arc_ext_opcodes
);
4691 create_extinst_section (&einsn
);
4695 tokenize_extregister (extRegister_t
*ereg
, int opertype
)
4701 int number
, imode
= 0;
4702 bfd_boolean isCore_p
= (opertype
== EXT_CORE_REGISTER
) ? TRUE
: FALSE
;
4703 bfd_boolean isReg_p
= (opertype
== EXT_CORE_REGISTER
4704 || opertype
== EXT_AUX_REGISTER
) ? TRUE
: FALSE
;
4706 /* 1st: get register name. */
4708 p
= input_line_pointer
;
4709 c
= get_symbol_name (&p
);
4712 restore_line_pointer (c
);
4714 /* 2nd: get register number. */
4717 if (*input_line_pointer
!= ',')
4719 as_bad (_("expected comma after name"));
4720 ignore_rest_of_line ();
4724 input_line_pointer
++;
4725 number
= get_absolute_expression ();
4728 && (opertype
!= EXT_AUX_REGISTER
))
4730 as_bad (_("%s second argument cannot be a negative number %d"),
4731 isCore_p
? "extCoreRegister's" : "extCondCode's",
4733 ignore_rest_of_line ();
4740 /* 3rd: get register mode. */
4743 if (*input_line_pointer
!= ',')
4745 as_bad (_("expected comma after register number"));
4746 ignore_rest_of_line ();
4751 input_line_pointer
++;
4752 mode
= input_line_pointer
;
4754 if (!strncmp (mode
, "r|w", 3))
4757 input_line_pointer
+= 3;
4759 else if (!strncmp (mode
, "r", 1))
4761 imode
= ARC_REGISTER_READONLY
;
4762 input_line_pointer
+= 1;
4764 else if (strncmp (mode
, "w", 1))
4766 as_bad (_("invalid mode"));
4767 ignore_rest_of_line ();
4773 imode
= ARC_REGISTER_WRITEONLY
;
4774 input_line_pointer
+= 1;
4780 /* 4th: get core register shortcut. */
4782 if (*input_line_pointer
!= ',')
4784 as_bad (_("expected comma after register mode"));
4785 ignore_rest_of_line ();
4790 input_line_pointer
++;
4792 if (!strncmp (input_line_pointer
, "cannot_shortcut", 15))
4794 imode
|= ARC_REGISTER_NOSHORT_CUT
;
4795 input_line_pointer
+= 15;
4797 else if (strncmp (input_line_pointer
, "can_shortcut", 12))
4799 as_bad (_("shortcut designator invalid"));
4800 ignore_rest_of_line ();
4806 input_line_pointer
+= 12;
4809 demand_empty_rest_of_line ();
4812 ereg
->number
= number
;
4813 ereg
->imode
= imode
;
4817 /* Create an extension register/condition description in the arc
4818 extension section of the output file.
4820 The structure for an instruction is like this:
4821 [0]: Length of the record.
4822 [1]: Type of the record.
4824 For core regs and condition codes:
4828 For auxiliary registers:
4832 The sequence is terminated by an empty entry. */
4835 create_extcore_section (extRegister_t
*ereg
, int opertype
)
4837 segT old_sec
= now_seg
;
4838 int old_subsec
= now_subseg
;
4840 int name_len
= strlen (ereg
->name
);
4847 case EXT_CORE_REGISTER
:
4849 *p
= 3 + name_len
+ 1;
4855 case EXT_AUX_REGISTER
:
4857 *p
= 6 + name_len
+ 1;
4859 *p
= EXT_AUX_REGISTER
;
4861 *p
= (ereg
->number
>> 24) & 0xff;
4863 *p
= (ereg
->number
>> 16) & 0xff;
4865 *p
= (ereg
->number
>> 8) & 0xff;
4867 *p
= (ereg
->number
) & 0xff;
4873 p
= frag_more (name_len
+ 1);
4874 strcpy (p
, ereg
->name
);
4876 subseg_set (old_sec
, old_subsec
);
4879 /* Handler .extCoreRegister pseudo-op. */
4882 arc_extcorereg (int opertype
)
4885 struct arc_aux_reg
*auxr
;
4887 struct arc_flag_operand
*ccode
;
4889 memset (&ereg
, 0, sizeof (ereg
));
4890 if (!tokenize_extregister (&ereg
, opertype
))
4895 case EXT_CORE_REGISTER
:
4896 /* Core register. */
4897 if (ereg
.number
> 60)
4898 as_bad (_("core register %s value (%d) too large"), ereg
.name
,
4900 declare_register (ereg
.name
, ereg
.number
);
4902 case EXT_AUX_REGISTER
:
4903 /* Auxiliary register. */
4904 auxr
= XNEW (struct arc_aux_reg
);
4905 auxr
->name
= ereg
.name
;
4906 auxr
->cpu
= selected_cpu
.flags
;
4907 auxr
->subclass
= NONE
;
4908 auxr
->address
= ereg
.number
;
4909 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
4911 as_fatal (_("internal error: can't hash aux register '%s': %s"),
4912 auxr
->name
, retval
);
4915 /* Condition code. */
4916 if (ereg
.number
> 31)
4917 as_bad (_("condition code %s value (%d) too large"), ereg
.name
,
4919 ext_condcode
.size
++;
4920 ext_condcode
.arc_ext_condcode
=
4921 XRESIZEVEC (struct arc_flag_operand
, ext_condcode
.arc_ext_condcode
,
4922 ext_condcode
.size
+ 1);
4923 if (ext_condcode
.arc_ext_condcode
== NULL
)
4924 as_fatal (_("Virtual memory exhausted"));
4926 ccode
= ext_condcode
.arc_ext_condcode
+ ext_condcode
.size
- 1;
4927 ccode
->name
= ereg
.name
;
4928 ccode
->code
= ereg
.number
;
4931 ccode
->favail
= 0; /* not used. */
4933 memset (ccode
, 0, sizeof (struct arc_flag_operand
));
4936 as_bad (_("Unknown extension"));
4939 create_extcore_section (&ereg
, opertype
);
4942 /* Parse a .arc_attribute directive. */
4945 arc_attribute (int ignored ATTRIBUTE_UNUSED
)
4947 int tag
= obj_elf_vendor_attribute (OBJ_ATTR_PROC
);
4949 if (tag
< NUM_KNOWN_OBJ_ATTRIBUTES
)
4950 attributes_set_explicitly
[tag
] = TRUE
;
4953 /* Set an attribute if it has not already been set by the user. */
4956 arc_set_attribute_int (int tag
, int value
)
4959 || tag
>= NUM_KNOWN_OBJ_ATTRIBUTES
4960 || !attributes_set_explicitly
[tag
])
4961 bfd_elf_add_proc_attr_int (stdoutput
, tag
, value
);
4965 arc_set_attribute_string (int tag
, const char *value
)
4968 || tag
>= NUM_KNOWN_OBJ_ATTRIBUTES
4969 || !attributes_set_explicitly
[tag
])
4970 bfd_elf_add_proc_attr_string (stdoutput
, tag
, value
);
4973 /* Allocate and concatenate two strings. s1 can be NULL but not
4974 s2. s1 pointer is freed at end of this procedure. */
4977 arc_stralloc (char * s1
, const char * s2
)
4983 len
= strlen (s1
) + 1;
4985 /* Only s1 can be null. */
4987 len
+= strlen (s2
) + 1;
4989 p
= (char *) xmalloc (len
);
4991 as_fatal (_("Virtual memory exhausted"));
5006 /* Set the public ARC object attributes. */
5009 arc_set_public_attributes (void)
5015 /* Tag_ARC_CPU_name. */
5016 arc_set_attribute_string (Tag_ARC_CPU_name
, selected_cpu
.name
);
5018 /* Tag_ARC_CPU_base. */
5019 switch (selected_cpu
.eflags
& EF_ARC_MACH_MSK
)
5021 case E_ARC_MACH_ARC600
:
5022 case E_ARC_MACH_ARC601
:
5023 base
= TAG_CPU_ARC6xx
;
5025 case E_ARC_MACH_ARC700
:
5026 base
= TAG_CPU_ARC7xx
;
5028 case EF_ARC_CPU_ARCV2EM
:
5029 base
= TAG_CPU_ARCEM
;
5031 case EF_ARC_CPU_ARCV2HS
:
5032 base
= TAG_CPU_ARCHS
;
5038 if (attributes_set_explicitly
[Tag_ARC_CPU_base
]
5039 && (base
!= bfd_elf_get_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
5041 as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
5042 bfd_elf_add_proc_attr_int (stdoutput
, Tag_ARC_CPU_base
, base
);
5044 /* Tag_ARC_ABI_osver. */
5045 if (attributes_set_explicitly
[Tag_ARC_ABI_osver
])
5047 int val
= bfd_elf_get_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
5050 selected_cpu
.eflags
= ((selected_cpu
.eflags
& ~EF_ARC_OSABI_MSK
)
5051 | (val
& 0x0f << 8));
5055 arc_set_attribute_int (Tag_ARC_ABI_osver
, E_ARC_OSABI_CURRENT
>> 8);
5058 /* Tag_ARC_ISA_config. */
5059 arc_check_feature();
5061 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
5062 if (selected_cpu
.features
& feature_list
[i
].feature
)
5063 s
= arc_stralloc (s
, feature_list
[i
].attr
);
5066 arc_set_attribute_string (Tag_ARC_ISA_config
, s
);
5068 /* Tag_ARC_ISA_mpy_option. */
5069 arc_set_attribute_int (Tag_ARC_ISA_mpy_option
, mpy_option
);
5071 /* Tag_ARC_ABI_pic. */
5072 arc_set_attribute_int (Tag_ARC_ABI_pic
, pic_option
);
5074 /* Tag_ARC_ABI_sda. */
5075 arc_set_attribute_int (Tag_ARC_ABI_sda
, sda_option
);
5077 /* Tag_ARC_ABI_tls. */
5078 arc_set_attribute_int (Tag_ARC_ABI_tls
, tls_option
);
5080 /* Tag_ARC_ATR_version. */
5081 arc_set_attribute_int (Tag_ARC_ATR_version
, 1);
5083 /* Tag_ARC_ABI_rf16. */
5084 if (attributes_set_explicitly
[Tag_ARC_ABI_rf16
]
5085 && bfd_elf_get_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
5089 as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full "
5091 bfd_elf_add_proc_attr_int (stdoutput
, Tag_ARC_ABI_rf16
, 0);
5095 /* Add the default contents for the .ARC.attributes section. */
5100 arc_set_public_attributes ();
5102 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
5103 as_fatal (_("could not set architecture and machine"));
5105 bfd_set_private_flags (stdoutput
, selected_cpu
.eflags
);
5108 void arc_copy_symbol_attributes (symbolS
*dest
, symbolS
*src
)
5110 ARC_GET_FLAG (dest
) = ARC_GET_FLAG (src
);
5113 int arc_convert_symbolic_attribute (const char *name
)
5122 #define T(tag) {#tag, tag}
5123 T (Tag_ARC_PCS_config
),
5124 T (Tag_ARC_CPU_base
),
5125 T (Tag_ARC_CPU_variation
),
5126 T (Tag_ARC_CPU_name
),
5127 T (Tag_ARC_ABI_rf16
),
5128 T (Tag_ARC_ABI_osver
),
5129 T (Tag_ARC_ABI_sda
),
5130 T (Tag_ARC_ABI_pic
),
5131 T (Tag_ARC_ABI_tls
),
5132 T (Tag_ARC_ABI_enumsize
),
5133 T (Tag_ARC_ABI_exceptions
),
5134 T (Tag_ARC_ABI_double_size
),
5135 T (Tag_ARC_ISA_config
),
5136 T (Tag_ARC_ISA_apex
),
5137 T (Tag_ARC_ISA_mpy_option
),
5138 T (Tag_ARC_ATR_version
)
5146 for (i
= 0; i
< ARRAY_SIZE (attribute_table
); i
++)
5147 if (streq (name
, attribute_table
[i
].name
))
5148 return attribute_table
[i
].tag
;
5154 eval: (c-set-style "gnu")