1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2024 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 "hs38_linux"
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 == DBNZ \
113 || (op)->insn_class == EI \
114 || (op)->insn_class == ENTER \
115 || (op)->insn_class == JLI \
116 || (op)->insn_class == LOOP \
117 || (op)->insn_class == LEAVE \
119 #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL))
120 #define is_nps400_p(op) (((sc) == NPS400))
122 /* Generic assembler global variables which must be defined by all
125 /* Characters which always start a comment. */
126 const char comment_chars
[] = "#;";
128 /* Characters which start a comment at the beginning of a line. */
129 const char line_comment_chars
[] = "#";
131 /* Characters which may be used to separate multiple commands on a
133 const char line_separator_chars
[] = "`";
135 /* Characters which are used to indicate an exponent in a floating
137 const char EXP_CHARS
[] = "eE";
139 /* Chars that mean this number is a floating point constant
140 As in 0f12.456 or 0d1.2345e12. */
141 const char FLT_CHARS
[] = "rRsSfFdD";
144 extern int target_big_endian
;
145 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
146 static int byte_order
= DEFAULT_BYTE_ORDER
;
148 /* Arc extension section. */
149 static segT arcext_section
;
151 /* By default relaxation is disabled. */
152 static int relaxation_state
= 0;
154 extern int arc_get_mach (char *);
156 /* Forward declarations. */
157 static void arc_lcomm (int);
158 static void arc_option (int);
159 static void arc_extra_reloc (int);
160 static void arc_extinsn (int);
161 static void arc_extcorereg (int);
162 static void arc_attribute (int);
164 const pseudo_typeS md_pseudo_table
[] =
166 /* Make sure that .word is 32 bits. */
169 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
170 { "lcomm", arc_lcomm
, 0 },
171 { "lcommon", arc_lcomm
, 0 },
172 { "cpu", arc_option
, 0 },
174 { "arc_attribute", arc_attribute
, 0 },
175 { "extinstruction", arc_extinsn
, 0 },
176 { "extcoreregister", arc_extcorereg
, EXT_CORE_REGISTER
},
177 { "extauxregister", arc_extcorereg
, EXT_AUX_REGISTER
},
178 { "extcondcode", arc_extcorereg
, EXT_COND_CODE
},
180 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
181 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
186 const char *md_shortopts
= "";
190 OPTION_EB
= OPTION_MD_BASE
,
208 /* The following options are deprecated and provided here only for
209 compatibility reasons. */
232 struct option md_longopts
[] =
234 { "EB", no_argument
, NULL
, OPTION_EB
},
235 { "EL", no_argument
, NULL
, OPTION_EL
},
236 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
237 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
238 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
239 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
240 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
241 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
242 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
243 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
244 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
245 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
246 { "mnps400", no_argument
, NULL
, OPTION_NPS400
},
248 /* Floating point options */
249 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
250 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
251 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
252 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
253 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
254 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
255 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
256 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
257 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
258 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
259 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
261 /* The following options are deprecated and provided here only for
262 compatibility reasons. */
263 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
264 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
265 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
266 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
267 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
268 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
269 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
270 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
271 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
272 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
273 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
274 { "mea", no_argument
, NULL
, OPTION_EA
},
275 { "mEA", no_argument
, NULL
, OPTION_EA
},
276 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
277 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
278 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
279 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
280 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
281 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
282 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
283 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
284 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
285 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
286 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
287 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
288 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
289 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
290 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
292 { NULL
, no_argument
, NULL
, 0 }
295 size_t md_longopts_size
= sizeof (md_longopts
);
297 /* Local data and data types. */
299 /* Used since new relocation types are introduced in this
300 file (DUMMY_RELOC_LITUSE_*). */
301 typedef int extended_bfd_reloc_code_real_type
;
307 extended_bfd_reloc_code_real_type reloc
;
309 /* index into arc_operands. */
310 unsigned int opindex
;
312 /* PC-relative, used by internals fixups. */
315 /* TRUE if this fixup is for LIMM operand. */
321 unsigned long long int insn
;
323 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
325 unsigned int len
; /* Length of instruction in bytes. */
326 bool has_limm
; /* Boolean value: TRUE if limm field is valid. */
327 bool relax
; /* Boolean value: TRUE if needs relaxation. */
330 /* Structure to hold any last two instructions. */
331 static struct arc_last_insn
333 /* Saved instruction opcode. */
334 const struct arc_opcode
*opcode
;
336 /* Boolean value: TRUE if current insn is short. */
339 /* Boolean value: TRUE if current insn has delay slot. */
343 /* Extension instruction suffix classes. */
351 static const attributes_t suffixclass
[] =
353 { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG
},
354 { "SUFFIX_COND", 11, ARC_SUFFIX_COND
},
355 { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE
}
358 /* Extension instruction syntax classes. */
359 static const attributes_t syntaxclass
[] =
361 { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP
},
362 { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP
},
363 { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP
},
364 { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP
}
367 /* Extension instruction syntax classes modifiers. */
368 static const attributes_t syntaxclassmod
[] =
370 { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED
},
371 { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM
}
374 /* Extension register type. */
382 /* A structure to hold the additional conditional codes. */
385 struct arc_flag_operand
*arc_ext_condcode
;
387 } ext_condcode
= { NULL
, 0 };
389 /* Structure to hold an entry in ARC_OPCODE_HASH. */
390 struct arc_opcode_hash_entry
392 /* The number of pointers in the OPCODE list. */
395 /* Points to a list of opcode pointers. */
396 const struct arc_opcode
**opcode
;
399 /* Structure used for iterating through an arc_opcode_hash_entry. */
400 struct arc_opcode_hash_entry_iterator
402 /* Index into the OPCODE element of the arc_opcode_hash_entry. */
405 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
406 returned by this iterator. */
407 const struct arc_opcode
*opcode
;
410 /* Forward declaration. */
411 static void assemble_insn
412 (const struct arc_opcode
*, const expressionS
*, int,
413 const struct arc_flags
*, int, struct arc_insn
*);
415 /* The selection of the machine type can come from different sources. This
416 enum is used to track how the selection was made in order to perform
418 enum mach_selection_type
421 MACH_SELECTION_FROM_DEFAULT
,
422 MACH_SELECTION_FROM_CPU_DIRECTIVE
,
423 MACH_SELECTION_FROM_COMMAND_LINE
426 /* How the current machine type was selected. */
427 static enum mach_selection_type mach_selection_mode
= MACH_SELECTION_NONE
;
429 /* The hash table of instruction opcodes. */
430 static htab_t arc_opcode_hash
;
432 /* The hash table of register symbols. */
433 static htab_t arc_reg_hash
;
435 /* The hash table of aux register symbols. */
436 static htab_t arc_aux_hash
;
438 /* The hash table of address types. */
439 static htab_t arc_addrtype_hash
;
441 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \
442 { #NAME, ARC_OPCODE_ARC600, bfd_mach_arc_arc600, \
443 E_ARC_MACH_ARC600, EXTRA}
444 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \
445 { #NAME, ARC_OPCODE_ARC700, bfd_mach_arc_arc700, \
446 E_ARC_MACH_ARC700, EXTRA}
447 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \
448 { #NAME, ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2, \
449 EF_ARC_CPU_ARCV2EM, EXTRA}
450 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \
451 { #NAME, ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2, \
452 EF_ARC_CPU_ARCV2HS, EXTRA}
453 #define ARC_CPU_TYPE_NONE \
456 /* A table of CPU names and opcode sets. */
457 static const struct cpu_type
467 #include "elf/arc-cpu.def"
470 /* Information about the cpu/variant we're assembling for. */
471 static struct cpu_type selected_cpu
= { 0, 0, 0, E_ARC_OSABI_CURRENT
, 0 };
473 /* TRUE if current assembly code uses RF16 only registers. */
474 static bool rf16_only
= true;
477 static unsigned mpy_option
= 0;
480 static unsigned pic_option
= 0;
482 /* Use small data. */
483 static unsigned sda_option
= 0;
486 static unsigned tls_option
= 0;
488 /* Command line given features. */
489 static unsigned cl_features
= 0;
491 /* Used by the arc_reloc_op table. Order is important. */
492 #define O_gotoff O_md1 /* @gotoff relocation. */
493 #define O_gotpc O_md2 /* @gotpc relocation. */
494 #define O_plt O_md3 /* @plt relocation. */
495 #define O_sda O_md4 /* @sda relocation. */
496 #define O_pcl O_md5 /* @pcl relocation. */
497 #define O_tlsgd O_md6 /* @tlsgd relocation. */
498 #define O_tlsie O_md7 /* @tlsie relocation. */
499 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
500 #define O_tpoff O_md9 /* @tpoff relocation. */
501 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
502 #define O_dtpoff O_md11 /* @dtpoff relocation. */
503 #define O_last O_dtpoff
505 /* Used to define a bracket as operand in tokens. */
506 #define O_bracket O_md32
508 /* Used to define a colon as an operand in tokens. */
509 #define O_colon O_md31
511 /* Used to define address types in nps400. */
512 #define O_addrtype O_md30
514 /* Dummy relocation, to be sorted out. */
515 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
517 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
519 /* A table to map the spelling of a relocation operand into an appropriate
520 bfd_reloc_code_real_type type. The table is assumed to be ordered such
521 that op-O_literal indexes into it. */
522 #define ARC_RELOC_TABLE(op) \
523 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
525 : (int) (op) - (int) O_gotoff) ])
527 #define DEF(NAME, RELOC, REQ) \
528 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
530 static const struct arc_reloc_op_tag
532 /* String to lookup. */
534 /* Size of the string. */
536 /* Which operator to use. */
538 extended_bfd_reloc_code_real_type reloc
;
539 /* Allows complex relocation expression like identifier@reloc +
541 unsigned int complex_expr
: 1;
545 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
546 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
547 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
548 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
549 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
550 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
551 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
552 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
553 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
554 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
555 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 1),
558 static const int arc_num_reloc_op
559 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
561 /* Structure for relaxable instruction that have to be swapped with a
562 smaller alternative instruction. */
563 struct arc_relaxable_ins
565 /* Mnemonic that should be checked. */
566 const char *mnemonic_r
;
568 /* Operands that should be checked.
569 Indexes of operands from operand array. */
570 enum rlx_operand_type operands
[6];
572 /* Flags that should be checked. */
573 unsigned flag_classes
[5];
575 /* Mnemonic (smaller) alternative to be used later for relaxation. */
576 const char *mnemonic_alt
;
578 /* Index of operand that generic relaxation has to check. */
581 /* Base subtype index used. */
582 enum arc_rlx_types subtype
;
585 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
586 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
587 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
591 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
592 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
593 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
598 /* ARC relaxation table. */
599 const relax_typeS md_relax_table
[] =
606 RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL
),
607 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE
),
611 RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B
),
612 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE
),
617 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6
),
618 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM
),
619 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
621 /* LD_S a, [b, u7] ->
622 LD<zz><.x><.aa><.di> a, [b, s9] ->
623 LD<zz><.x><.aa><.di> a, [b, limm] */
624 RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9
),
625 RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM
),
626 RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE
),
631 RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12
),
632 RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM
),
633 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
637 SUB<.f> a, b, limm. */
638 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6
),
639 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM
),
640 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
642 /* MPY<.f> a, b, u6 ->
643 MPY<.f> a, b, limm. */
644 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM
),
645 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
647 /* MOV<.f><.cc> b, u6 ->
648 MOV<.f><.cc> b, limm. */
649 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM
),
650 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
652 /* ADD<.f><.cc> b, b, u6 ->
653 ADD<.f><.cc> b, b, limm. */
654 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM
),
655 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
658 /* Order of this table's entries matters! */
659 const struct arc_relaxable_ins arc_relaxable_insns
[] =
661 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
662 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
663 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
664 2, ARC_RLX_ADD_RRU6
},
665 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
667 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
669 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
670 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
671 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
672 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
673 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
674 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
675 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
676 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
678 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
680 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
684 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
686 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
687 symbolS
* GOT_symbol
= 0;
689 /* Set to TRUE when we assemble instructions. */
690 static bool assembling_insn
= false;
692 /* List with attributes set explicitly. */
693 static bool attributes_set_explicitly
[NUM_KNOWN_OBJ_ATTRIBUTES
];
695 /* Functions implementation. */
697 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
698 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
699 are no matching entries in ARC_OPCODE_HASH. */
701 static const struct arc_opcode_hash_entry
*
702 arc_find_opcode (const char *name
)
704 const struct arc_opcode_hash_entry
*entry
;
706 entry
= str_hash_find (arc_opcode_hash
, name
);
710 /* Initialise the iterator ITER. */
713 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator
*iter
)
719 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
720 calls to this function. Return NULL when all ARC_OPCODE entries have
723 static const struct arc_opcode
*
724 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry
*entry
,
725 struct arc_opcode_hash_entry_iterator
*iter
)
727 if (iter
->opcode
== NULL
&& iter
->index
== 0)
729 gas_assert (entry
->count
> 0);
730 iter
->opcode
= entry
->opcode
[iter
->index
];
732 else if (iter
->opcode
!= NULL
)
734 const char *old_name
= iter
->opcode
->name
;
737 if (iter
->opcode
->name
== NULL
738 || strcmp (old_name
, iter
->opcode
->name
) != 0)
741 if (iter
->index
== entry
->count
)
744 iter
->opcode
= entry
->opcode
[iter
->index
];
751 /* Insert an opcode into opcode hash structure. */
754 arc_insert_opcode (const struct arc_opcode
*opcode
)
757 struct arc_opcode_hash_entry
*entry
;
760 entry
= str_hash_find (arc_opcode_hash
, name
);
763 entry
= XNEW (struct arc_opcode_hash_entry
);
765 entry
->opcode
= NULL
;
767 if (str_hash_insert (arc_opcode_hash
, name
, entry
, 0) != NULL
)
768 as_fatal (_("duplicate %s"), name
);
771 entry
->opcode
= XRESIZEVEC (const struct arc_opcode
*, entry
->opcode
,
774 entry
->opcode
[entry
->count
] = opcode
;
779 arc_opcode_free (void *elt
)
781 string_tuple_t
*tuple
= (string_tuple_t
*) elt
;
782 struct arc_opcode_hash_entry
*entry
= (void *) tuple
->value
;
783 free (entry
->opcode
);
788 /* Like md_number_to_chars but for middle-endian values. The 4-byte limm
789 value, is encoded as 'middle-endian' for a little-endian target. This
790 function is used for regular 4, 6, and 8 byte instructions as well. */
793 md_number_to_chars_midend (char *buf
, unsigned long long val
, int n
)
798 md_number_to_chars (buf
, val
, n
);
801 md_number_to_chars (buf
, (val
& 0xffff00000000ull
) >> 32, 2);
802 md_number_to_chars_midend (buf
+ 2, (val
& 0xffffffff), 4);
805 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
806 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
809 md_number_to_chars_midend (buf
, (val
& 0xffffffff00000000ull
) >> 32, 4);
810 md_number_to_chars_midend (buf
+ 4, (val
& 0xffffffff), 4);
817 /* Check if a feature is allowed for a specific CPU. */
820 arc_check_feature (void)
824 if (!selected_cpu
.features
825 || !selected_cpu
.name
)
828 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
829 if ((selected_cpu
.features
& feature_list
[i
].feature
)
830 && !(selected_cpu
.flags
& feature_list
[i
].cpus
))
831 as_bad (_("invalid %s option for %s cpu"), feature_list
[i
].name
,
834 for (i
= 0; i
< ARRAY_SIZE (conflict_list
); i
++)
835 if ((selected_cpu
.features
& conflict_list
[i
]) == conflict_list
[i
])
836 as_bad(_("conflicting ISA extension attributes."));
839 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
840 the relevant static global variables. Parameter SEL describes where
841 this selection originated from. */
844 arc_select_cpu (const char *arg
, enum mach_selection_type sel
)
847 static struct cpu_type old_cpu
= { 0, 0, 0, E_ARC_OSABI_CURRENT
, 0 };
849 /* We should only set a default if we've not made a selection from some
851 gas_assert (sel
!= MACH_SELECTION_FROM_DEFAULT
852 || mach_selection_mode
== MACH_SELECTION_NONE
);
854 if ((mach_selection_mode
== MACH_SELECTION_FROM_CPU_DIRECTIVE
)
855 && (sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
))
856 as_bad (_("Multiple .cpu directives found"));
858 /* Look for a matching entry in CPU_TYPES array. */
859 for (i
= 0; cpu_types
[i
].name
; ++i
)
861 if (!strcasecmp (cpu_types
[i
].name
, arg
))
863 /* If a previous selection was made on the command line, then we
864 allow later selections on the command line to override earlier
865 ones. However, a selection from a '.cpu NAME' directive must
866 match the command line selection, or we give a warning. */
867 if (mach_selection_mode
== MACH_SELECTION_FROM_COMMAND_LINE
)
869 gas_assert (sel
== MACH_SELECTION_FROM_COMMAND_LINE
870 || sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
);
871 if (sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
872 && selected_cpu
.mach
!= cpu_types
[i
].mach
)
874 as_warn (_("Command-line value overrides \".cpu\" directive"));
878 /* Initialise static global data about selected machine type. */
879 selected_cpu
.flags
= cpu_types
[i
].flags
;
880 selected_cpu
.name
= cpu_types
[i
].name
;
881 selected_cpu
.features
= cpu_types
[i
].features
| cl_features
;
882 selected_cpu
.mach
= cpu_types
[i
].mach
;
883 selected_cpu
.eflags
= ((selected_cpu
.eflags
& ~EF_ARC_MACH_MSK
)
884 | cpu_types
[i
].eflags
);
889 if (!cpu_types
[i
].name
)
890 as_fatal (_("unknown architecture: %s\n"), arg
);
892 /* Check if set features are compatible with the chosen CPU. */
893 arc_check_feature ();
895 /* If we change the CPU, we need to re-init the bfd. */
896 if (mach_selection_mode
!= MACH_SELECTION_NONE
897 && (old_cpu
.mach
!= selected_cpu
.mach
))
899 bfd_find_target (arc_target_format
, stdoutput
);
900 if (! bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
901 as_warn (_("Could not set architecture and machine"));
904 mach_selection_mode
= sel
;
905 old_cpu
= selected_cpu
;
908 /* Here ends all the ARCompact extension instruction assembling
912 arc_extra_reloc (int r_type
)
915 symbolS
*sym
, *lab
= NULL
;
917 if (*input_line_pointer
== '@')
918 input_line_pointer
++;
919 c
= get_symbol_name (&sym_name
);
920 sym
= symbol_find_or_make (sym_name
);
921 restore_line_pointer (c
);
922 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
924 ++input_line_pointer
;
926 c
= get_symbol_name (&lab_name
);
927 lab
= symbol_find_or_make (lab_name
);
928 restore_line_pointer (c
);
931 /* These relocations exist as a mechanism for the compiler to tell the
932 linker how to patch the code if the tls model is optimised. However,
933 the relocation itself does not require any space within the assembler
934 fragment, and so we pass a size of 0.
936 The lines that generate these relocations look like this:
938 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
940 The '.tls_gd_ld @.tdata' is processed first and generates the
941 additional relocation, while the 'bl __tls_get_addr@plt' is processed
942 second and generates the additional branch.
944 It is possible that the additional relocation generated by the
945 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
946 while the 'bl __tls_get_addr@plt' will be generated as the first thing
947 in the next fragment. This will be fine; both relocations will still
948 appear to be at the same address in the generated object file.
949 However, this only works as the additional relocation is generated
950 with size of 0 bytes. */
952 = fix_new (frag_now
, /* Which frag? */
953 frag_now_fix (), /* Where in that frag? */
954 0, /* size: 1, 2, or 4 usually. */
955 sym
, /* X_add_symbol. */
956 0, /* X_add_number. */
957 false, /* TRUE if PC-relative relocation. */
958 r_type
/* Relocation type. */);
959 fixP
->fx_subsy
= lab
;
963 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
964 symbolS
*symbolP
, addressT size
)
969 if (*input_line_pointer
== ',')
971 align
= parse_align (1);
973 if (align
== (addressT
) -1)
988 bss_alloc (symbolP
, size
, align
);
989 S_CLEAR_EXTERNAL (symbolP
);
995 arc_lcomm (int ignore
)
997 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
1000 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1003 /* Select the cpu we're assembling for. */
1006 arc_option (int ignore ATTRIBUTE_UNUSED
)
1010 const char *cpu_name
;
1012 c
= get_symbol_name (&cpu
);
1015 if ((!strcmp ("ARC600", cpu
))
1016 || (!strcmp ("ARC601", cpu
))
1017 || (!strcmp ("A6", cpu
)))
1018 cpu_name
= "arc600";
1019 else if ((!strcmp ("ARC700", cpu
))
1020 || (!strcmp ("A7", cpu
)))
1021 cpu_name
= "arc700";
1022 else if (!strcmp ("EM", cpu
))
1024 else if (!strcmp ("HS", cpu
))
1026 else if (!strcmp ("NPS400", cpu
))
1027 cpu_name
= "nps400";
1029 arc_select_cpu (cpu_name
, MACH_SELECTION_FROM_CPU_DIRECTIVE
);
1031 restore_line_pointer (c
);
1032 demand_empty_rest_of_line ();
1035 /* Smartly print an expression. */
1038 debug_exp (expressionS
*t
)
1040 const char *name ATTRIBUTE_UNUSED
;
1041 const char *namemd ATTRIBUTE_UNUSED
;
1043 pr_debug ("debug_exp: ");
1047 default: name
= "unknown"; break;
1048 case O_illegal
: name
= "O_illegal"; break;
1049 case O_absent
: name
= "O_absent"; break;
1050 case O_constant
: name
= "O_constant"; break;
1051 case O_symbol
: name
= "O_symbol"; break;
1052 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1053 case O_register
: name
= "O_register"; break;
1054 case O_big
: name
= "O_big"; break;
1055 case O_uminus
: name
= "O_uminus"; break;
1056 case O_bit_not
: name
= "O_bit_not"; break;
1057 case O_logical_not
: name
= "O_logical_not"; break;
1058 case O_multiply
: name
= "O_multiply"; break;
1059 case O_divide
: name
= "O_divide"; break;
1060 case O_modulus
: name
= "O_modulus"; break;
1061 case O_left_shift
: name
= "O_left_shift"; break;
1062 case O_right_shift
: name
= "O_right_shift"; break;
1063 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1064 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1065 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1066 case O_bit_and
: name
= "O_bit_and"; break;
1067 case O_add
: name
= "O_add"; break;
1068 case O_subtract
: name
= "O_subtract"; break;
1069 case O_eq
: name
= "O_eq"; break;
1070 case O_ne
: name
= "O_ne"; break;
1071 case O_lt
: name
= "O_lt"; break;
1072 case O_le
: name
= "O_le"; break;
1073 case O_ge
: name
= "O_ge"; break;
1074 case O_gt
: name
= "O_gt"; break;
1075 case O_logical_and
: name
= "O_logical_and"; break;
1076 case O_logical_or
: name
= "O_logical_or"; break;
1077 case O_index
: name
= "O_index"; break;
1078 case O_bracket
: name
= "O_bracket"; break;
1079 case O_colon
: name
= "O_colon"; break;
1080 case O_addrtype
: name
= "O_addrtype"; break;
1085 default: namemd
= "unknown"; break;
1086 case O_gotoff
: namemd
= "O_gotoff"; break;
1087 case O_gotpc
: namemd
= "O_gotpc"; break;
1088 case O_plt
: namemd
= "O_plt"; break;
1089 case O_sda
: namemd
= "O_sda"; break;
1090 case O_pcl
: namemd
= "O_pcl"; break;
1091 case O_tlsgd
: namemd
= "O_tlsgd"; break;
1092 case O_tlsie
: namemd
= "O_tlsie"; break;
1093 case O_tpoff9
: namemd
= "O_tpoff9"; break;
1094 case O_tpoff
: namemd
= "O_tpoff"; break;
1095 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
1096 case O_dtpoff
: namemd
= "O_dtpoff"; break;
1099 pr_debug ("%s (%s, %s, %d, %s)", name
,
1100 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1101 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1102 (int) t
->X_add_number
,
1103 (t
->X_md
) ? namemd
: "--");
1108 /* Helper for parsing an argument, used for sorting out the relocation
1112 parse_reloc_symbol (expressionS
*resultP
)
1114 char *reloc_name
, c
, *sym_name
;
1117 const struct arc_reloc_op_tag
*r
;
1121 /* A relocation operand has the following form
1122 @identifier@relocation_type. The identifier is already in
1124 if (resultP
->X_op
!= O_symbol
)
1126 as_bad (_("No valid label relocation operand"));
1127 resultP
->X_op
= O_illegal
;
1131 /* Parse @relocation_type. */
1132 input_line_pointer
++;
1133 c
= get_symbol_name (&reloc_name
);
1134 len
= input_line_pointer
- reloc_name
;
1137 as_bad (_("No relocation operand"));
1138 resultP
->X_op
= O_illegal
;
1142 /* Go through known relocation and try to find a match. */
1143 r
= &arc_reloc_op
[0];
1144 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1145 if (len
== r
->length
1146 && memcmp (reloc_name
, r
->name
, len
) == 0)
1150 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
1151 resultP
->X_op
= O_illegal
;
1155 *input_line_pointer
= c
;
1156 SKIP_WHITESPACE_AFTER_NAME ();
1157 /* Extra check for TLS: base. */
1158 if (*input_line_pointer
== '@')
1160 if (resultP
->X_op_symbol
!= NULL
1161 || resultP
->X_op
!= O_symbol
)
1163 as_bad (_("Unable to parse TLS base: %s"),
1164 input_line_pointer
);
1165 resultP
->X_op
= O_illegal
;
1168 input_line_pointer
++;
1169 c
= get_symbol_name (&sym_name
);
1170 base
= symbol_find_or_make (sym_name
);
1171 resultP
->X_op
= O_subtract
;
1172 resultP
->X_op_symbol
= base
;
1173 restore_line_pointer (c
);
1174 right
.X_add_number
= 0;
1177 if ((*input_line_pointer
!= '+')
1178 && (*input_line_pointer
!= '-'))
1179 right
.X_add_number
= 0;
1182 /* Parse the constant of a complex relocation expression
1183 like @identifier@reloc +/- const. */
1184 if (! r
->complex_expr
)
1186 as_bad (_("@%s is not a complex relocation."), r
->name
);
1187 resultP
->X_op
= O_illegal
;
1190 expression (&right
);
1191 if (right
.X_op
!= O_constant
)
1193 as_bad (_("Bad expression: @%s + %s."),
1194 r
->name
, input_line_pointer
);
1195 resultP
->X_op
= O_illegal
;
1200 resultP
->X_md
= r
->op
;
1201 resultP
->X_add_number
= right
.X_add_number
;
1204 /* Parse the arguments to an opcode. */
1207 tokenize_arguments (char *str
,
1211 char *old_input_line_pointer
;
1212 bool saw_comma
= false;
1213 bool saw_arg
= false;
1217 memset (tok
, 0, sizeof (*tok
) * ntok
);
1219 /* Save and restore input_line_pointer around this function. */
1220 old_input_line_pointer
= input_line_pointer
;
1221 input_line_pointer
= str
;
1223 while (*input_line_pointer
)
1226 switch (*input_line_pointer
)
1232 input_line_pointer
++;
1233 if (saw_comma
|| !saw_arg
)
1240 ++input_line_pointer
;
1242 if (!saw_arg
|| num_args
== ntok
)
1244 tok
->X_op
= O_bracket
;
1251 input_line_pointer
++;
1252 if (brk_lvl
|| num_args
== ntok
)
1255 tok
->X_op
= O_bracket
;
1261 input_line_pointer
++;
1262 if (!saw_arg
|| num_args
== ntok
)
1264 tok
->X_op
= O_colon
;
1271 /* We have labels, function names and relocations, all
1272 starting with @ symbol. Sort them out. */
1273 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1277 input_line_pointer
++;
1278 tok
->X_op
= O_symbol
;
1279 tok
->X_md
= O_absent
;
1282 if (*input_line_pointer
== '@')
1283 parse_reloc_symbol (tok
);
1287 if (tok
->X_op
== O_illegal
1288 || tok
->X_op
== O_absent
1289 || num_args
== ntok
)
1299 /* Can be a register. */
1300 ++input_line_pointer
;
1304 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1307 tok
->X_op
= O_absent
;
1308 tok
->X_md
= O_absent
;
1311 /* Legacy: There are cases when we have
1312 identifier@relocation_type, if it is the case parse the
1313 relocation type as well. */
1314 if (*input_line_pointer
== '@')
1315 parse_reloc_symbol (tok
);
1317 resolve_register (tok
);
1321 if (tok
->X_op
== O_illegal
1322 || tok
->X_op
== O_absent
1323 || num_args
== ntok
)
1335 if (saw_comma
|| brk_lvl
)
1337 input_line_pointer
= old_input_line_pointer
;
1343 as_bad (_("Brackets in operand field incorrect"));
1345 as_bad (_("extra comma"));
1347 as_bad (_("missing argument"));
1349 as_bad (_("missing comma or colon"));
1350 input_line_pointer
= old_input_line_pointer
;
1354 /* Parse the flags to a structure. */
1357 tokenize_flags (const char *str
,
1358 struct arc_flags flags
[],
1361 char *old_input_line_pointer
;
1362 bool saw_flg
= false;
1363 bool saw_dot
= false;
1367 memset (flags
, 0, sizeof (*flags
) * nflg
);
1369 /* Save and restore input_line_pointer around this function. */
1370 old_input_line_pointer
= input_line_pointer
;
1371 input_line_pointer
= (char *) str
;
1373 while (*input_line_pointer
)
1375 switch (*input_line_pointer
)
1382 input_line_pointer
++;
1390 if (saw_flg
&& !saw_dot
)
1393 if (num_flags
>= nflg
)
1396 flgnamelen
= strspn (input_line_pointer
,
1397 "abcdefghijklmnopqrstuvwxyz0123456789");
1398 if (flgnamelen
> MAX_FLAG_NAME_LENGTH
)
1401 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1403 input_line_pointer
+= flgnamelen
;
1413 input_line_pointer
= old_input_line_pointer
;
1418 as_bad (_("extra dot"));
1420 as_bad (_("unrecognized flag"));
1422 as_bad (_("failed to parse flags"));
1423 input_line_pointer
= old_input_line_pointer
;
1427 /* Apply the fixups in order. */
1430 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1434 for (i
= 0; i
< insn
->nfixups
; i
++)
1436 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1437 int size
, pcrel
, offset
= 0;
1439 /* FIXME! the reloc size is wrong in the BFD file.
1440 When it is fixed please delete me. */
1441 size
= ((insn
->len
== 2) && !fixup
->islong
) ? 2 : 4;
1446 /* Some fixups are only used internally, thus no howto. */
1447 if ((int) fixup
->reloc
== 0)
1448 as_fatal (_("Unhandled reloc type"));
1450 if ((int) fixup
->reloc
< 0)
1452 /* FIXME! the reloc size is wrong in the BFD file.
1453 When it is fixed please enable me.
1454 size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
1455 pcrel
= fixup
->pcrel
;
1459 reloc_howto_type
*reloc_howto
=
1460 bfd_reloc_type_lookup (stdoutput
,
1461 (bfd_reloc_code_real_type
) fixup
->reloc
);
1462 gas_assert (reloc_howto
);
1464 /* FIXME! the reloc size is wrong in the BFD file.
1465 When it is fixed please enable me.
1466 size = bfd_get_reloc_size (reloc_howto); */
1467 pcrel
= reloc_howto
->pc_relative
;
1470 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1472 fragP
->fr_file
, fragP
->fr_line
,
1473 (fixup
->reloc
< 0) ? "Internal" :
1474 bfd_get_reloc_code_name (fixup
->reloc
),
1477 fix_new_exp (fragP
, fix
+ offset
,
1478 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1480 /* Check for ZOLs, and update symbol info if any. */
1481 if (LP_INSN (insn
->insn
))
1483 gas_assert (fixup
->exp
.X_add_symbol
);
1484 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1489 /* Actually output an instruction with its fixup. */
1492 emit_insn0 (struct arc_insn
*insn
, char *where
, bool relax
)
1497 pr_debug ("Emit insn : 0x%llx\n", insn
->insn
);
1498 pr_debug ("\tLength : %d\n", insn
->len
);
1499 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1501 /* Write out the instruction. */
1502 total_len
= insn
->len
+ (insn
->has_limm
? 4 : 0);
1504 f
= frag_more (total_len
);
1506 md_number_to_chars_midend(f
, insn
->insn
, insn
->len
);
1509 md_number_to_chars_midend (f
+ insn
->len
, insn
->limm
, 4);
1510 dwarf2_emit_insn (total_len
);
1513 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1517 emit_insn1 (struct arc_insn
*insn
)
1519 /* How frag_var's args are currently configured:
1520 - rs_machine_dependent, to dictate it's a relaxation frag.
1521 - FRAG_MAX_GROWTH, maximum size of instruction
1522 - 0, variable size that might grow...unused by generic relaxation.
1523 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1524 - s, opand expression.
1525 - 0, offset but it's unused.
1526 - 0, opcode but it's unused. */
1527 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1528 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1530 if (frag_room () < FRAG_MAX_GROWTH
)
1532 /* Handle differently when frag literal memory is exhausted.
1533 This is used because when there's not enough memory left in
1534 the current frag, a new frag is created and the information
1535 we put into frag_now->tc_frag_data is disregarded. */
1537 struct arc_relax_type relax_info_copy
;
1538 relax_substateT subtype
= frag_now
->fr_subtype
;
1540 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1541 sizeof (struct arc_relax_type
));
1543 frag_wane (frag_now
);
1544 frag_grow (FRAG_MAX_GROWTH
);
1546 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1547 sizeof (struct arc_relax_type
));
1549 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1553 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1554 frag_now
->fr_subtype
, s
, 0, 0);
1558 emit_insn (struct arc_insn
*insn
)
1563 emit_insn0 (insn
, NULL
, false);
1566 /* Check whether a symbol involves a register. */
1569 contains_register (symbolS
*sym
)
1573 expressionS
*ex
= symbol_get_value_expression (sym
);
1575 return ((O_register
== ex
->X_op
)
1576 && !contains_register (ex
->X_add_symbol
)
1577 && !contains_register (ex
->X_op_symbol
));
1583 /* Returns the register number within a symbol. */
1586 get_register (symbolS
*sym
)
1588 if (!contains_register (sym
))
1591 expressionS
*ex
= symbol_get_value_expression (sym
);
1592 return regno (ex
->X_add_number
);
1595 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1596 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1599 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1606 case BFD_RELOC_ARC_SDA_LDST
:
1607 case BFD_RELOC_ARC_SDA_LDST1
:
1608 case BFD_RELOC_ARC_SDA_LDST2
:
1609 case BFD_RELOC_ARC_SDA16_LD
:
1610 case BFD_RELOC_ARC_SDA16_LD1
:
1611 case BFD_RELOC_ARC_SDA16_LD2
:
1612 case BFD_RELOC_ARC_SDA16_ST2
:
1613 case BFD_RELOC_ARC_SDA32_ME
:
1620 /* Allocates a tok entry. */
1623 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1625 if (ntok
> MAX_INSN_ARGS
- 2)
1626 return 0; /* No space left. */
1629 return 0; /* Incorrect args. */
1631 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1634 return 1; /* Success. */
1635 return allocate_tok (tok
, ntok
- 1, cidx
);
1638 /* Check if an particular ARC feature is enabled. */
1641 check_cpu_feature (insn_subclass_t sc
)
1643 if (is_code_density_p (sc
) && !(selected_cpu
.features
& CD
))
1646 if (is_spfp_p (sc
) && !(selected_cpu
.features
& SPX
))
1649 if (is_dpfp_p (sc
) && !(selected_cpu
.features
& DPX
))
1652 if (is_fpuda_p (sc
) && !(selected_cpu
.features
& DPA
))
1655 if (is_nps400_p (sc
) && !(selected_cpu
.features
& NPS400
))
1661 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1662 operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG
1663 array and returns TRUE if the flag operands all match, otherwise,
1664 returns FALSE, in which case the FIRST_PFLAG array may have been
1668 parse_opcode_flags (const struct arc_opcode
*opcode
,
1670 struct arc_flags
*first_pflag
)
1673 const unsigned char *flgidx
;
1676 for (i
= 0; i
< nflgs
; i
++)
1677 first_pflag
[i
].flgp
= NULL
;
1679 /* Check the flags. Iterate over the valid flag classes. */
1680 for (flgidx
= opcode
->flags
; *flgidx
; ++flgidx
)
1682 /* Get a valid flag class. */
1683 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1684 const unsigned *flgopridx
;
1686 struct arc_flags
*pflag
= NULL
;
1688 /* Check if opcode has implicit flag classes. */
1689 if (cl_flags
->flag_class
& F_CLASS_IMPLICIT
)
1692 /* Check for extension conditional codes. */
1693 if (ext_condcode
.arc_ext_condcode
1694 && cl_flags
->flag_class
& F_CLASS_EXTEND
)
1696 struct arc_flag_operand
*pf
= ext_condcode
.arc_ext_condcode
;
1699 pflag
= first_pflag
;
1700 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1702 if (!strcmp (pf
->name
, pflag
->name
))
1704 if (pflag
->flgp
!= NULL
)
1717 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1719 const struct arc_flag_operand
*flg_operand
;
1721 pflag
= first_pflag
;
1722 flg_operand
= &arc_flag_operands
[*flgopridx
];
1723 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1725 /* Match against the parsed flags. */
1726 if (!strcmp (flg_operand
->name
, pflag
->name
))
1728 if (pflag
->flgp
!= NULL
)
1731 pflag
->flgp
= flg_operand
;
1733 break; /* goto next flag class and parsed flag. */
1738 if ((cl_flags
->flag_class
& F_CLASS_REQUIRED
) && cl_matches
== 0)
1740 if ((cl_flags
->flag_class
& F_CLASS_OPTIONAL
) && cl_matches
> 1)
1744 /* Did I check all the parsed flags? */
1749 /* Search forward through all variants of an opcode looking for a
1752 static const struct arc_opcode
*
1753 find_opcode_match (const struct arc_opcode_hash_entry
*entry
,
1756 struct arc_flags
*first_pflag
,
1759 const char **errmsg
)
1761 const struct arc_opcode
*opcode
;
1762 struct arc_opcode_hash_entry_iterator iter
;
1764 int got_cpu_match
= 0;
1765 expressionS bktok
[MAX_INSN_ARGS
];
1766 int bkntok
, maxerridx
= 0;
1768 const char *tmpmsg
= NULL
;
1770 arc_opcode_hash_entry_iterator_init (&iter
);
1771 memset (&emptyE
, 0, sizeof (emptyE
));
1772 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1775 for (opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
);
1777 opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
))
1779 const unsigned char *opidx
;
1781 const expressionS
*t
= &emptyE
;
1783 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
1784 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1786 /* Don't match opcodes that don't exist on this
1788 if (!(opcode
->cpu
& selected_cpu
.flags
))
1791 if (!check_cpu_feature (opcode
->subclass
))
1797 /* Check the operands. */
1798 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1800 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1802 /* Only take input from real operands. */
1803 if (ARC_OPERAND_IS_FAKE (operand
))
1806 /* When we expect input, make sure we have it. */
1810 /* Match operand type with expression type. */
1811 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1813 case ARC_OPERAND_ADDRTYPE
:
1817 /* Check to be an address type. */
1818 if (tok
[tokidx
].X_op
!= O_addrtype
)
1821 /* All address type operands need to have an insert
1822 method in order to check that we have the correct
1824 gas_assert (operand
->insert
!= NULL
);
1825 (*operand
->insert
) (0, tok
[tokidx
].X_add_number
,
1832 case ARC_OPERAND_IR
:
1833 /* Check to be a register. */
1834 if ((tok
[tokidx
].X_op
!= O_register
1835 || !is_ir_num (tok
[tokidx
].X_add_number
))
1836 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1839 /* If expect duplicate, make sure it is duplicate. */
1840 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1842 /* Check for duplicate. */
1843 if (t
->X_op
!= O_register
1844 || !is_ir_num (t
->X_add_number
)
1845 || (regno (t
->X_add_number
) !=
1846 regno (tok
[tokidx
].X_add_number
)))
1850 /* Special handling? */
1851 if (operand
->insert
)
1854 (*operand
->insert
)(0,
1855 regno (tok
[tokidx
].X_add_number
),
1859 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1861 /* Missing argument, create one. */
1862 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1865 tok
[tokidx
].X_op
= O_absent
;
1876 case ARC_OPERAND_BRAKET
:
1877 /* Check if bracket is also in opcode table as
1879 if (tok
[tokidx
].X_op
!= O_bracket
)
1883 case ARC_OPERAND_COLON
:
1884 /* Check if colon is also in opcode table as operand. */
1885 if (tok
[tokidx
].X_op
!= O_colon
)
1889 case ARC_OPERAND_LIMM
:
1890 case ARC_OPERAND_SIGNED
:
1891 case ARC_OPERAND_UNSIGNED
:
1892 switch (tok
[tokidx
].X_op
)
1900 /* Got an (too) early bracket, check if it is an
1901 ignored operand. N.B. This procedure works only
1902 when bracket is the last operand! */
1903 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1905 /* Insert the missing operand. */
1906 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1909 tok
[tokidx
].X_op
= O_absent
;
1917 const struct arc_aux_reg
*auxr
;
1919 if (opcode
->insn_class
!= AUXREG
)
1921 p
= S_GET_NAME (tok
[tokidx
].X_add_symbol
);
1923 /* For compatibility reasons, an aux register can
1924 be spelled with upper or lower case
1927 for (pp
= tmpp
; *pp
; ++pp
) *pp
= TOLOWER (*pp
);
1929 auxr
= str_hash_find (arc_aux_hash
, tmpp
);
1932 /* We modify the token array here, safe in the
1933 knowledge, that if this was the wrong
1934 choice then the original contents will be
1935 restored from BKTOK. */
1936 tok
[tokidx
].X_op
= O_constant
;
1937 tok
[tokidx
].X_add_number
= auxr
->address
;
1938 ARC_SET_FLAG (tok
[tokidx
].X_add_symbol
, ARC_FLAG_AUX
);
1942 if (tok
[tokidx
].X_op
!= O_constant
)
1947 /* Check the range. */
1948 if (operand
->bits
!= 32
1949 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1951 offsetT min
, max
, val
;
1952 val
= tok
[tokidx
].X_add_number
;
1954 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1956 max
= (1 << (operand
->bits
- 1)) - 1;
1957 min
= -(1 << (operand
->bits
- 1));
1961 max
= (1 << operand
->bits
) - 1;
1965 if (val
< min
|| val
> max
)
1967 tmpmsg
= _("immediate is out of bounds");
1971 /* Check alignments. */
1972 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1975 tmpmsg
= _("immediate is not 32bit aligned");
1979 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1982 tmpmsg
= _("immediate is not 16bit aligned");
1986 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1988 if (operand
->insert
)
1991 (*operand
->insert
)(0,
1992 tok
[tokidx
].X_add_number
,
1997 else if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
2003 /* Check if it is register range. */
2004 if ((tok
[tokidx
].X_add_number
== 0)
2005 && contains_register (tok
[tokidx
].X_add_symbol
)
2006 && contains_register (tok
[tokidx
].X_op_symbol
))
2010 regs
= get_register (tok
[tokidx
].X_add_symbol
);
2012 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
2013 if (operand
->insert
)
2016 (*operand
->insert
)(0,
2029 if (operand
->default_reloc
== 0)
2030 goto match_failed
; /* The operand needs relocation. */
2032 /* Relocs requiring long immediate. FIXME! make it
2033 generic and move it to a function. */
2034 switch (tok
[tokidx
].X_md
)
2043 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
2047 if (!generic_reloc_p (operand
->default_reloc
))
2055 /* If expect duplicate, make sure it is duplicate. */
2056 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
2058 if (t
->X_op
== O_illegal
2059 || t
->X_op
== O_absent
2060 || t
->X_op
== O_register
2061 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
2063 tmpmsg
= _("operand is not duplicate of the "
2072 /* Everything else should have been fake. */
2080 /* Setup ready for flag parsing. */
2081 if (!parse_opcode_flags (opcode
, nflgs
, first_pflag
))
2083 tmpmsg
= _("flag mismatch");
2088 /* Possible match -- did we use all of our input? */
2095 tmpmsg
= _("too many arguments");
2099 /* Restore the original parameters. */
2100 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
2102 if (tokidx
>= maxerridx
2111 *pcpumatch
= got_cpu_match
;
2116 /* Swap operand tokens. */
2119 swap_operand (expressionS
*operand_array
,
2121 unsigned destination
)
2123 expressionS cpy_operand
;
2124 expressionS
*src_operand
;
2125 expressionS
*dst_operand
;
2128 if (source
== destination
)
2131 src_operand
= &operand_array
[source
];
2132 dst_operand
= &operand_array
[destination
];
2133 size
= sizeof (expressionS
);
2135 /* Make copy of operand to swap with and swap. */
2136 memcpy (&cpy_operand
, dst_operand
, size
);
2137 memcpy (dst_operand
, src_operand
, size
);
2138 memcpy (src_operand
, &cpy_operand
, size
);
2141 /* Check if *op matches *tok type.
2142 Returns FALSE if they don't match, TRUE if they match. */
2145 pseudo_operand_match (const expressionS
*tok
,
2146 const struct arc_operand_operation
*op
)
2148 offsetT min
, max
, val
;
2150 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
2156 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
2158 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
2160 val
= tok
->X_add_number
+ op
->count
;
2161 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
2163 max
= (1 << (operand_real
->bits
- 1)) - 1;
2164 min
= -(1 << (operand_real
->bits
- 1));
2168 max
= (1 << operand_real
->bits
) - 1;
2171 if (min
<= val
&& val
<= max
)
2177 /* Handle all symbols as long immediates or signed 9. */
2178 if (operand_real
->flags
& ARC_OPERAND_LIMM
2179 || ((operand_real
->flags
& ARC_OPERAND_SIGNED
)
2180 && operand_real
->bits
== 9))
2185 if (operand_real
->flags
& ARC_OPERAND_IR
)
2190 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2201 /* Find pseudo instruction in array. */
2203 static const struct arc_pseudo_insn
*
2204 find_pseudo_insn (const char *opname
,
2206 const expressionS
*tok
)
2208 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2209 const struct arc_operand_operation
*op
;
2213 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
2215 pseudo_insn
= &arc_pseudo_insns
[i
];
2216 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
2218 op
= pseudo_insn
->operand
;
2219 for (j
= 0; j
< ntok
; ++j
)
2220 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
2223 /* Found the right instruction. */
2231 /* Assumes the expressionS *tok is of sufficient size. */
2233 static const struct arc_opcode_hash_entry
*
2234 find_special_case_pseudo (const char *opname
,
2238 struct arc_flags
*pflags
)
2240 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2241 const struct arc_operand_operation
*operand_pseudo
;
2242 const struct arc_operand
*operand_real
;
2244 char construct_operand
[MAX_CONSTR_STR
];
2246 /* Find whether opname is in pseudo instruction array. */
2247 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
2249 if (pseudo_insn
== NULL
)
2252 /* Handle flag, Limited to one flag at the moment. */
2253 if (pseudo_insn
->flag_r
!= NULL
)
2254 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
2255 MAX_INSN_FLGS
- *nflgs
);
2257 /* Handle operand operations. */
2258 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2260 operand_pseudo
= &pseudo_insn
->operand
[i
];
2261 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
2263 if (operand_real
->flags
& ARC_OPERAND_BRAKET
2264 && !operand_pseudo
->needs_insert
)
2267 /* Has to be inserted (i.e. this token does not exist yet). */
2268 if (operand_pseudo
->needs_insert
)
2270 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2272 tok
[i
].X_op
= O_bracket
;
2277 /* Check if operand is a register or constant and handle it
2279 if (operand_real
->flags
& ARC_OPERAND_IR
)
2280 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
2281 operand_pseudo
->count
);
2283 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
2284 operand_pseudo
->count
);
2286 tokenize_arguments (construct_operand
, &tok
[i
], 1);
2290 else if (operand_pseudo
->count
)
2292 /* Operand number has to be adjusted accordingly (by operand
2294 switch (tok
[i
].X_op
)
2297 tok
[i
].X_add_number
+= operand_pseudo
->count
;
2310 /* Swap operands if necessary. Only supports one swap at the
2312 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2314 operand_pseudo
= &pseudo_insn
->operand
[i
];
2316 if (operand_pseudo
->swap_operand_idx
== i
)
2319 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
2321 /* Prevent a swap back later by breaking out. */
2325 return arc_find_opcode (pseudo_insn
->mnemonic_r
);
2328 static const struct arc_opcode_hash_entry
*
2329 find_special_case_flag (const char *opname
,
2331 struct arc_flags
*pflags
)
2335 unsigned flag_idx
, flag_arr_idx
;
2336 size_t flaglen
, oplen
;
2337 const struct arc_flag_special
*arc_flag_special_opcode
;
2338 const struct arc_opcode_hash_entry
*entry
;
2340 /* Search for special case instruction. */
2341 for (i
= 0; i
< arc_num_flag_special
; i
++)
2343 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
2344 oplen
= strlen (arc_flag_special_opcode
->name
);
2346 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
2349 /* Found a potential special case instruction, now test for
2351 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
2353 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
2355 break; /* End of array, nothing found. */
2357 flagnm
= arc_flag_operands
[flag_idx
].name
;
2358 flaglen
= strlen (flagnm
);
2359 if (strcmp (opname
+ oplen
, flagnm
) == 0)
2361 entry
= arc_find_opcode (arc_flag_special_opcode
->name
);
2363 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
2365 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
2366 pflags
[*nflgs
].name
[flaglen
] = '\0';
2375 /* Used to find special case opcode. */
2377 static const struct arc_opcode_hash_entry
*
2378 find_special_case (const char *opname
,
2380 struct arc_flags
*pflags
,
2384 const struct arc_opcode_hash_entry
*entry
;
2386 entry
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
2389 entry
= find_special_case_flag (opname
, nflgs
, pflags
);
2394 /* Autodetect cpu attribute list. */
2397 autodetect_attributes (const struct arc_opcode
*opcode
,
2398 const expressionS
*tok
,
2406 } mpy_list
[] = {{ MPY1E
, 1 }, { MPY6E
, 6 }, { MPY7E
, 7 }, { MPY8E
, 8 },
2409 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
2410 if (opcode
->subclass
== feature_list
[i
].feature
)
2411 selected_cpu
.features
|= feature_list
[i
].feature
;
2413 for (i
= 0; i
< ARRAY_SIZE (mpy_list
); i
++)
2414 if (opcode
->subclass
== mpy_list
[i
].feature
)
2415 mpy_option
= mpy_list
[i
].encoding
;
2417 for (i
= 0; i
< (unsigned) ntok
; i
++)
2419 switch (tok
[i
].X_md
)
2441 switch (tok
[i
].X_op
)
2444 if ((tok
[i
].X_add_number
>= 4 && tok
[i
].X_add_number
<= 9)
2445 || (tok
[i
].X_add_number
>= 16 && tok
[i
].X_add_number
<= 25))
2454 /* Given an opcode name, pre-tockenized set of argumenst and the
2455 opcode flags, take it all the way through emission. */
2458 assemble_tokens (const char *opname
,
2461 struct arc_flags
*pflags
,
2464 bool found_something
= false;
2465 const struct arc_opcode_hash_entry
*entry
;
2467 const char *errmsg
= NULL
;
2469 /* Search opcodes. */
2470 entry
= arc_find_opcode (opname
);
2472 /* Couldn't find opcode conventional way, try special cases. */
2474 entry
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
2478 const struct arc_opcode
*opcode
;
2480 pr_debug ("%s:%d: assemble_tokens: %s\n",
2481 frag_now
->fr_file
, frag_now
->fr_line
, opname
);
2482 found_something
= true;
2483 opcode
= find_opcode_match (entry
, tok
, &ntok
, pflags
,
2484 nflgs
, &cpumatch
, &errmsg
);
2487 struct arc_insn insn
;
2489 autodetect_attributes (opcode
, tok
, ntok
);
2490 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
2496 if (found_something
)
2500 as_bad (_("%s for instruction '%s'"), errmsg
, opname
);
2502 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
2504 as_bad (_("opcode '%s' not supported for target %s"), opname
,
2508 as_bad (_("unknown opcode '%s'"), opname
);
2511 /* The public interface to the instruction assembler. */
2514 md_assemble (char *str
)
2517 expressionS tok
[MAX_INSN_ARGS
];
2520 struct arc_flags flags
[MAX_INSN_FLGS
];
2522 /* Split off the opcode. */
2523 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123456789");
2524 opname
= xmemdup0 (str
, opnamelen
);
2526 /* Signalize we are assembling the instructions. */
2527 assembling_insn
= true;
2529 /* Tokenize the flags. */
2530 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2532 as_bad (_("syntax error"));
2536 /* Scan up to the end of the mnemonic which must end in space or end
2539 for (; *str
!= '\0'; str
++)
2543 /* Tokenize the rest of the line. */
2544 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2546 as_bad (_("syntax error"));
2550 /* Finish it off. */
2551 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2552 assembling_insn
= false;
2555 /* Callback to insert a register into the hash table. */
2558 declare_register (const char *name
, int number
)
2560 symbolS
*regS
= symbol_create (name
, reg_section
,
2561 &zero_address_frag
, number
);
2563 if (str_hash_insert (arc_reg_hash
, S_GET_NAME (regS
), regS
, 0) != NULL
)
2564 as_fatal (_("duplicate %s"), name
);
2567 /* Construct symbols for each of the general registers. */
2570 declare_register_set (void)
2573 for (i
= 0; i
< 64; ++i
)
2577 sprintf (name
, "r%d", i
);
2578 declare_register (name
, i
);
2579 if ((i
& 0x01) == 0)
2581 sprintf (name
, "r%dr%d", i
, i
+1);
2582 declare_register (name
, i
);
2587 /* Construct a symbol for an address type. */
2590 declare_addrtype (const char *name
, int number
)
2592 symbolS
*addrtypeS
= symbol_create (name
, undefined_section
,
2593 &zero_address_frag
, number
);
2595 if (str_hash_insert (arc_addrtype_hash
, S_GET_NAME (addrtypeS
), addrtypeS
, 0))
2596 as_fatal (_("duplicate %s"), name
);
2599 /* Port-specific assembler initialization. This function is called
2600 once, at assembler startup time. */
2605 const struct arc_opcode
*opcode
= arc_opcodes
;
2607 if (mach_selection_mode
== MACH_SELECTION_NONE
)
2608 arc_select_cpu (TARGET_WITH_CPU
, MACH_SELECTION_FROM_DEFAULT
);
2610 /* The endianness can be chosen "at the factory". */
2611 target_big_endian
= byte_order
== BIG_ENDIAN
;
2613 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
2614 as_warn (_("could not set architecture and machine"));
2616 /* Set elf header flags. */
2617 bfd_set_private_flags (stdoutput
, selected_cpu
.eflags
);
2619 /* Set up a hash table for the instructions. */
2620 arc_opcode_hash
= htab_create_alloc (16, hash_string_tuple
, eq_string_tuple
,
2621 arc_opcode_free
, xcalloc
, free
);
2623 /* Initialize the hash table with the insns. */
2626 const char *name
= opcode
->name
;
2628 arc_insert_opcode (opcode
);
2630 while (++opcode
&& opcode
->name
2631 && (opcode
->name
== name
2632 || !strcmp (opcode
->name
, name
)))
2634 }while (opcode
->name
);
2636 /* Register declaration. */
2637 arc_reg_hash
= str_htab_create ();
2639 declare_register_set ();
2640 declare_register ("gp", 26);
2641 declare_register ("fp", 27);
2642 declare_register ("sp", 28);
2643 declare_register ("ilink", 29);
2644 declare_register ("ilink1", 29);
2645 declare_register ("ilink2", 30);
2646 declare_register ("blink", 31);
2648 /* XY memory registers. */
2649 declare_register ("x0_u0", 32);
2650 declare_register ("x0_u1", 33);
2651 declare_register ("x1_u0", 34);
2652 declare_register ("x1_u1", 35);
2653 declare_register ("x2_u0", 36);
2654 declare_register ("x2_u1", 37);
2655 declare_register ("x3_u0", 38);
2656 declare_register ("x3_u1", 39);
2657 declare_register ("y0_u0", 40);
2658 declare_register ("y0_u1", 41);
2659 declare_register ("y1_u0", 42);
2660 declare_register ("y1_u1", 43);
2661 declare_register ("y2_u0", 44);
2662 declare_register ("y2_u1", 45);
2663 declare_register ("y3_u0", 46);
2664 declare_register ("y3_u1", 47);
2665 declare_register ("x0_nu", 48);
2666 declare_register ("x1_nu", 49);
2667 declare_register ("x2_nu", 50);
2668 declare_register ("x3_nu", 51);
2669 declare_register ("y0_nu", 52);
2670 declare_register ("y1_nu", 53);
2671 declare_register ("y2_nu", 54);
2672 declare_register ("y3_nu", 55);
2674 declare_register ("mlo", 57);
2675 declare_register ("mmid", 58);
2676 declare_register ("mhi", 59);
2678 declare_register ("acc1", 56);
2679 declare_register ("acc2", 57);
2681 declare_register ("lp_count", 60);
2682 declare_register ("pcl", 63);
2684 /* Initialize the last instructions. */
2685 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2687 /* Aux register declaration. */
2688 arc_aux_hash
= str_htab_create ();
2690 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
2692 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
2694 if (!(auxr
->cpu
& selected_cpu
.flags
))
2697 if ((auxr
->subclass
!= NONE
)
2698 && !check_cpu_feature (auxr
->subclass
))
2701 if (str_hash_insert (arc_aux_hash
, auxr
->name
, auxr
, 0) != 0)
2702 as_fatal (_("duplicate %s"), auxr
->name
);
2705 /* Address type declaration. */
2706 arc_addrtype_hash
= str_htab_create ();
2708 declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD
);
2709 declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID
);
2710 declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD
);
2711 declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD
);
2712 declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD
);
2713 declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM
);
2714 declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA
);
2715 declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD
);
2716 declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD
);
2717 declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD
);
2718 declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID
);
2719 declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD
);
2720 declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM
);
2721 declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD
);
2722 declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA
);
2723 declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD
);
2729 htab_delete (arc_opcode_hash
);
2730 htab_delete (arc_reg_hash
);
2731 htab_delete (arc_aux_hash
);
2732 htab_delete (arc_addrtype_hash
);
2735 /* Write a value out to the object file, using the appropriate
2739 md_number_to_chars (char *buf
,
2743 if (target_big_endian
)
2744 number_to_chars_bigendian (buf
, val
, n
);
2746 number_to_chars_littleendian (buf
, val
, n
);
2749 /* Round up a section size to the appropriate boundary. */
2752 md_section_align (segT segment
,
2755 int align
= bfd_section_alignment (segment
);
2757 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2760 /* The location from which a PC relative jump should be calculated,
2761 given a PC relative reloc. */
2764 md_pcrel_from_section (fixS
*fixP
,
2767 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2769 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2771 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2772 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2773 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2775 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2777 /* The symbol is undefined (or is defined but not in this section).
2778 Let the linker figure it out. */
2782 if ((int) fixP
->fx_r_type
< 0)
2784 /* These are the "internal" relocations. Align them to
2785 32 bit boundary (PCL), for the moment. */
2790 switch (fixP
->fx_r_type
)
2792 case BFD_RELOC_ARC_PC32
:
2793 /* The hardware calculates relative to the start of the
2794 insn, but this relocation is relative to location of the
2795 LIMM, compensate. The base always needs to be
2796 subtracted by 4 as we do not support this type of PCrel
2797 relocation for short instructions. */
2800 case BFD_RELOC_ARC_PLT32
:
2801 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2802 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2803 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2804 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2806 case BFD_RELOC_ARC_S21H_PCREL
:
2807 case BFD_RELOC_ARC_S25H_PCREL
:
2808 case BFD_RELOC_ARC_S13_PCREL
:
2809 case BFD_RELOC_ARC_S21W_PCREL
:
2810 case BFD_RELOC_ARC_S25W_PCREL
:
2814 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2815 _("unhandled reloc %s in md_pcrel_from_section"),
2816 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2821 pr_debug ("pcrel from %" PRIx64
" + %lx = %" PRIx64
", "
2822 "symbol: %s (%" PRIx64
")\n",
2823 (uint64_t) fixP
->fx_frag
->fr_address
, fixP
->fx_where
, (uint64_t) base
,
2824 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2825 fixP
->fx_addsy
? (uint64_t) S_GET_VALUE (fixP
->fx_addsy
) : (uint64_t) 0);
2830 /* Given a BFD relocation find the corresponding operand. */
2832 static const struct arc_operand
*
2833 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2837 for (i
= 0; i
< arc_num_operands
; i
++)
2838 if (arc_operands
[i
].default_reloc
== reloc
)
2839 return &arc_operands
[i
];
2843 /* Insert an operand value into an instruction. */
2845 static unsigned long long
2846 insert_operand (unsigned long long insn
,
2847 const struct arc_operand
*operand
,
2852 offsetT min
= 0, max
= 0;
2854 if (operand
->bits
!= 32
2855 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2856 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2858 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2860 max
= (1 << (operand
->bits
- 1)) - 1;
2861 min
= -(1 << (operand
->bits
- 1));
2865 max
= (1 << operand
->bits
) - 1;
2869 if (val
< min
|| val
> max
)
2870 as_bad_value_out_of_range (_("operand"),
2871 val
, min
, max
, file
, line
);
2874 pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
2875 min
, val
, max
, insn
);
2877 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2879 as_bad_where (file
, line
,
2880 _("Unaligned operand. Needs to be 32bit aligned"));
2882 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2884 as_bad_where (file
, line
,
2885 _("Unaligned operand. Needs to be 16bit aligned"));
2887 if (operand
->insert
)
2889 const char *errmsg
= NULL
;
2891 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2893 as_warn_where (file
, line
, "%s", errmsg
);
2897 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2899 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2901 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2904 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2909 /* Apply a fixup to the object code. At this point all symbol values
2910 should be fully resolved, and we attempt to completely resolve the
2911 reloc. If we can not do that, we determine the correct reloc code
2912 and put it back in the fixup. To indicate that a fixup has been
2913 eliminated, set fixP->fx_done. */
2916 md_apply_fix (fixS
*fixP
,
2920 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2921 valueT value
= *valP
;
2923 symbolS
*fx_addsy
, *fx_subsy
;
2925 segT add_symbol_segment
= absolute_section
;
2926 segT sub_symbol_segment
= absolute_section
;
2927 const struct arc_operand
*operand
= NULL
;
2928 extended_bfd_reloc_code_real_type reloc
;
2930 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2931 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2932 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2933 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2936 fx_addsy
= fixP
->fx_addsy
;
2937 fx_subsy
= fixP
->fx_subsy
;
2942 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2946 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2947 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2948 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2950 resolve_symbol_value (fx_subsy
);
2951 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2953 if (sub_symbol_segment
== absolute_section
)
2955 /* The symbol is really a constant. */
2956 fx_offset
-= S_GET_VALUE (fx_subsy
);
2961 as_bad_subtract (fixP
);
2967 && !S_IS_WEAK (fx_addsy
))
2969 if (add_symbol_segment
== seg
2972 value
+= S_GET_VALUE (fx_addsy
);
2973 value
-= md_pcrel_from_section (fixP
, seg
);
2975 fixP
->fx_pcrel
= false;
2977 else if (add_symbol_segment
== absolute_section
)
2979 value
= fixP
->fx_offset
;
2980 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2982 fixP
->fx_pcrel
= false;
2987 fixP
->fx_done
= true;
2992 && ((S_IS_DEFINED (fx_addsy
)
2993 && S_GET_SEGMENT (fx_addsy
) != seg
)
2994 || S_IS_WEAK (fx_addsy
)))
2995 value
+= md_pcrel_from_section (fixP
, seg
);
2997 switch (fixP
->fx_r_type
)
2999 case BFD_RELOC_ARC_32_ME
:
3000 /* This is a pc-relative value in a LIMM. Adjust it to the
3001 address of the instruction not to the address of the
3002 LIMM. Note: it is not any longer valid this affirmation as
3003 the linker consider ARC_PC32 a fixup to entire 64 bit
3005 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
3008 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
3010 case BFD_RELOC_ARC_PC32
:
3011 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
3014 if ((int) fixP
->fx_r_type
< 0)
3015 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3016 _("PC relative relocation not allowed for (internal)"
3023 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
3024 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
3025 ((int) fixP
->fx_r_type
< 0) ? "Internal":
3026 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
3030 /* Now check for TLS relocations. */
3031 reloc
= fixP
->fx_r_type
;
3034 case BFD_RELOC_ARC_TLS_DTPOFF
:
3035 case BFD_RELOC_ARC_TLS_LE_32
:
3039 case BFD_RELOC_ARC_TLS_GD_GOT
:
3040 case BFD_RELOC_ARC_TLS_IE_GOT
:
3041 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
3044 case BFD_RELOC_ARC_TLS_GD_LD
:
3045 gas_assert (!fixP
->fx_offset
);
3048 = (S_GET_VALUE (fixP
->fx_subsy
)
3049 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
3050 fixP
->fx_subsy
= NULL
;
3052 case BFD_RELOC_ARC_TLS_GD_CALL
:
3053 /* These two relocs are there just to allow ld to change the tls
3054 model for this symbol, by patching the code. The offset -
3055 and scale, if any - will be installed by the linker. */
3056 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
3059 case BFD_RELOC_ARC_TLS_LE_S9
:
3060 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
3061 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3073 /* Adjust the value if we have a constant. */
3076 /* For hosts with longs bigger than 32-bits make sure that the top
3077 bits of a 32-bit negative value read in by the parser are set,
3078 so that the correct comparisons are made. */
3079 if (value
& 0x80000000)
3080 value
|= (-1UL << 31);
3082 reloc
= fixP
->fx_r_type
;
3090 case BFD_RELOC_ARC_32_PCREL
:
3091 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
3094 case BFD_RELOC_ARC_GOTPC32
:
3095 /* I cannot fix an GOTPC relocation because I need to relax it
3096 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
3097 as_bad (_("Unsupported operation on reloc"));
3100 case BFD_RELOC_ARC_TLS_DTPOFF
:
3101 case BFD_RELOC_ARC_TLS_LE_32
:
3102 gas_assert (!fixP
->fx_addsy
);
3103 gas_assert (!fixP
->fx_subsy
);
3106 case BFD_RELOC_ARC_GOTOFF
:
3107 case BFD_RELOC_ARC_32_ME
:
3108 case BFD_RELOC_ARC_PC32
:
3109 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
3112 case BFD_RELOC_ARC_PLT32
:
3113 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
3116 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
3117 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
3120 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
3121 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
3124 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
3125 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
3128 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
3129 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
3132 case BFD_RELOC_ARC_S25W_PCREL
:
3133 case BFD_RELOC_ARC_S21W_PCREL
:
3134 case BFD_RELOC_ARC_S21H_PCREL
:
3135 case BFD_RELOC_ARC_S25H_PCREL
:
3136 case BFD_RELOC_ARC_S13_PCREL
:
3138 operand
= find_operand_for_reloc (reloc
);
3139 gas_assert (operand
);
3144 if ((int) fixP
->fx_r_type
>= 0)
3145 as_fatal (_("unhandled relocation type %s"),
3146 bfd_get_reloc_code_name (fixP
->fx_r_type
));
3148 /* The rest of these fixups needs to be completely resolved as
3150 if (fixP
->fx_addsy
!= 0
3151 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
3152 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3153 _("non-absolute expression in constant field"));
3155 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
3156 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
3161 if (target_big_endian
)
3163 switch (fixP
->fx_size
)
3166 insn
= bfd_getb32 (fixpos
);
3169 insn
= bfd_getb16 (fixpos
);
3172 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3173 _("unknown fixup size"));
3179 switch (fixP
->fx_size
)
3182 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
3185 insn
= bfd_getl16 (fixpos
);
3188 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3189 _("unknown fixup size"));
3193 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
3194 fixP
->fx_file
, fixP
->fx_line
);
3196 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
3199 /* Prepare machine-dependent frags for relaxation.
3201 Called just before relaxation starts. Any symbol that is now undefined
3202 will not become defined.
3204 Return the correct fr_subtype in the frag.
3206 Return the initial "guess for fr_var" to caller. The guess for fr_var
3207 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3208 or fr_var contributes to our returned value.
3210 Although it may not be explicit in the frag, pretend
3211 fr_var starts with a value. */
3214 md_estimate_size_before_relax (fragS
*fragP
,
3219 /* If the symbol is not located within the same section AND it's not
3220 an absolute section, use the maximum. OR if the symbol is a
3221 constant AND the insn is by nature not pc-rel, use the maximum.
3222 OR if the symbol is being equated against another symbol, use the
3223 maximum. OR if the symbol is weak use the maximum. */
3224 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
3225 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
3226 || (symbol_constant_p (fragP
->fr_symbol
)
3227 && !fragP
->tc_frag_data
.pcrel
)
3228 || symbol_equated_p (fragP
->fr_symbol
)
3229 || S_IS_WEAK (fragP
->fr_symbol
))
3231 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
3232 ++fragP
->fr_subtype
;
3235 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3236 fragP
->fr_var
= growth
;
3238 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3239 fragP
->fr_file
, fragP
->fr_line
, growth
);
3244 /* Translate internal representation of relocation info to BFD target
3248 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
3252 bfd_reloc_code_real_type code
;
3254 reloc
= XNEW (arelent
);
3255 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3256 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3257 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3259 /* Make sure none of our internal relocations make it this far.
3260 They'd better have been fully resolved by this point. */
3261 gas_assert ((int) fixP
->fx_r_type
> 0);
3263 code
= fixP
->fx_r_type
;
3265 /* if we have something like add gp, pcl,
3266 _GLOBAL_OFFSET_TABLE_@gotpc. */
3267 if (code
== BFD_RELOC_ARC_GOTPC32
3269 && fixP
->fx_addsy
== GOT_symbol
)
3270 code
= BFD_RELOC_ARC_GOTPC
;
3272 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
3273 if (reloc
->howto
== NULL
)
3275 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3276 _("cannot represent `%s' relocation in object file"),
3277 bfd_get_reloc_code_name (code
));
3281 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
3282 as_fatal (_("internal error? cannot generate `%s' relocation"),
3283 bfd_get_reloc_code_name (code
));
3285 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
3287 reloc
->addend
= fixP
->fx_offset
;
3292 /* Perform post-processing of machine-dependent frags after relaxation.
3293 Called after relaxation is finished.
3294 In: Address of frag.
3295 fr_type == rs_machine_dependent.
3296 fr_subtype is what the address relaxed to.
3298 Out: Any fixS:s and constants are set up. */
3301 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
3302 segT segment ATTRIBUTE_UNUSED
,
3305 const relax_typeS
*table_entry
;
3307 const struct arc_opcode
*opcode
;
3308 struct arc_insn insn
;
3310 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
3312 fix
= fragP
->fr_fix
;
3313 dest
= fragP
->fr_literal
+ fix
;
3314 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
3316 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3317 "var: %" PRId64
"\n",
3318 fragP
->fr_file
, fragP
->fr_line
,
3319 fragP
->fr_subtype
, fix
, (int64_t) fragP
->fr_var
);
3321 if (fragP
->fr_subtype
<= 0
3322 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
3323 as_fatal (_("no relaxation found for this instruction."));
3325 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
3327 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
3328 relax_arg
->nflg
, &insn
);
3330 apply_fixups (&insn
, fragP
, fix
);
3332 size
= insn
.len
+ (insn
.has_limm
? 4 : 0);
3333 gas_assert (table_entry
->rlx_length
== size
);
3334 emit_insn0 (&insn
, dest
, true);
3336 fragP
->fr_fix
+= table_entry
->rlx_length
;
3340 /* We have no need to default values of symbols. We could catch
3341 register names here, but that is handled by inserting them all in
3342 the symbol table to begin with. */
3345 md_undefined_symbol (char *name
)
3347 /* The arc abi demands that a GOT[0] should be referencible as
3348 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3349 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3351 && (*(name
+1) == 'G')
3352 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0)))
3356 if (symbol_find (name
))
3357 as_bad ("GOT already in symbol table");
3359 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
3360 &zero_address_frag
, 0);
3367 /* Turn a string in input_line_pointer into a floating point constant
3368 of type type, and store the appropriate bytes in *litP. The number
3369 of LITTLENUMS emitted is stored in *sizeP. An error message is
3370 returned, or NULL on OK. */
3373 md_atof (int type
, char *litP
, int *sizeP
)
3375 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
3378 /* Called for any expression that can not be recognized. When the
3379 function is called, `input_line_pointer' will point to the start of
3380 the expression. We use it when we have complex operations like
3381 @label1 - @label2. */
3384 md_operand (expressionS
*expressionP
)
3386 char *p
= input_line_pointer
;
3389 input_line_pointer
++;
3390 expressionP
->X_op
= O_symbol
;
3391 expressionP
->X_md
= O_absent
;
3392 expression (expressionP
);
3396 /* This function is called from the function 'expression', it attempts
3397 to parse special names (in our case register names). It fills in
3398 the expression with the identified register. It returns TRUE if
3399 it is a register and FALSE otherwise. */
3402 arc_parse_name (const char *name
,
3403 struct expressionS
*e
)
3407 if (!assembling_insn
)
3410 if (e
->X_op
== O_symbol
3411 && e
->X_md
== O_absent
)
3414 sym
= str_hash_find (arc_reg_hash
, name
);
3417 e
->X_op
= O_register
;
3418 e
->X_add_number
= S_GET_VALUE (sym
);
3422 sym
= str_hash_find (arc_addrtype_hash
, name
);
3425 e
->X_op
= O_addrtype
;
3426 e
->X_add_number
= S_GET_VALUE (sym
);
3434 Invocation line includes a switch not recognized by the base assembler.
3435 See if it's a processor-specific option.
3437 New options (supported) are:
3439 -mcpu=<cpu name> Assemble for selected processor
3440 -EB/-mbig-endian Big-endian
3441 -EL/-mlittle-endian Little-endian
3442 -mrelax Enable relaxation
3444 The following CPU names are recognized:
3445 arc600, arc700, arcem, archs, nps400. */
3448 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
3454 return md_parse_option (OPTION_MCPU
, "arc600");
3457 return md_parse_option (OPTION_MCPU
, "arc700");
3460 return md_parse_option (OPTION_MCPU
, "arcem");
3463 return md_parse_option (OPTION_MCPU
, "archs");
3467 arc_select_cpu (arg
, MACH_SELECTION_FROM_COMMAND_LINE
);
3472 arc_target_format
= "elf32-bigarc";
3473 byte_order
= BIG_ENDIAN
;
3477 arc_target_format
= "elf32-littlearc";
3478 byte_order
= LITTLE_ENDIAN
;
3482 selected_cpu
.features
|= CD
;
3484 arc_check_feature ();
3488 relaxation_state
= 1;
3492 selected_cpu
.features
|= NPS400
;
3493 cl_features
|= NPS400
;
3494 arc_check_feature ();
3498 selected_cpu
.features
|= SPX
;
3500 arc_check_feature ();
3504 selected_cpu
.features
|= DPX
;
3506 arc_check_feature ();
3510 selected_cpu
.features
|= DPA
;
3512 arc_check_feature ();
3515 /* Dummy options are accepted but have no effect. */
3516 case OPTION_USER_MODE
:
3517 case OPTION_LD_EXT_MASK
:
3520 case OPTION_BARREL_SHIFT
:
3521 case OPTION_MIN_MAX
:
3526 case OPTION_XMAC_D16
:
3527 case OPTION_XMAC_24
:
3528 case OPTION_DSP_PACKA
:
3531 case OPTION_TELEPHONY
:
3532 case OPTION_XYMEMORY
:
3545 /* Display the list of cpu names for use in the help text. */
3548 arc_show_cpu_list (FILE *stream
)
3551 static const char *space_buf
= " ";
3553 fprintf (stream
, "%s", space_buf
);
3554 offset
= strlen (space_buf
);
3555 for (i
= 0; cpu_types
[i
].name
!= NULL
; ++i
)
3557 bool last
= (cpu_types
[i
+ 1].name
== NULL
);
3559 /* If displaying the new cpu name string, and the ', ' (for all
3560 but the last one) will take us past a target width of 80
3561 characters, then it's time for a new line. */
3562 if (offset
+ strlen (cpu_types
[i
].name
) + (last
? 0 : 2) > 80)
3564 fprintf (stream
, "\n%s", space_buf
);
3565 offset
= strlen (space_buf
);
3568 fprintf (stream
, "%s%s", cpu_types
[i
].name
, (last
? "\n" : ", "));
3569 offset
+= strlen (cpu_types
[i
].name
) + (last
? 0 : 2);
3574 md_show_usage (FILE *stream
)
3576 fprintf (stream
, _("ARC-specific assembler options:\n"));
3578 fprintf (stream
, " -mcpu=<cpu name>\t (default: %s), assemble for"
3579 " CPU <cpu name>, one of:\n", TARGET_WITH_CPU
);
3580 arc_show_cpu_list (stream
);
3581 fprintf (stream
, "\n");
3582 fprintf (stream
, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3583 fprintf (stream
, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3584 fprintf (stream
, " -mEM\t\t\t same as -mcpu=arcem\n");
3585 fprintf (stream
, " -mHS\t\t\t same as -mcpu=archs\n");
3587 fprintf (stream
, " -mnps400\t\t enable NPS-400 extended instructions\n");
3588 fprintf (stream
, " -mspfp\t\t enable single-precision floating point"
3590 fprintf (stream
, " -mdpfp\t\t enable double-precision floating point"
3592 fprintf (stream
, " -mfpuda\t\t enable double-precision assist floating "
3593 "point\n\t\t\t instructions for ARC EM\n");
3596 " -mcode-density\t enable code density option for ARC EM\n");
3598 fprintf (stream
, _("\
3599 -EB assemble code for a big-endian cpu\n"));
3600 fprintf (stream
, _("\
3601 -EL assemble code for a little-endian cpu\n"));
3602 fprintf (stream
, _("\
3603 -mrelax enable relaxation\n"));
3605 fprintf (stream
, _("The following ARC-specific assembler options are "
3606 "deprecated and are accepted\nfor compatibility only:\n"));
3608 fprintf (stream
, _(" -mEA\n"
3609 " -mbarrel-shifter\n"
3610 " -mbarrel_shifter\n"
3615 " -mld-extension-reg-mask\n"
3631 " -muser-mode-only\n"
3635 /* Find the proper relocation for the given opcode. */
3637 static extended_bfd_reloc_code_real_type
3638 find_reloc (const char *name
,
3639 const char *opcodename
,
3640 const struct arc_flags
*pflags
,
3642 extended_bfd_reloc_code_real_type reloc
)
3646 bool found_flag
, tmp
;
3647 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
3649 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
3651 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3653 /* Find the entry. */
3654 if (strcmp (name
, r
->name
))
3656 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3663 unsigned * psflg
= (unsigned *)r
->flags
;
3667 for (j
= 0; j
< nflg
; j
++)
3668 if (!strcmp (pflags
[j
].name
,
3669 arc_flag_operands
[*psflg
].name
))
3690 if (reloc
!= r
->oldreloc
)
3697 if (ret
== BFD_RELOC_UNUSED
)
3698 as_bad (_("Unable to find %s relocation for instruction %s"),
3703 /* All the symbol types that are allowed to be used for
3707 may_relax_expr (expressionS tok
)
3709 /* Check if we have unrelaxable relocs. */
3734 /* Checks if flags are in line with relaxable insn. */
3737 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3738 const struct arc_flags
*pflags
,
3741 unsigned flag_class
,
3746 const struct arc_flag_operand
*flag_opand
;
3747 int i
, counttrue
= 0;
3749 /* Iterate through flags classes. */
3750 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3752 /* Iterate through flags in flag class. */
3753 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3756 flag_opand
= &arc_flag_operands
[flag
];
3757 /* Iterate through flags in ins to compare. */
3758 for (i
= 0; i
< nflgs
; ++i
)
3760 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3771 /* If counttrue == nflgs, then all flags have been found. */
3772 return counttrue
== nflgs
;
3775 /* Checks if operands are in line with relaxable insn. */
3778 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3779 const expressionS
*tok
,
3782 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3785 while (*operand
!= EMPTY
)
3787 const expressionS
*epr
= &tok
[i
];
3789 if (i
!= 0 && i
>= ntok
)
3795 if (!(epr
->X_op
== O_multiply
3796 || epr
->X_op
== O_divide
3797 || epr
->X_op
== O_modulus
3798 || epr
->X_op
== O_add
3799 || epr
->X_op
== O_subtract
3800 || epr
->X_op
== O_symbol
))
3806 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3810 if (epr
->X_op
!= O_register
)
3815 if (epr
->X_op
!= O_register
)
3818 switch (epr
->X_add_number
)
3820 case 0: case 1: case 2: case 3:
3821 case 12: case 13: case 14: case 15:
3828 case REGISTER_NO_GP
:
3829 if ((epr
->X_op
!= O_register
)
3830 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3835 if (epr
->X_op
!= O_bracket
)
3840 /* Don't understand, bail out. */
3846 operand
= &ins
->operands
[i
];
3852 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3855 relax_insn_p (const struct arc_opcode
*opcode
,
3856 const expressionS
*tok
,
3858 const struct arc_flags
*pflags
,
3864 /* Check the relaxation table. */
3865 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3867 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3869 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3870 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3871 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3872 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3875 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3876 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3877 sizeof (expressionS
) * ntok
);
3878 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3879 sizeof (struct arc_flags
) * nflg
);
3880 frag_now
->tc_frag_data
.nflg
= nflg
;
3881 frag_now
->tc_frag_data
.ntok
= ntok
;
3889 /* Turn an opcode description and a set of arguments into
3890 an instruction and a fixup. */
3893 assemble_insn (const struct arc_opcode
*opcode
,
3894 const expressionS
*tok
,
3896 const struct arc_flags
*pflags
,
3898 struct arc_insn
*insn
)
3900 const expressionS
*reloc_exp
= NULL
;
3901 unsigned long long image
;
3902 const unsigned char *argidx
;
3905 unsigned char pcrel
= 0;
3907 bool has_delay_slot
= false;
3908 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3910 memset (insn
, 0, sizeof (*insn
));
3911 image
= opcode
->opcode
;
3913 pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
3914 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3917 /* Handle operands. */
3918 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3920 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3921 const expressionS
*t
= (const expressionS
*) 0;
3923 if (ARC_OPERAND_IS_FAKE (operand
))
3926 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3928 /* Duplicate operand, already inserted. */
3940 /* Regardless if we have a reloc or not mark the instruction
3941 limm if it is the case. */
3942 if (operand
->flags
& ARC_OPERAND_LIMM
)
3943 insn
->has_limm
= true;
3948 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3953 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3955 if (operand
->flags
& ARC_OPERAND_LIMM
)
3956 insn
->limm
= t
->X_add_number
;
3962 /* Ignore brackets, colons, and address types. */
3966 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3970 /* Maybe register range. */
3971 if ((t
->X_add_number
== 0)
3972 && contains_register (t
->X_add_symbol
)
3973 && contains_register (t
->X_op_symbol
))
3977 regs
= get_register (t
->X_add_symbol
);
3979 regs
|= get_register (t
->X_op_symbol
);
3980 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3986 /* This operand needs a relocation. */
3987 needGOTSymbol
= false;
3992 if (opcode
->insn_class
== JUMP
)
3993 as_bad (_("Unable to use @plt relocation for insn %s"),
3995 needGOTSymbol
= true;
3996 reloc
= find_reloc ("plt", opcode
->name
,
3998 operand
->default_reloc
);
4003 needGOTSymbol
= true;
4004 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
4007 if (operand
->flags
& ARC_OPERAND_LIMM
)
4009 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
4010 if (arc_opcode_len (opcode
) == 2
4011 || opcode
->insn_class
== JUMP
)
4012 as_bad (_("Unable to use @pcl relocation for insn %s"),
4017 /* This is a relaxed operand which initially was
4018 limm, choose whatever we have defined in the
4020 reloc
= operand
->default_reloc
;
4024 reloc
= find_reloc ("sda", opcode
->name
,
4026 operand
->default_reloc
);
4030 needGOTSymbol
= true;
4035 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
4038 case O_tpoff9
: /*FIXME! Check for the conditionality of
4040 case O_dtpoff9
: /*FIXME! Check for the conditionality of
4042 as_bad (_("TLS_*_S9 relocs are not supported yet"));
4046 /* Just consider the default relocation. */
4047 reloc
= operand
->default_reloc
;
4051 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
4052 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
4059 /* sanity checks. */
4060 reloc_howto_type
*reloc_howto
4061 = bfd_reloc_type_lookup (stdoutput
,
4062 (bfd_reloc_code_real_type
) reloc
);
4063 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
4064 if (reloc_howto
->rightshift
)
4065 reloc_bitsize
-= reloc_howto
->rightshift
;
4066 if (reloc_bitsize
!= operand
->bits
)
4068 as_bad (_("invalid relocation %s for field"),
4069 bfd_get_reloc_code_name (reloc
));
4074 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
4075 as_fatal (_("too many fixups"));
4077 struct arc_fixup
*fixup
;
4078 fixup
= &insn
->fixups
[insn
->nfixups
++];
4080 fixup
->reloc
= reloc
;
4081 if ((int) reloc
< 0)
4082 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
4085 reloc_howto_type
*reloc_howto
=
4086 bfd_reloc_type_lookup (stdoutput
,
4087 (bfd_reloc_code_real_type
) fixup
->reloc
);
4088 pcrel
= reloc_howto
->pc_relative
;
4090 fixup
->pcrel
= pcrel
;
4091 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) != 0;
4097 for (i
= 0; i
< nflg
; i
++)
4099 const struct arc_flag_operand
*flg_operand
= pflags
[i
].flgp
;
4101 /* Check if the instruction has a delay slot. */
4102 if (!strcmp (flg_operand
->name
, "d"))
4103 has_delay_slot
= true;
4105 /* There is an exceptional case when we cannot insert a flag just as
4106 it is. On ARCv2 the '.t' and '.nt' flags must be handled in
4107 relation with the relative address. Unfortunately, some of the
4108 ARC700 extensions (NPS400) also have a '.nt' flag that should be
4109 handled in the normal way.
4111 Flag operands don't have an architecture field, so we can't
4112 directly validate that FLAG_OPERAND is valid for the current
4113 architecture, what we do instead is just validate that we're
4114 assembling for an ARCv2 architecture. */
4115 if ((selected_cpu
.flags
& ARC_OPCODE_ARCV2
)
4116 && (!strcmp (flg_operand
->name
, "t")
4117 || !strcmp (flg_operand
->name
, "nt")))
4119 unsigned bitYoperand
= 0;
4120 /* FIXME! move selection bbit/brcc in arc-opc.c. */
4121 if (!strcmp (flg_operand
->name
, "t"))
4122 if (!strcmp (opcode
->name
, "bbit0")
4123 || !strcmp (opcode
->name
, "bbit1"))
4124 bitYoperand
= arc_NToperand
;
4126 bitYoperand
= arc_Toperand
;
4128 if (!strcmp (opcode
->name
, "bbit0")
4129 || !strcmp (opcode
->name
, "bbit1"))
4130 bitYoperand
= arc_Toperand
;
4132 bitYoperand
= arc_NToperand
;
4134 gas_assert (reloc_exp
!= NULL
);
4135 if (reloc_exp
->X_op
== O_constant
)
4137 /* Check if we have a constant and solved it
4139 offsetT val
= reloc_exp
->X_add_number
;
4140 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
4145 struct arc_fixup
*fixup
;
4147 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
4148 as_fatal (_("too many fixups"));
4150 fixup
= &insn
->fixups
[insn
->nfixups
++];
4151 fixup
->exp
= *reloc_exp
;
4152 fixup
->reloc
= -bitYoperand
;
4153 fixup
->pcrel
= pcrel
;
4154 fixup
->islong
= false;
4158 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
4159 << flg_operand
->shift
;
4162 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
4164 /* Instruction length. */
4165 insn
->len
= arc_opcode_len (opcode
);
4169 /* Update last insn status. */
4170 arc_last_insns
[1] = arc_last_insns
[0];
4171 arc_last_insns
[0].opcode
= opcode
;
4172 arc_last_insns
[0].has_limm
= insn
->has_limm
;
4173 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
4175 /* Check if the current instruction is legally used. */
4176 if (arc_last_insns
[1].has_delay_slot
4177 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4178 as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."),
4179 arc_last_insns
[1].opcode
->name
,
4180 arc_last_insns
[0].opcode
->name
);
4181 if (arc_last_insns
[1].has_delay_slot
4182 && arc_last_insns
[0].has_limm
)
4183 as_bad (_("Insn %s has an instruction %s with limm in its delay slot."),
4184 arc_last_insns
[1].opcode
->name
,
4185 arc_last_insns
[0].opcode
->name
);
4189 arc_handle_align (fragS
* fragP
)
4191 if ((fragP
)->fr_type
== rs_align_code
)
4193 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
4194 valueT count
= ((fragP
)->fr_next
->fr_address
4195 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
4197 (fragP
)->fr_var
= 2;
4199 if (count
& 1)/* Padding in the gap till the next 2-byte
4200 boundary with 0s. */
4205 /* Writing nop_s. */
4206 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
4210 /* Here we decide which fixups can be adjusted to make them relative
4211 to the beginning of the section instead of the symbol. Basically
4212 we need to make sure that the dynamic relocations are done
4213 correctly, so in some cases we force the original symbol to be
4217 tc_arc_fix_adjustable (fixS
*fixP
)
4220 /* Prevent all adjustments to global symbols. */
4221 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
4223 if (S_IS_WEAK (fixP
->fx_addsy
))
4226 /* Adjust_reloc_syms doesn't know about the GOT. */
4227 switch (fixP
->fx_r_type
)
4229 case BFD_RELOC_ARC_GOTPC32
:
4230 case BFD_RELOC_ARC_PLT32
:
4231 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
4232 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
4233 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
4234 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
4244 /* Compute the reloc type of an expression EXP. */
4247 arc_check_reloc (expressionS
*exp
,
4248 bfd_reloc_code_real_type
*r_type_p
)
4250 if (*r_type_p
== BFD_RELOC_32
4251 && exp
->X_op
== O_subtract
4252 && exp
->X_op_symbol
!= NULL
4253 && S_GET_SEGMENT (exp
->X_op_symbol
) == now_seg
)
4254 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
4258 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4261 arc_cons_fix_new (fragS
*frag
,
4265 bfd_reloc_code_real_type r_type
)
4267 r_type
= BFD_RELOC_UNUSED
;
4272 r_type
= BFD_RELOC_8
;
4276 r_type
= BFD_RELOC_16
;
4280 r_type
= BFD_RELOC_24
;
4284 r_type
= BFD_RELOC_32
;
4285 arc_check_reloc (exp
, &r_type
);
4289 r_type
= BFD_RELOC_64
;
4293 as_bad (_("unsupported BFD relocation size %u"), size
);
4294 r_type
= BFD_RELOC_UNUSED
;
4297 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
4300 /* The actual routine that checks the ZOL conditions. */
4303 check_zol (symbolS
*s
)
4305 switch (selected_cpu
.mach
)
4307 case bfd_mach_arc_arcv2
:
4308 if (selected_cpu
.flags
& ARC_OPCODE_ARCv2EM
)
4311 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
4312 || arc_last_insns
[1].has_delay_slot
)
4313 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4317 case bfd_mach_arc_arc600
:
4319 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
4320 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4323 if (arc_last_insns
[0].has_limm
4324 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4325 as_bad (_("A jump instruction with long immediate detected at the \
4326 end of the ZOL label @%s"), S_GET_NAME (s
));
4329 case bfd_mach_arc_arc700
:
4330 if (arc_last_insns
[0].has_delay_slot
)
4331 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4340 /* If ZOL end check the last two instruction for illegals. */
4342 arc_frob_label (symbolS
* sym
)
4344 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
4347 dwarf2_emit_label (sym
);
4350 /* Used because generic relaxation assumes a pc-rel value whilst we
4351 also relax instructions that use an absolute value resolved out of
4352 relative values (if that makes any sense). An example: 'add r1,
4353 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4354 but if they're in the same section we can subtract the section
4355 offset relocation which ends up in a resolved value. So if @.L2 is
4356 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4357 .text + 0x40 = 0x10. */
4359 arc_pcrel_adjust (fragS
*fragP
)
4361 pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
4362 fragP
->fr_address
, fragP
->fr_fix
,
4363 fragP
->tc_frag_data
.pcrel
? "Y" : "N");
4365 if (!fragP
->tc_frag_data
.pcrel
)
4366 return fragP
->fr_address
+ fragP
->fr_fix
;
4368 /* Take into account the PCL rounding. */
4369 return (fragP
->fr_address
+ fragP
->fr_fix
) & 0x03;
4372 /* Initialize the DWARF-2 unwind information for this procedure. */
4375 tc_arc_frame_initial_instructions (void)
4377 /* Stack pointer is register 28. */
4378 cfi_add_CFA_def_cfa (28, 0);
4382 tc_arc_regname_to_dw2regnum (char *regname
)
4386 sym
= str_hash_find (arc_reg_hash
, regname
);
4388 return S_GET_VALUE (sym
);
4393 /* Adjust the symbol table. Delete found AUX register symbols. */
4396 arc_adjust_symtab (void)
4400 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
4402 /* I've created a symbol during parsing process. Now, remove
4403 the symbol as it is found to be an AUX register. */
4404 if (ARC_GET_FLAG (sym
) & ARC_FLAG_AUX
)
4405 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
4408 /* Now do generic ELF adjustments. */
4409 elf_adjust_symtab ();
4413 tokenize_extinsn (extInstruction_t
*einsn
)
4417 unsigned char major_opcode
;
4418 unsigned char sub_opcode
;
4419 unsigned char syntax_class
= 0;
4420 unsigned char syntax_class_modifiers
= 0;
4421 unsigned char suffix_class
= 0;
4426 /* 1st: get instruction name. */
4427 p
= input_line_pointer
;
4428 c
= get_symbol_name (&p
);
4430 insn_name
= xstrdup (p
);
4431 restore_line_pointer (c
);
4433 /* Convert to lower case. */
4434 for (p
= insn_name
; *p
; ++p
)
4437 /* 2nd: get major opcode. */
4438 if (*input_line_pointer
!= ',')
4440 as_bad (_("expected comma after instruction name"));
4441 ignore_rest_of_line ();
4444 input_line_pointer
++;
4445 major_opcode
= get_absolute_expression ();
4447 /* 3rd: get sub-opcode. */
4450 if (*input_line_pointer
!= ',')
4452 as_bad (_("expected comma after major opcode"));
4453 ignore_rest_of_line ();
4456 input_line_pointer
++;
4457 sub_opcode
= get_absolute_expression ();
4459 /* 4th: get suffix class. */
4462 if (*input_line_pointer
!= ',')
4464 as_bad ("expected comma after sub opcode");
4465 ignore_rest_of_line ();
4468 input_line_pointer
++;
4474 for (i
= 0; i
< ARRAY_SIZE (suffixclass
); i
++)
4476 if (!strncmp (suffixclass
[i
].name
, input_line_pointer
,
4477 suffixclass
[i
].len
))
4479 suffix_class
|= suffixclass
[i
].attr_class
;
4480 input_line_pointer
+= suffixclass
[i
].len
;
4485 if (i
== ARRAY_SIZE (suffixclass
))
4487 as_bad ("invalid suffix class");
4488 ignore_rest_of_line ();
4494 if (*input_line_pointer
== '|')
4495 input_line_pointer
++;
4500 /* 5th: get syntax class and syntax class modifiers. */
4501 if (*input_line_pointer
!= ',')
4503 as_bad ("expected comma after suffix class");
4504 ignore_rest_of_line ();
4507 input_line_pointer
++;
4513 for (i
= 0; i
< ARRAY_SIZE (syntaxclassmod
); i
++)
4515 if (!strncmp (syntaxclassmod
[i
].name
,
4517 syntaxclassmod
[i
].len
))
4519 syntax_class_modifiers
|= syntaxclassmod
[i
].attr_class
;
4520 input_line_pointer
+= syntaxclassmod
[i
].len
;
4525 if (i
== ARRAY_SIZE (syntaxclassmod
))
4527 for (i
= 0; i
< ARRAY_SIZE (syntaxclass
); i
++)
4529 if (!strncmp (syntaxclass
[i
].name
,
4531 syntaxclass
[i
].len
))
4533 syntax_class
|= syntaxclass
[i
].attr_class
;
4534 input_line_pointer
+= syntaxclass
[i
].len
;
4539 if (i
== ARRAY_SIZE (syntaxclass
))
4541 as_bad ("missing syntax class");
4542 ignore_rest_of_line ();
4549 if (*input_line_pointer
== '|')
4550 input_line_pointer
++;
4555 demand_empty_rest_of_line ();
4557 einsn
->name
= insn_name
;
4558 einsn
->major
= major_opcode
;
4559 einsn
->minor
= sub_opcode
;
4560 einsn
->syntax
= syntax_class
;
4561 einsn
->modsyn
= syntax_class_modifiers
;
4562 einsn
->suffix
= suffix_class
;
4563 einsn
->flags
= syntax_class
4564 | (syntax_class_modifiers
& ARC_OP1_IMM_IMPLIED
? 0x10 : 0);
4567 /* Generate an extension section. */
4570 arc_set_ext_seg (void)
4572 if (!arcext_section
)
4574 arcext_section
= subseg_new (".arcextmap", 0);
4575 bfd_set_section_flags (arcext_section
, SEC_READONLY
| SEC_HAS_CONTENTS
);
4578 subseg_set (arcext_section
, 0);
4582 /* Create an extension instruction description in the arc extension
4583 section of the output file.
4584 The structure for an instruction is like this:
4585 [0]: Length of the record.
4586 [1]: Type of the record.
4590 [4]: Syntax (flags).
4591 [5]+ Name instruction.
4593 The sequence is terminated by an empty entry. */
4596 create_extinst_section (extInstruction_t
*einsn
)
4599 segT old_sec
= now_seg
;
4600 int old_subsec
= now_subseg
;
4602 int name_len
= strlen (einsn
->name
);
4607 *p
= 5 + name_len
+ 1;
4609 *p
= EXT_INSTRUCTION
;
4616 p
= frag_more (name_len
+ 1);
4617 strcpy (p
, einsn
->name
);
4619 subseg_set (old_sec
, old_subsec
);
4622 /* Handler .extinstruction pseudo-op. */
4625 arc_extinsn (int ignore ATTRIBUTE_UNUSED
)
4627 extInstruction_t einsn
;
4628 struct arc_opcode
*arc_ext_opcodes
;
4629 const char *errmsg
= NULL
;
4630 unsigned char moplow
, mophigh
;
4632 memset (&einsn
, 0, sizeof (einsn
));
4633 tokenize_extinsn (&einsn
);
4635 /* Check if the name is already used. */
4636 if (arc_find_opcode (einsn
.name
))
4637 as_warn (_("Pseudocode already used %s"), einsn
.name
);
4639 /* Check the opcode ranges. */
4641 mophigh
= (selected_cpu
.flags
& (ARC_OPCODE_ARCv2EM
4642 | ARC_OPCODE_ARCv2HS
)) ? 0x07 : 0x0a;
4644 if ((einsn
.major
> mophigh
) || (einsn
.major
< moplow
))
4645 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow
, mophigh
);
4647 if ((einsn
.minor
> 0x3f) && (einsn
.major
!= 0x0a)
4648 && (einsn
.major
!= 5) && (einsn
.major
!= 9))
4649 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4651 switch (einsn
.syntax
& ARC_SYNTAX_MASK
)
4653 case ARC_SYNTAX_3OP
:
4654 if (einsn
.modsyn
& ARC_OP1_IMM_IMPLIED
)
4655 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4657 case ARC_SYNTAX_2OP
:
4658 case ARC_SYNTAX_1OP
:
4659 case ARC_SYNTAX_NOP
:
4660 if (einsn
.modsyn
& ARC_OP1_MUST_BE_IMM
)
4661 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4667 arc_ext_opcodes
= arcExtMap_genOpcode (&einsn
, selected_cpu
.flags
, &errmsg
);
4668 if (arc_ext_opcodes
== NULL
)
4671 as_fatal ("%s", errmsg
);
4673 as_fatal (_("Couldn't generate extension instruction opcodes"));
4676 as_warn ("%s", errmsg
);
4678 /* Insert the extension instruction. */
4679 arc_insert_opcode ((const struct arc_opcode
*) arc_ext_opcodes
);
4681 create_extinst_section (&einsn
);
4685 tokenize_extregister (extRegister_t
*ereg
, int opertype
)
4691 int number
, imode
= 0;
4692 bool isCore_p
= opertype
== EXT_CORE_REGISTER
;
4693 bool isReg_p
= opertype
== EXT_CORE_REGISTER
|| opertype
== EXT_AUX_REGISTER
;
4695 /* 1st: get register name. */
4697 p
= input_line_pointer
;
4698 c
= get_symbol_name (&p
);
4701 restore_line_pointer (c
);
4703 /* 2nd: get register number. */
4706 if (*input_line_pointer
!= ',')
4708 as_bad (_("expected comma after name"));
4709 ignore_rest_of_line ();
4713 input_line_pointer
++;
4714 number
= get_absolute_expression ();
4717 && (opertype
!= EXT_AUX_REGISTER
))
4719 as_bad (_("%s second argument cannot be a negative number %d"),
4720 isCore_p
? "extCoreRegister's" : "extCondCode's",
4722 ignore_rest_of_line ();
4729 /* 3rd: get register mode. */
4732 if (*input_line_pointer
!= ',')
4734 as_bad (_("expected comma after register number"));
4735 ignore_rest_of_line ();
4740 input_line_pointer
++;
4741 mode
= input_line_pointer
;
4743 if (startswith (mode
, "r|w"))
4746 input_line_pointer
+= 3;
4748 else if (startswith (mode
, "r"))
4750 imode
= ARC_REGISTER_READONLY
;
4751 input_line_pointer
+= 1;
4753 else if (!startswith (mode
, "w"))
4755 as_bad (_("invalid mode"));
4756 ignore_rest_of_line ();
4762 imode
= ARC_REGISTER_WRITEONLY
;
4763 input_line_pointer
+= 1;
4769 /* 4th: get core register shortcut. */
4771 if (*input_line_pointer
!= ',')
4773 as_bad (_("expected comma after register mode"));
4774 ignore_rest_of_line ();
4779 input_line_pointer
++;
4781 if (startswith (input_line_pointer
, "cannot_shortcut"))
4783 imode
|= ARC_REGISTER_NOSHORT_CUT
;
4784 input_line_pointer
+= 15;
4786 else if (!startswith (input_line_pointer
, "can_shortcut"))
4788 as_bad (_("shortcut designator invalid"));
4789 ignore_rest_of_line ();
4795 input_line_pointer
+= 12;
4798 demand_empty_rest_of_line ();
4801 ereg
->number
= number
;
4802 ereg
->imode
= imode
;
4806 /* Create an extension register/condition description in the arc
4807 extension section of the output file.
4809 The structure for an instruction is like this:
4810 [0]: Length of the record.
4811 [1]: Type of the record.
4813 For core regs and condition codes:
4817 For auxiliary registers:
4821 The sequence is terminated by an empty entry. */
4824 create_extcore_section (extRegister_t
*ereg
, int opertype
)
4826 segT old_sec
= now_seg
;
4827 int old_subsec
= now_subseg
;
4829 int name_len
= strlen (ereg
->name
);
4836 case EXT_CORE_REGISTER
:
4838 *p
= 3 + name_len
+ 1;
4844 case EXT_AUX_REGISTER
:
4846 *p
= 6 + name_len
+ 1;
4848 *p
= EXT_AUX_REGISTER
;
4850 *p
= (ereg
->number
>> 24) & 0xff;
4852 *p
= (ereg
->number
>> 16) & 0xff;
4854 *p
= (ereg
->number
>> 8) & 0xff;
4856 *p
= (ereg
->number
) & 0xff;
4862 p
= frag_more (name_len
+ 1);
4863 strcpy (p
, ereg
->name
);
4865 subseg_set (old_sec
, old_subsec
);
4868 /* Handler .extCoreRegister pseudo-op. */
4871 arc_extcorereg (int opertype
)
4874 struct arc_aux_reg
*auxr
;
4875 struct arc_flag_operand
*ccode
;
4877 memset (&ereg
, 0, sizeof (ereg
));
4878 if (!tokenize_extregister (&ereg
, opertype
))
4883 case EXT_CORE_REGISTER
:
4884 /* Core register. */
4885 if (ereg
.number
> 60)
4886 as_bad (_("core register %s value (%d) too large"), ereg
.name
,
4888 declare_register (ereg
.name
, ereg
.number
);
4890 case EXT_AUX_REGISTER
:
4891 /* Auxiliary register. */
4892 auxr
= XNEW (struct arc_aux_reg
);
4893 auxr
->name
= ereg
.name
;
4894 auxr
->cpu
= selected_cpu
.flags
;
4895 auxr
->subclass
= NONE
;
4896 auxr
->address
= ereg
.number
;
4897 if (str_hash_insert (arc_aux_hash
, auxr
->name
, auxr
, 0) != NULL
)
4898 as_bad (_("duplicate aux register %s"), auxr
->name
);
4901 /* Condition code. */
4902 if (ereg
.number
> 31)
4903 as_bad (_("condition code %s value (%d) too large"), ereg
.name
,
4905 ext_condcode
.size
++;
4906 ext_condcode
.arc_ext_condcode
=
4907 XRESIZEVEC (struct arc_flag_operand
, ext_condcode
.arc_ext_condcode
,
4908 ext_condcode
.size
+ 1);
4910 ccode
= ext_condcode
.arc_ext_condcode
+ ext_condcode
.size
- 1;
4911 ccode
->name
= ereg
.name
;
4912 ccode
->code
= ereg
.number
;
4915 ccode
->favail
= 0; /* not used. */
4917 memset (ccode
, 0, sizeof (struct arc_flag_operand
));
4920 as_bad (_("Unknown extension"));
4923 create_extcore_section (&ereg
, opertype
);
4926 /* Parse a .arc_attribute directive. */
4929 arc_attribute (int ignored ATTRIBUTE_UNUSED
)
4931 int tag
= obj_elf_vendor_attribute (OBJ_ATTR_PROC
);
4933 if (tag
< NUM_KNOWN_OBJ_ATTRIBUTES
)
4934 attributes_set_explicitly
[tag
] = true;
4937 /* Set an attribute if it has not already been set by the user. */
4940 arc_set_attribute_int (int tag
, int value
)
4943 || tag
>= NUM_KNOWN_OBJ_ATTRIBUTES
4944 || !attributes_set_explicitly
[tag
])
4945 if (!bfd_elf_add_proc_attr_int (stdoutput
, tag
, value
))
4946 as_fatal (_("error adding attribute: %s"),
4947 bfd_errmsg (bfd_get_error ()));
4951 arc_set_attribute_string (int tag
, const char *value
)
4954 || tag
>= NUM_KNOWN_OBJ_ATTRIBUTES
4955 || !attributes_set_explicitly
[tag
])
4956 if (!bfd_elf_add_proc_attr_string (stdoutput
, tag
, value
))
4957 as_fatal (_("error adding attribute: %s"),
4958 bfd_errmsg (bfd_get_error ()));
4961 /* Allocate and concatenate two strings. s1 can be NULL but not
4962 s2. s1 pointer is freed at end of this procedure. */
4965 arc_stralloc (char * s1
, const char * s2
)
4971 len
= strlen (s1
) + 1;
4973 /* Only s1 can be null. */
4975 len
+= strlen (s2
) + 1;
4977 p
= (char *) xmalloc (len
);
4992 /* Set the public ARC object attributes. */
4995 arc_set_public_attributes (void)
5001 /* Tag_ARC_CPU_name. */
5002 arc_set_attribute_string (Tag_ARC_CPU_name
, selected_cpu
.name
);
5004 /* Tag_ARC_CPU_base. */
5005 switch (selected_cpu
.eflags
& EF_ARC_MACH_MSK
)
5007 case E_ARC_MACH_ARC600
:
5008 case E_ARC_MACH_ARC601
:
5009 base
= TAG_CPU_ARC6xx
;
5011 case E_ARC_MACH_ARC700
:
5012 base
= TAG_CPU_ARC7xx
;
5014 case EF_ARC_CPU_ARCV2EM
:
5015 base
= TAG_CPU_ARCEM
;
5017 case EF_ARC_CPU_ARCV2HS
:
5018 base
= TAG_CPU_ARCHS
;
5024 if (attributes_set_explicitly
[Tag_ARC_CPU_base
]
5025 && (base
!= bfd_elf_get_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
5027 as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
5028 if (!bfd_elf_add_proc_attr_int (stdoutput
, Tag_ARC_CPU_base
, base
))
5029 as_fatal (_("error adding attribute: %s"),
5030 bfd_errmsg (bfd_get_error ()));
5032 /* Tag_ARC_ABI_osver. */
5033 if (attributes_set_explicitly
[Tag_ARC_ABI_osver
])
5035 int val
= bfd_elf_get_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
5038 selected_cpu
.eflags
= ((selected_cpu
.eflags
& ~EF_ARC_OSABI_MSK
)
5039 | (val
& 0x0f << 8));
5043 arc_set_attribute_int (Tag_ARC_ABI_osver
, E_ARC_OSABI_CURRENT
>> 8);
5046 /* Tag_ARC_ISA_config. */
5047 arc_check_feature();
5049 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
5050 if (selected_cpu
.features
& feature_list
[i
].feature
)
5051 s
= arc_stralloc (s
, feature_list
[i
].attr
);
5054 arc_set_attribute_string (Tag_ARC_ISA_config
, s
);
5056 /* Tag_ARC_ISA_mpy_option. */
5057 arc_set_attribute_int (Tag_ARC_ISA_mpy_option
, mpy_option
);
5059 /* Tag_ARC_ABI_pic. */
5060 arc_set_attribute_int (Tag_ARC_ABI_pic
, pic_option
);
5062 /* Tag_ARC_ABI_sda. */
5063 arc_set_attribute_int (Tag_ARC_ABI_sda
, sda_option
);
5065 /* Tag_ARC_ABI_tls. */
5066 arc_set_attribute_int (Tag_ARC_ABI_tls
, tls_option
);
5068 /* Tag_ARC_ATR_version. */
5069 arc_set_attribute_int (Tag_ARC_ATR_version
, 1);
5071 /* Tag_ARC_ABI_rf16. */
5072 if (attributes_set_explicitly
[Tag_ARC_ABI_rf16
]
5073 && bfd_elf_get_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
5077 as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full "
5079 if (!bfd_elf_add_proc_attr_int (stdoutput
, Tag_ARC_ABI_rf16
, 0))
5080 as_fatal (_("error adding attribute: %s"),
5081 bfd_errmsg (bfd_get_error ()));
5085 /* Add the default contents for the .ARC.attributes section. */
5088 arc_md_finish (void)
5090 arc_set_public_attributes ();
5092 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
5093 as_fatal (_("could not set architecture and machine"));
5095 bfd_set_private_flags (stdoutput
, selected_cpu
.eflags
);
5098 void arc_copy_symbol_attributes (symbolS
*dest
, symbolS
*src
)
5100 ARC_GET_FLAG (dest
) = ARC_GET_FLAG (src
);
5103 int arc_convert_symbolic_attribute (const char *name
)
5112 #define T(tag) {#tag, tag}
5113 T (Tag_ARC_PCS_config
),
5114 T (Tag_ARC_CPU_base
),
5115 T (Tag_ARC_CPU_variation
),
5116 T (Tag_ARC_CPU_name
),
5117 T (Tag_ARC_ABI_rf16
),
5118 T (Tag_ARC_ABI_osver
),
5119 T (Tag_ARC_ABI_sda
),
5120 T (Tag_ARC_ABI_pic
),
5121 T (Tag_ARC_ABI_tls
),
5122 T (Tag_ARC_ABI_enumsize
),
5123 T (Tag_ARC_ABI_exceptions
),
5124 T (Tag_ARC_ABI_double_size
),
5125 T (Tag_ARC_ISA_config
),
5126 T (Tag_ARC_ISA_apex
),
5127 T (Tag_ARC_ISA_mpy_option
),
5128 T (Tag_ARC_ATR_version
)
5136 for (i
= 0; i
< ARRAY_SIZE (attribute_table
); i
++)
5137 if (streq (name
, attribute_table
[i
].name
))
5138 return attribute_table
[i
].tag
;
5144 eval: (c-set-style "gnu")