1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2018 Free Software Foundation, Inc.
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
25 #include "struc-symbol.h"
26 #include "dwarf2dbg.h"
27 #include "dw2gencfi.h"
28 #include "safe-ctype.h"
30 #include "opcode/arc.h"
31 #include "opcode/arc-attrs.h"
33 #include "../opcodes/arc-ext.h"
35 /* Defines section. */
37 #define MAX_INSN_FIXUPS 2
38 #define MAX_CONSTR_STR 20
39 #define FRAG_MAX_GROWTH 8
42 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
44 # define pr_debug(fmt, args...)
47 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
48 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
49 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) \
50 && (SUB_OPCODE (x) == 0x28))
52 /* Equal to MAX_PRECISION in atof-ieee.c. */
53 #define MAX_LITTLENUMS 6
55 #ifndef TARGET_WITH_CPU
56 #define TARGET_WITH_CPU "arc700"
57 #endif /* TARGET_WITH_CPU */
59 #define ARC_GET_FLAG(s) (*symbol_get_tc (s))
60 #define ARC_SET_FLAG(s,v) (*symbol_get_tc (s) |= (v))
61 #define streq(a, b) (strcmp (a, b) == 0)
63 /* Enum used to enumerate the relaxable ins operands. */
68 REGISTER_S
, /* Register for short instruction(s). */
69 REGISTER_NO_GP
, /* Is a register but not gp register specifically. */
70 REGISTER_DUP
, /* Duplication of previous operand of type register. */
102 /* Macros section. */
104 #define regno(x) ((x) & 0x3F)
105 #define is_ir_num(x) (((x) & ~0x3F) == 0)
106 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
107 #define is_spfp_p(op) (((sc) == SPX))
108 #define is_dpfp_p(op) (((sc) == DPX))
109 #define is_fpuda_p(op) (((sc) == DPA))
110 #define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH \
111 || (op)->insn_class == JUMP \
112 || (op)->insn_class == BRCC \
113 || (op)->insn_class == BBIT0 \
114 || (op)->insn_class == BBIT1 \
115 || (op)->insn_class == BI \
116 || (op)->insn_class == EI \
117 || (op)->insn_class == ENTER \
118 || (op)->insn_class == JLI \
119 || (op)->insn_class == LOOP \
120 || (op)->insn_class == LEAVE \
122 #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL))
123 #define is_nps400_p(op) (((sc) == NPS400))
125 /* Generic assembler global variables which must be defined by all
128 /* Characters which always start a comment. */
129 const char comment_chars
[] = "#;";
131 /* Characters which start a comment at the beginning of a line. */
132 const char line_comment_chars
[] = "#";
134 /* Characters which may be used to separate multiple commands on a
136 const char line_separator_chars
[] = "`";
138 /* Characters which are used to indicate an exponent in a floating
140 const char EXP_CHARS
[] = "eE";
142 /* Chars that mean this number is a floating point constant
143 As in 0f12.456 or 0d1.2345e12. */
144 const char FLT_CHARS
[] = "rRsSfFdD";
147 extern int target_big_endian
;
148 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
149 static int byte_order
= DEFAULT_BYTE_ORDER
;
151 /* Arc extension section. */
152 static segT arcext_section
;
154 /* By default relaxation is disabled. */
155 static int relaxation_state
= 0;
157 extern int arc_get_mach (char *);
159 /* Forward declarations. */
160 static void arc_lcomm (int);
161 static void arc_option (int);
162 static void arc_extra_reloc (int);
163 static void arc_extinsn (int);
164 static void arc_extcorereg (int);
165 static void arc_attribute (int);
167 const pseudo_typeS md_pseudo_table
[] =
169 /* Make sure that .word is 32 bits. */
172 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
173 { "lcomm", arc_lcomm
, 0 },
174 { "lcommon", arc_lcomm
, 0 },
175 { "cpu", arc_option
, 0 },
177 { "arc_attribute", arc_attribute
, 0 },
178 { "extinstruction", arc_extinsn
, 0 },
179 { "extcoreregister", arc_extcorereg
, EXT_CORE_REGISTER
},
180 { "extauxregister", arc_extcorereg
, EXT_AUX_REGISTER
},
181 { "extcondcode", arc_extcorereg
, EXT_COND_CODE
},
183 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
184 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
189 const char *md_shortopts
= "";
193 OPTION_EB
= OPTION_MD_BASE
,
211 /* The following options are deprecated and provided here only for
212 compatibility reasons. */
235 struct option md_longopts
[] =
237 { "EB", no_argument
, NULL
, OPTION_EB
},
238 { "EL", no_argument
, NULL
, OPTION_EL
},
239 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
240 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
241 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
242 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
243 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
244 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
245 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
246 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
247 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
248 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
249 { "mnps400", no_argument
, NULL
, OPTION_NPS400
},
251 /* Floating point options */
252 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
253 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
254 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
255 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
256 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
257 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
258 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
259 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
260 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
261 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
262 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
264 /* The following options are deprecated and provided here only for
265 compatibility reasons. */
266 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
267 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
268 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
269 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
270 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
271 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
272 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
273 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
274 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
275 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
276 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
277 { "mea", no_argument
, NULL
, OPTION_EA
},
278 { "mEA", no_argument
, NULL
, OPTION_EA
},
279 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
280 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
281 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
282 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
283 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
284 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
285 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
286 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
287 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
288 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
289 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
290 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
291 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
292 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
293 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
295 { NULL
, no_argument
, NULL
, 0 }
298 size_t md_longopts_size
= sizeof (md_longopts
);
300 /* Local data and data types. */
302 /* Used since new relocation types are introduced in this
303 file (DUMMY_RELOC_LITUSE_*). */
304 typedef int extended_bfd_reloc_code_real_type
;
310 extended_bfd_reloc_code_real_type reloc
;
312 /* index into arc_operands. */
313 unsigned int opindex
;
315 /* PC-relative, used by internals fixups. */
318 /* TRUE if this fixup is for LIMM operand. */
324 unsigned long long int insn
;
326 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
328 unsigned int len
; /* Length of instruction in bytes. */
329 bfd_boolean has_limm
; /* Boolean value: TRUE if limm field is
331 bfd_boolean relax
; /* Boolean value: TRUE if needs
335 /* Structure to hold any last two instructions. */
336 static struct arc_last_insn
338 /* Saved instruction opcode. */
339 const struct arc_opcode
*opcode
;
341 /* Boolean value: TRUE if current insn is short. */
342 bfd_boolean has_limm
;
344 /* Boolean value: TRUE if current insn has delay slot. */
345 bfd_boolean has_delay_slot
;
348 /* Extension instruction suffix classes. */
356 static const attributes_t suffixclass
[] =
358 { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG
},
359 { "SUFFIX_COND", 11, ARC_SUFFIX_COND
},
360 { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE
}
363 /* Extension instruction syntax classes. */
364 static const attributes_t syntaxclass
[] =
366 { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP
},
367 { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP
},
368 { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP
},
369 { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP
}
372 /* Extension instruction syntax classes modifiers. */
373 static const attributes_t syntaxclassmod
[] =
375 { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED
},
376 { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM
}
379 /* Extension register type. */
387 /* A structure to hold the additional conditional codes. */
390 struct arc_flag_operand
*arc_ext_condcode
;
392 } ext_condcode
= { NULL
, 0 };
394 /* Structure to hold an entry in ARC_OPCODE_HASH. */
395 struct arc_opcode_hash_entry
397 /* The number of pointers in the OPCODE list. */
400 /* Points to a list of opcode pointers. */
401 const struct arc_opcode
**opcode
;
404 /* Structure used for iterating through an arc_opcode_hash_entry. */
405 struct arc_opcode_hash_entry_iterator
407 /* Index into the OPCODE element of the arc_opcode_hash_entry. */
410 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
411 returned by this iterator. */
412 const struct arc_opcode
*opcode
;
415 /* Forward declaration. */
416 static void assemble_insn
417 (const struct arc_opcode
*, const expressionS
*, int,
418 const struct arc_flags
*, int, struct arc_insn
*);
420 /* The selection of the machine type can come from different sources. This
421 enum is used to track how the selection was made in order to perform
423 enum mach_selection_type
426 MACH_SELECTION_FROM_DEFAULT
,
427 MACH_SELECTION_FROM_CPU_DIRECTIVE
,
428 MACH_SELECTION_FROM_COMMAND_LINE
431 /* How the current machine type was selected. */
432 static enum mach_selection_type mach_selection_mode
= MACH_SELECTION_NONE
;
434 /* The hash table of instruction opcodes. */
435 static struct hash_control
*arc_opcode_hash
;
437 /* The hash table of register symbols. */
438 static struct hash_control
*arc_reg_hash
;
440 /* The hash table of aux register symbols. */
441 static struct hash_control
*arc_aux_hash
;
443 /* The hash table of address types. */
444 static struct hash_control
*arc_addrtype_hash
;
446 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \
447 { #NAME, ARC_OPCODE_ARC600, bfd_mach_arc_arc600, \
448 E_ARC_MACH_ARC600, EXTRA}
449 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \
450 { #NAME, ARC_OPCODE_ARC700, bfd_mach_arc_arc700, \
451 E_ARC_MACH_ARC700, EXTRA}
452 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \
453 { #NAME, ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2, \
454 EF_ARC_CPU_ARCV2EM, EXTRA}
455 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \
456 { #NAME, ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2, \
457 EF_ARC_CPU_ARCV2HS, EXTRA}
458 #define ARC_CPU_TYPE_NONE \
461 /* A table of CPU names and opcode sets. */
462 static const struct cpu_type
472 #include "elf/arc-cpu.def"
475 /* Information about the cpu/variant we're assembling for. */
476 static struct cpu_type selected_cpu
= { 0, 0, 0, E_ARC_OSABI_CURRENT
, 0 };
479 static unsigned mpy_option
= 0;
482 static unsigned pic_option
= 0;
484 /* Use small data. */
485 static unsigned sda_option
= 0;
488 static unsigned tls_option
= 0;
490 /* Command line given features. */
491 static unsigned cl_features
= 0;
493 /* Used by the arc_reloc_op table. Order is important. */
494 #define O_gotoff O_md1 /* @gotoff relocation. */
495 #define O_gotpc O_md2 /* @gotpc relocation. */
496 #define O_plt O_md3 /* @plt relocation. */
497 #define O_sda O_md4 /* @sda relocation. */
498 #define O_pcl O_md5 /* @pcl relocation. */
499 #define O_tlsgd O_md6 /* @tlsgd relocation. */
500 #define O_tlsie O_md7 /* @tlsie relocation. */
501 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
502 #define O_tpoff O_md9 /* @tpoff relocation. */
503 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
504 #define O_dtpoff O_md11 /* @dtpoff relocation. */
505 #define O_last O_dtpoff
507 /* Used to define a bracket as operand in tokens. */
508 #define O_bracket O_md32
510 /* Used to define a colon as an operand in tokens. */
511 #define O_colon O_md31
513 /* Used to define address types in nps400. */
514 #define O_addrtype O_md30
516 /* Dummy relocation, to be sorted out. */
517 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
519 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
521 /* A table to map the spelling of a relocation operand into an appropriate
522 bfd_reloc_code_real_type type. The table is assumed to be ordered such
523 that op-O_literal indexes into it. */
524 #define ARC_RELOC_TABLE(op) \
525 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
527 : (int) (op) - (int) O_gotoff) ])
529 #define DEF(NAME, RELOC, REQ) \
530 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
532 static const struct arc_reloc_op_tag
534 /* String to lookup. */
536 /* Size of the string. */
538 /* Which operator to use. */
540 extended_bfd_reloc_code_real_type reloc
;
541 /* Allows complex relocation expression like identifier@reloc +
543 unsigned int complex_expr
: 1;
547 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
548 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
549 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
550 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
551 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
552 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
553 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
554 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
555 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
556 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
557 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 1),
560 static const int arc_num_reloc_op
561 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
563 /* Structure for relaxable instruction that have to be swapped with a
564 smaller alternative instruction. */
565 struct arc_relaxable_ins
567 /* Mnemonic that should be checked. */
568 const char *mnemonic_r
;
570 /* Operands that should be checked.
571 Indexes of operands from operand array. */
572 enum rlx_operand_type operands
[6];
574 /* Flags that should be checked. */
575 unsigned flag_classes
[5];
577 /* Mnemonic (smaller) alternative to be used later for relaxation. */
578 const char *mnemonic_alt
;
580 /* Index of operand that generic relaxation has to check. */
583 /* Base subtype index used. */
584 enum arc_rlx_types subtype
;
587 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
588 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
589 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
593 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
594 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
595 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
600 /* ARC relaxation table. */
601 const relax_typeS md_relax_table
[] =
608 RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL
),
609 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE
),
613 RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B
),
614 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE
),
619 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6
),
620 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM
),
621 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
623 /* LD_S a, [b, u7] ->
624 LD<zz><.x><.aa><.di> a, [b, s9] ->
625 LD<zz><.x><.aa><.di> a, [b, limm] */
626 RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9
),
627 RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM
),
628 RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE
),
633 RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12
),
634 RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM
),
635 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
639 SUB<.f> a, b, limm. */
640 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6
),
641 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM
),
642 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
644 /* MPY<.f> a, b, u6 ->
645 MPY<.f> a, b, limm. */
646 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM
),
647 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
649 /* MOV<.f><.cc> b, u6 ->
650 MOV<.f><.cc> b, limm. */
651 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM
),
652 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
654 /* ADD<.f><.cc> b, b, u6 ->
655 ADD<.f><.cc> b, b, limm. */
656 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM
),
657 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
660 /* Order of this table's entries matters! */
661 const struct arc_relaxable_ins arc_relaxable_insns
[] =
663 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
664 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
665 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
666 2, ARC_RLX_ADD_RRU6
},
667 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
669 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
671 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
672 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
673 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
674 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
675 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
676 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
677 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
678 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
680 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
682 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
686 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
688 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
689 symbolS
* GOT_symbol
= 0;
691 /* Set to TRUE when we assemble instructions. */
692 static bfd_boolean assembling_insn
= FALSE
;
694 /* List with attributes set explicitly. */
695 static bfd_boolean attributes_set_explicitly
[NUM_KNOWN_OBJ_ATTRIBUTES
];
697 /* Functions implementation. */
699 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
700 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
701 are no matching entries in ARC_OPCODE_HASH. */
703 static const struct arc_opcode_hash_entry
*
704 arc_find_opcode (const char *name
)
706 const struct arc_opcode_hash_entry
*entry
;
708 entry
= hash_find (arc_opcode_hash
, name
);
712 /* Initialise the iterator ITER. */
715 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator
*iter
)
721 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
722 calls to this function. Return NULL when all ARC_OPCODE entries have
725 static const struct arc_opcode
*
726 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry
*entry
,
727 struct arc_opcode_hash_entry_iterator
*iter
)
729 if (iter
->opcode
== NULL
&& iter
->index
== 0)
731 gas_assert (entry
->count
> 0);
732 iter
->opcode
= entry
->opcode
[iter
->index
];
734 else if (iter
->opcode
!= NULL
)
736 const char *old_name
= iter
->opcode
->name
;
739 if (iter
->opcode
->name
== NULL
740 || strcmp (old_name
, iter
->opcode
->name
) != 0)
743 if (iter
->index
== entry
->count
)
746 iter
->opcode
= entry
->opcode
[iter
->index
];
753 /* Insert an opcode into opcode hash structure. */
756 arc_insert_opcode (const struct arc_opcode
*opcode
)
758 const char *name
, *retval
;
759 struct arc_opcode_hash_entry
*entry
;
762 entry
= hash_find (arc_opcode_hash
, name
);
765 entry
= XNEW (struct arc_opcode_hash_entry
);
767 entry
->opcode
= NULL
;
769 retval
= hash_insert (arc_opcode_hash
, name
, (void *) entry
);
771 as_fatal (_("internal error: can't hash opcode '%s': %s"),
775 entry
->opcode
= XRESIZEVEC (const struct arc_opcode
*, entry
->opcode
,
778 if (entry
->opcode
== NULL
)
779 as_fatal (_("Virtual memory exhausted"));
781 entry
->opcode
[entry
->count
] = opcode
;
786 /* Like md_number_to_chars but for middle-endian values. The 4-byte limm
787 value, is encoded as 'middle-endian' for a little-endian target. This
788 function is used for regular 4, 6, and 8 byte instructions as well. */
791 md_number_to_chars_midend (char *buf
, unsigned long long val
, int n
)
796 md_number_to_chars (buf
, val
, n
);
799 md_number_to_chars (buf
, (val
& 0xffff00000000) >> 32, 2);
800 md_number_to_chars_midend (buf
+ 2, (val
& 0xffffffff), 4);
803 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
804 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
807 md_number_to_chars_midend (buf
, (val
& 0xffffffff00000000) >> 32, 4);
808 md_number_to_chars_midend (buf
+ 4, (val
& 0xffffffff), 4);
815 /* Check if a feature is allowed for a specific CPU. */
818 arc_check_feature (void)
822 if (!selected_cpu
.features
823 || !selected_cpu
.name
)
826 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
827 if ((selected_cpu
.features
& feature_list
[i
].feature
)
828 && !(selected_cpu
.flags
& feature_list
[i
].cpus
))
829 as_bad (_("invalid %s option for %s cpu"), feature_list
[i
].name
,
832 for (i
= 0; i
< ARRAY_SIZE (conflict_list
); i
++)
833 if ((selected_cpu
.features
& conflict_list
[i
]) == conflict_list
[i
])
834 as_bad(_("conflicting ISA extension attributes."));
837 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
838 the relevant static global variables. Parameter SEL describes where
839 this selection originated from. */
842 arc_select_cpu (const char *arg
, enum mach_selection_type sel
)
846 /* We should only set a default if we've not made a selection from some
848 gas_assert (sel
!= MACH_SELECTION_FROM_DEFAULT
849 || mach_selection_mode
== MACH_SELECTION_NONE
);
851 if ((mach_selection_mode
== MACH_SELECTION_FROM_CPU_DIRECTIVE
)
852 && (sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
))
853 as_bad (_("Multiple .cpu directives found"));
855 /* Look for a matching entry in CPU_TYPES array. */
856 for (i
= 0; cpu_types
[i
].name
; ++i
)
858 if (!strcasecmp (cpu_types
[i
].name
, arg
))
860 /* If a previous selection was made on the command line, then we
861 allow later selections on the command line to override earlier
862 ones. However, a selection from a '.cpu NAME' directive must
863 match the command line selection, or we give a warning. */
864 if (mach_selection_mode
== MACH_SELECTION_FROM_COMMAND_LINE
)
866 gas_assert (sel
== MACH_SELECTION_FROM_COMMAND_LINE
867 || sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
);
868 if (sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
869 && selected_cpu
.mach
!= cpu_types
[i
].mach
)
871 as_warn (_("Command-line value overrides \".cpu\" directive"));
876 /* Initialise static global data about selected machine type. */
877 selected_cpu
.flags
= cpu_types
[i
].flags
;
878 selected_cpu
.name
= cpu_types
[i
].name
;
879 selected_cpu
.features
= cpu_types
[i
].features
| cl_features
;
880 selected_cpu
.mach
= cpu_types
[i
].mach
;
881 selected_cpu
.eflags
= ((selected_cpu
.eflags
& ~EF_ARC_MACH_MSK
)
882 | cpu_types
[i
].eflags
);
887 if (!cpu_types
[i
].name
)
888 as_fatal (_("unknown architecture: %s\n"), arg
);
890 /* Check if set features are compatible with the chosen CPU. */
891 arc_check_feature ();
893 mach_selection_mode
= sel
;
896 /* Here ends all the ARCompact extension instruction assembling
900 arc_extra_reloc (int r_type
)
903 symbolS
*sym
, *lab
= NULL
;
905 if (*input_line_pointer
== '@')
906 input_line_pointer
++;
907 c
= get_symbol_name (&sym_name
);
908 sym
= symbol_find_or_make (sym_name
);
909 restore_line_pointer (c
);
910 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
912 ++input_line_pointer
;
914 c
= get_symbol_name (&lab_name
);
915 lab
= symbol_find_or_make (lab_name
);
916 restore_line_pointer (c
);
919 /* These relocations exist as a mechanism for the compiler to tell the
920 linker how to patch the code if the tls model is optimised. However,
921 the relocation itself does not require any space within the assembler
922 fragment, and so we pass a size of 0.
924 The lines that generate these relocations look like this:
926 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
928 The '.tls_gd_ld @.tdata' is processed first and generates the
929 additional relocation, while the 'bl __tls_get_addr@plt' is processed
930 second and generates the additional branch.
932 It is possible that the additional relocation generated by the
933 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
934 while the 'bl __tls_get_addr@plt' will be generated as the first thing
935 in the next fragment. This will be fine; both relocations will still
936 appear to be at the same address in the generated object file.
937 However, this only works as the additional relocation is generated
938 with size of 0 bytes. */
940 = fix_new (frag_now
, /* Which frag? */
941 frag_now_fix (), /* Where in that frag? */
942 0, /* size: 1, 2, or 4 usually. */
943 sym
, /* X_add_symbol. */
944 0, /* X_add_number. */
945 FALSE
, /* TRUE if PC-relative relocation. */
946 r_type
/* Relocation type. */);
947 fixP
->fx_subsy
= lab
;
951 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
952 symbolS
*symbolP
, addressT size
)
957 if (*input_line_pointer
== ',')
959 align
= parse_align (1);
961 if (align
== (addressT
) -1)
976 bss_alloc (symbolP
, size
, align
);
977 S_CLEAR_EXTERNAL (symbolP
);
983 arc_lcomm (int ignore
)
985 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
988 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
991 /* Select the cpu we're assembling for. */
994 arc_option (int ignore ATTRIBUTE_UNUSED
)
998 const char *cpu_name
;
1000 c
= get_symbol_name (&cpu
);
1003 if ((!strcmp ("ARC600", cpu
))
1004 || (!strcmp ("ARC601", cpu
))
1005 || (!strcmp ("A6", cpu
)))
1006 cpu_name
= "arc600";
1007 else if ((!strcmp ("ARC700", cpu
))
1008 || (!strcmp ("A7", cpu
)))
1009 cpu_name
= "arc700";
1010 else if (!strcmp ("EM", cpu
))
1012 else if (!strcmp ("HS", cpu
))
1014 else if (!strcmp ("NPS400", cpu
))
1015 cpu_name
= "nps400";
1017 arc_select_cpu (cpu_name
, MACH_SELECTION_FROM_CPU_DIRECTIVE
);
1019 restore_line_pointer (c
);
1020 demand_empty_rest_of_line ();
1023 /* Smartly print an expression. */
1026 debug_exp (expressionS
*t
)
1028 const char *name ATTRIBUTE_UNUSED
;
1029 const char *namemd ATTRIBUTE_UNUSED
;
1031 pr_debug ("debug_exp: ");
1035 default: name
= "unknown"; break;
1036 case O_illegal
: name
= "O_illegal"; break;
1037 case O_absent
: name
= "O_absent"; break;
1038 case O_constant
: name
= "O_constant"; break;
1039 case O_symbol
: name
= "O_symbol"; break;
1040 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1041 case O_register
: name
= "O_register"; break;
1042 case O_big
: name
= "O_big"; break;
1043 case O_uminus
: name
= "O_uminus"; break;
1044 case O_bit_not
: name
= "O_bit_not"; break;
1045 case O_logical_not
: name
= "O_logical_not"; break;
1046 case O_multiply
: name
= "O_multiply"; break;
1047 case O_divide
: name
= "O_divide"; break;
1048 case O_modulus
: name
= "O_modulus"; break;
1049 case O_left_shift
: name
= "O_left_shift"; break;
1050 case O_right_shift
: name
= "O_right_shift"; break;
1051 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1052 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1053 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1054 case O_bit_and
: name
= "O_bit_and"; break;
1055 case O_add
: name
= "O_add"; break;
1056 case O_subtract
: name
= "O_subtract"; break;
1057 case O_eq
: name
= "O_eq"; break;
1058 case O_ne
: name
= "O_ne"; break;
1059 case O_lt
: name
= "O_lt"; break;
1060 case O_le
: name
= "O_le"; break;
1061 case O_ge
: name
= "O_ge"; break;
1062 case O_gt
: name
= "O_gt"; break;
1063 case O_logical_and
: name
= "O_logical_and"; break;
1064 case O_logical_or
: name
= "O_logical_or"; break;
1065 case O_index
: name
= "O_index"; break;
1066 case O_bracket
: name
= "O_bracket"; break;
1067 case O_colon
: name
= "O_colon"; break;
1068 case O_addrtype
: name
= "O_addrtype"; break;
1073 default: namemd
= "unknown"; break;
1074 case O_gotoff
: namemd
= "O_gotoff"; break;
1075 case O_gotpc
: namemd
= "O_gotpc"; break;
1076 case O_plt
: namemd
= "O_plt"; break;
1077 case O_sda
: namemd
= "O_sda"; break;
1078 case O_pcl
: namemd
= "O_pcl"; break;
1079 case O_tlsgd
: namemd
= "O_tlsgd"; break;
1080 case O_tlsie
: namemd
= "O_tlsie"; break;
1081 case O_tpoff9
: namemd
= "O_tpoff9"; break;
1082 case O_tpoff
: namemd
= "O_tpoff"; break;
1083 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
1084 case O_dtpoff
: namemd
= "O_dtpoff"; break;
1087 pr_debug ("%s (%s, %s, %d, %s)", name
,
1088 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1089 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1090 (int) t
->X_add_number
,
1091 (t
->X_md
) ? namemd
: "--");
1096 /* Parse the arguments to an opcode. */
1099 tokenize_arguments (char *str
,
1103 char *old_input_line_pointer
;
1104 bfd_boolean saw_comma
= FALSE
;
1105 bfd_boolean saw_arg
= FALSE
;
1110 const struct arc_reloc_op_tag
*r
;
1112 char *reloc_name
, c
;
1114 memset (tok
, 0, sizeof (*tok
) * ntok
);
1116 /* Save and restore input_line_pointer around this function. */
1117 old_input_line_pointer
= input_line_pointer
;
1118 input_line_pointer
= str
;
1120 while (*input_line_pointer
)
1123 switch (*input_line_pointer
)
1129 input_line_pointer
++;
1130 if (saw_comma
|| !saw_arg
)
1137 ++input_line_pointer
;
1139 if (!saw_arg
|| num_args
== ntok
)
1141 tok
->X_op
= O_bracket
;
1148 input_line_pointer
++;
1149 if (brk_lvl
|| num_args
== ntok
)
1152 tok
->X_op
= O_bracket
;
1158 input_line_pointer
++;
1159 if (!saw_arg
|| num_args
== ntok
)
1161 tok
->X_op
= O_colon
;
1168 /* We have labels, function names and relocations, all
1169 starting with @ symbol. Sort them out. */
1170 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1174 tok
->X_op
= O_symbol
;
1175 tok
->X_md
= O_absent
;
1177 if (*input_line_pointer
!= '@')
1178 goto normalsymbol
; /* This is not a relocation. */
1182 /* A relocation operand has the following form
1183 @identifier@relocation_type. The identifier is already
1185 if (tok
->X_op
!= O_symbol
)
1187 as_bad (_("No valid label relocation operand"));
1191 /* Parse @relocation_type. */
1192 input_line_pointer
++;
1193 c
= get_symbol_name (&reloc_name
);
1194 len
= input_line_pointer
- reloc_name
;
1197 as_bad (_("No relocation operand"));
1201 /* Go through known relocation and try to find a match. */
1202 r
= &arc_reloc_op
[0];
1203 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1204 if (len
== r
->length
1205 && memcmp (reloc_name
, r
->name
, len
) == 0)
1209 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
1213 *input_line_pointer
= c
;
1214 SKIP_WHITESPACE_AFTER_NAME ();
1215 /* Extra check for TLS: base. */
1216 if (*input_line_pointer
== '@')
1219 if (tok
->X_op_symbol
!= NULL
1220 || tok
->X_op
!= O_symbol
)
1222 as_bad (_("Unable to parse TLS base: %s"),
1223 input_line_pointer
);
1226 input_line_pointer
++;
1228 c
= get_symbol_name (&sym_name
);
1229 base
= symbol_find_or_make (sym_name
);
1230 tok
->X_op
= O_subtract
;
1231 tok
->X_op_symbol
= base
;
1232 restore_line_pointer (c
);
1233 tmpE
.X_add_number
= 0;
1235 if ((*input_line_pointer
!= '+')
1236 && (*input_line_pointer
!= '-'))
1238 tmpE
.X_add_number
= 0;
1242 /* Parse the constant of a complex relocation expression
1243 like @identifier@reloc +/- const. */
1244 if (! r
->complex_expr
)
1246 as_bad (_("@%s is not a complex relocation."), r
->name
);
1250 if (tmpE
.X_op
!= O_constant
)
1252 as_bad (_("Bad expression: @%s + %s."),
1253 r
->name
, input_line_pointer
);
1259 tok
->X_add_number
= tmpE
.X_add_number
;
1270 /* Can be a register. */
1271 ++input_line_pointer
;
1275 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1278 tok
->X_op
= O_absent
;
1279 tok
->X_md
= O_absent
;
1282 /* Legacy: There are cases when we have
1283 identifier@relocation_type, if it is the case parse the
1284 relocation type as well. */
1285 if (*input_line_pointer
== '@')
1291 if (tok
->X_op
== O_illegal
1292 || tok
->X_op
== O_absent
1293 || num_args
== ntok
)
1305 if (saw_comma
|| brk_lvl
)
1307 input_line_pointer
= old_input_line_pointer
;
1313 as_bad (_("Brackets in operand field incorrect"));
1315 as_bad (_("extra comma"));
1317 as_bad (_("missing argument"));
1319 as_bad (_("missing comma or colon"));
1320 input_line_pointer
= old_input_line_pointer
;
1324 /* Parse the flags to a structure. */
1327 tokenize_flags (const char *str
,
1328 struct arc_flags flags
[],
1331 char *old_input_line_pointer
;
1332 bfd_boolean saw_flg
= FALSE
;
1333 bfd_boolean saw_dot
= FALSE
;
1337 memset (flags
, 0, sizeof (*flags
) * nflg
);
1339 /* Save and restore input_line_pointer around this function. */
1340 old_input_line_pointer
= input_line_pointer
;
1341 input_line_pointer
= (char *) str
;
1343 while (*input_line_pointer
)
1345 switch (*input_line_pointer
)
1352 input_line_pointer
++;
1360 if (saw_flg
&& !saw_dot
)
1363 if (num_flags
>= nflg
)
1366 flgnamelen
= strspn (input_line_pointer
,
1367 "abcdefghijklmnopqrstuvwxyz0123456789");
1368 if (flgnamelen
> MAX_FLAG_NAME_LENGTH
)
1371 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1373 input_line_pointer
+= flgnamelen
;
1383 input_line_pointer
= old_input_line_pointer
;
1388 as_bad (_("extra dot"));
1390 as_bad (_("unrecognized flag"));
1392 as_bad (_("failed to parse flags"));
1393 input_line_pointer
= old_input_line_pointer
;
1397 /* Apply the fixups in order. */
1400 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1404 for (i
= 0; i
< insn
->nfixups
; i
++)
1406 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1407 int size
, pcrel
, offset
= 0;
1409 /* FIXME! the reloc size is wrong in the BFD file.
1410 When it is fixed please delete me. */
1411 size
= ((insn
->len
== 2) && !fixup
->islong
) ? 2 : 4;
1416 /* Some fixups are only used internally, thus no howto. */
1417 if ((int) fixup
->reloc
== 0)
1418 as_fatal (_("Unhandled reloc type"));
1420 if ((int) fixup
->reloc
< 0)
1422 /* FIXME! the reloc size is wrong in the BFD file.
1423 When it is fixed please enable me.
1424 size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
1425 pcrel
= fixup
->pcrel
;
1429 reloc_howto_type
*reloc_howto
=
1430 bfd_reloc_type_lookup (stdoutput
,
1431 (bfd_reloc_code_real_type
) fixup
->reloc
);
1432 gas_assert (reloc_howto
);
1434 /* FIXME! the reloc size is wrong in the BFD file.
1435 When it is fixed please enable me.
1436 size = bfd_get_reloc_size (reloc_howto); */
1437 pcrel
= reloc_howto
->pc_relative
;
1440 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1442 fragP
->fr_file
, fragP
->fr_line
,
1443 (fixup
->reloc
< 0) ? "Internal" :
1444 bfd_get_reloc_code_name (fixup
->reloc
),
1447 fix_new_exp (fragP
, fix
+ offset
,
1448 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1450 /* Check for ZOLs, and update symbol info if any. */
1451 if (LP_INSN (insn
->insn
))
1453 gas_assert (fixup
->exp
.X_add_symbol
);
1454 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1459 /* Actually output an instruction with its fixup. */
1462 emit_insn0 (struct arc_insn
*insn
, char *where
, bfd_boolean relax
)
1467 pr_debug ("Emit insn : 0x%llx\n", insn
->insn
);
1468 pr_debug ("\tLength : 0x%d\n", insn
->len
);
1469 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1471 /* Write out the instruction. */
1472 total_len
= insn
->len
+ (insn
->has_limm
? 4 : 0);
1474 f
= frag_more (total_len
);
1476 md_number_to_chars_midend(f
, insn
->insn
, insn
->len
);
1479 md_number_to_chars_midend (f
+ insn
->len
, insn
->limm
, 4);
1480 dwarf2_emit_insn (total_len
);
1483 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1487 emit_insn1 (struct arc_insn
*insn
)
1489 /* How frag_var's args are currently configured:
1490 - rs_machine_dependent, to dictate it's a relaxation frag.
1491 - FRAG_MAX_GROWTH, maximum size of instruction
1492 - 0, variable size that might grow...unused by generic relaxation.
1493 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1494 - s, opand expression.
1495 - 0, offset but it's unused.
1496 - 0, opcode but it's unused. */
1497 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1498 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1500 if (frag_room () < FRAG_MAX_GROWTH
)
1502 /* Handle differently when frag literal memory is exhausted.
1503 This is used because when there's not enough memory left in
1504 the current frag, a new frag is created and the information
1505 we put into frag_now->tc_frag_data is disregarded. */
1507 struct arc_relax_type relax_info_copy
;
1508 relax_substateT subtype
= frag_now
->fr_subtype
;
1510 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1511 sizeof (struct arc_relax_type
));
1513 frag_wane (frag_now
);
1514 frag_grow (FRAG_MAX_GROWTH
);
1516 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1517 sizeof (struct arc_relax_type
));
1519 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1523 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1524 frag_now
->fr_subtype
, s
, 0, 0);
1528 emit_insn (struct arc_insn
*insn
)
1533 emit_insn0 (insn
, NULL
, FALSE
);
1536 /* Check whether a symbol involves a register. */
1539 contains_register (symbolS
*sym
)
1543 expressionS
*ex
= symbol_get_value_expression (sym
);
1545 return ((O_register
== ex
->X_op
)
1546 && !contains_register (ex
->X_add_symbol
)
1547 && !contains_register (ex
->X_op_symbol
));
1553 /* Returns the register number within a symbol. */
1556 get_register (symbolS
*sym
)
1558 if (!contains_register (sym
))
1561 expressionS
*ex
= symbol_get_value_expression (sym
);
1562 return regno (ex
->X_add_number
);
1565 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1566 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1569 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1576 case BFD_RELOC_ARC_SDA_LDST
:
1577 case BFD_RELOC_ARC_SDA_LDST1
:
1578 case BFD_RELOC_ARC_SDA_LDST2
:
1579 case BFD_RELOC_ARC_SDA16_LD
:
1580 case BFD_RELOC_ARC_SDA16_LD1
:
1581 case BFD_RELOC_ARC_SDA16_LD2
:
1582 case BFD_RELOC_ARC_SDA16_ST2
:
1583 case BFD_RELOC_ARC_SDA32_ME
:
1590 /* Allocates a tok entry. */
1593 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1595 if (ntok
> MAX_INSN_ARGS
- 2)
1596 return 0; /* No space left. */
1599 return 0; /* Incorrect args. */
1601 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1604 return 1; /* Success. */
1605 return allocate_tok (tok
, ntok
- 1, cidx
);
1608 /* Check if an particular ARC feature is enabled. */
1611 check_cpu_feature (insn_subclass_t sc
)
1613 if (is_code_density_p (sc
) && !(selected_cpu
.features
& CD
))
1616 if (is_spfp_p (sc
) && !(selected_cpu
.features
& SPX
))
1619 if (is_dpfp_p (sc
) && !(selected_cpu
.features
& DPX
))
1622 if (is_fpuda_p (sc
) && !(selected_cpu
.features
& DPA
))
1625 if (is_nps400_p (sc
) && !(selected_cpu
.features
& NPS400
))
1631 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1632 operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG
1633 array and returns TRUE if the flag operands all match, otherwise,
1634 returns FALSE, in which case the FIRST_PFLAG array may have been
1638 parse_opcode_flags (const struct arc_opcode
*opcode
,
1640 struct arc_flags
*first_pflag
)
1643 const unsigned char *flgidx
;
1646 for (i
= 0; i
< nflgs
; i
++)
1647 first_pflag
[i
].flgp
= NULL
;
1649 /* Check the flags. Iterate over the valid flag classes. */
1650 for (flgidx
= opcode
->flags
; *flgidx
; ++flgidx
)
1652 /* Get a valid flag class. */
1653 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1654 const unsigned *flgopridx
;
1656 struct arc_flags
*pflag
= NULL
;
1658 /* Check if opcode has implicit flag classes. */
1659 if (cl_flags
->flag_class
& F_CLASS_IMPLICIT
)
1662 /* Check for extension conditional codes. */
1663 if (ext_condcode
.arc_ext_condcode
1664 && cl_flags
->flag_class
& F_CLASS_EXTEND
)
1666 struct arc_flag_operand
*pf
= ext_condcode
.arc_ext_condcode
;
1669 pflag
= first_pflag
;
1670 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1672 if (!strcmp (pf
->name
, pflag
->name
))
1674 if (pflag
->flgp
!= NULL
)
1687 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1689 const struct arc_flag_operand
*flg_operand
;
1691 pflag
= first_pflag
;
1692 flg_operand
= &arc_flag_operands
[*flgopridx
];
1693 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1695 /* Match against the parsed flags. */
1696 if (!strcmp (flg_operand
->name
, pflag
->name
))
1698 if (pflag
->flgp
!= NULL
)
1701 pflag
->flgp
= flg_operand
;
1703 break; /* goto next flag class and parsed flag. */
1708 if ((cl_flags
->flag_class
& F_CLASS_REQUIRED
) && cl_matches
== 0)
1710 if ((cl_flags
->flag_class
& F_CLASS_OPTIONAL
) && cl_matches
> 1)
1714 /* Did I check all the parsed flags? */
1715 return lnflg
? FALSE
: TRUE
;
1719 /* Search forward through all variants of an opcode looking for a
1722 static const struct arc_opcode
*
1723 find_opcode_match (const struct arc_opcode_hash_entry
*entry
,
1726 struct arc_flags
*first_pflag
,
1729 const char **errmsg
)
1731 const struct arc_opcode
*opcode
;
1732 struct arc_opcode_hash_entry_iterator iter
;
1734 int got_cpu_match
= 0;
1735 expressionS bktok
[MAX_INSN_ARGS
];
1739 arc_opcode_hash_entry_iterator_init (&iter
);
1740 memset (&emptyE
, 0, sizeof (emptyE
));
1741 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1744 for (opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
);
1746 opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
))
1748 const unsigned char *opidx
;
1750 const expressionS
*t
= &emptyE
;
1752 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
1753 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1755 /* Don't match opcodes that don't exist on this
1757 if (!(opcode
->cpu
& selected_cpu
.flags
))
1760 if (!check_cpu_feature (opcode
->subclass
))
1766 /* Check the operands. */
1767 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1769 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1771 /* Only take input from real operands. */
1772 if (ARC_OPERAND_IS_FAKE (operand
))
1775 /* When we expect input, make sure we have it. */
1779 /* Match operand type with expression type. */
1780 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1782 case ARC_OPERAND_ADDRTYPE
:
1786 /* Check to be an address type. */
1787 if (tok
[tokidx
].X_op
!= O_addrtype
)
1790 /* All address type operands need to have an insert
1791 method in order to check that we have the correct
1793 gas_assert (operand
->insert
!= NULL
);
1794 (*operand
->insert
) (0, tok
[tokidx
].X_add_number
,
1796 if (*errmsg
!= NULL
)
1801 case ARC_OPERAND_IR
:
1802 /* Check to be a register. */
1803 if ((tok
[tokidx
].X_op
!= O_register
1804 || !is_ir_num (tok
[tokidx
].X_add_number
))
1805 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1808 /* If expect duplicate, make sure it is duplicate. */
1809 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1811 /* Check for duplicate. */
1812 if (t
->X_op
!= O_register
1813 || !is_ir_num (t
->X_add_number
)
1814 || (regno (t
->X_add_number
) !=
1815 regno (tok
[tokidx
].X_add_number
)))
1819 /* Special handling? */
1820 if (operand
->insert
)
1823 (*operand
->insert
)(0,
1824 regno (tok
[tokidx
].X_add_number
),
1828 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1830 /* Missing argument, create one. */
1831 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1834 tok
[tokidx
].X_op
= O_absent
;
1845 case ARC_OPERAND_BRAKET
:
1846 /* Check if bracket is also in opcode table as
1848 if (tok
[tokidx
].X_op
!= O_bracket
)
1852 case ARC_OPERAND_COLON
:
1853 /* Check if colon is also in opcode table as operand. */
1854 if (tok
[tokidx
].X_op
!= O_colon
)
1858 case ARC_OPERAND_LIMM
:
1859 case ARC_OPERAND_SIGNED
:
1860 case ARC_OPERAND_UNSIGNED
:
1861 switch (tok
[tokidx
].X_op
)
1869 /* Got an (too) early bracket, check if it is an
1870 ignored operand. N.B. This procedure works only
1871 when bracket is the last operand! */
1872 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1874 /* Insert the missing operand. */
1875 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1878 tok
[tokidx
].X_op
= O_absent
;
1886 const struct arc_aux_reg
*auxr
;
1888 if (opcode
->insn_class
!= AUXREG
)
1890 p
= S_GET_NAME (tok
[tokidx
].X_add_symbol
);
1892 /* For compatibility reasons, an aux register can
1893 be spelled with upper or lower case
1896 for (pp
= tmpp
; *pp
; ++pp
) *pp
= TOLOWER (*pp
);
1898 auxr
= hash_find (arc_aux_hash
, tmpp
);
1901 /* We modify the token array here, safe in the
1902 knowledge, that if this was the wrong
1903 choice then the original contents will be
1904 restored from BKTOK. */
1905 tok
[tokidx
].X_op
= O_constant
;
1906 tok
[tokidx
].X_add_number
= auxr
->address
;
1907 ARC_SET_FLAG (tok
[tokidx
].X_add_symbol
, ARC_FLAG_AUX
);
1911 if (tok
[tokidx
].X_op
!= O_constant
)
1916 /* Check the range. */
1917 if (operand
->bits
!= 32
1918 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1920 offsetT min
, max
, val
;
1921 val
= tok
[tokidx
].X_add_number
;
1923 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1925 max
= (1 << (operand
->bits
- 1)) - 1;
1926 min
= -(1 << (operand
->bits
- 1));
1930 max
= (1 << operand
->bits
) - 1;
1934 if (val
< min
|| val
> max
)
1937 /* Check alignments. */
1938 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1942 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1946 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1948 if (operand
->insert
)
1951 (*operand
->insert
)(0,
1952 tok
[tokidx
].X_add_number
,
1957 else if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1963 /* Check if it is register range. */
1964 if ((tok
[tokidx
].X_add_number
== 0)
1965 && contains_register (tok
[tokidx
].X_add_symbol
)
1966 && contains_register (tok
[tokidx
].X_op_symbol
))
1970 regs
= get_register (tok
[tokidx
].X_add_symbol
);
1972 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
1973 if (operand
->insert
)
1976 (*operand
->insert
)(0,
1989 if (operand
->default_reloc
== 0)
1990 goto match_failed
; /* The operand needs relocation. */
1992 /* Relocs requiring long immediate. FIXME! make it
1993 generic and move it to a function. */
1994 switch (tok
[tokidx
].X_md
)
2003 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
2007 if (!generic_reloc_p (operand
->default_reloc
))
2015 /* If expect duplicate, make sure it is duplicate. */
2016 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
2018 if (t
->X_op
== O_illegal
2019 || t
->X_op
== O_absent
2020 || t
->X_op
== O_register
2021 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
2028 /* Everything else should have been fake. */
2036 /* Setup ready for flag parsing. */
2037 if (!parse_opcode_flags (opcode
, nflgs
, first_pflag
))
2041 /* Possible match -- did we use all of our input? */
2051 /* Restore the original parameters. */
2052 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
2057 *pcpumatch
= got_cpu_match
;
2062 /* Swap operand tokens. */
2065 swap_operand (expressionS
*operand_array
,
2067 unsigned destination
)
2069 expressionS cpy_operand
;
2070 expressionS
*src_operand
;
2071 expressionS
*dst_operand
;
2074 if (source
== destination
)
2077 src_operand
= &operand_array
[source
];
2078 dst_operand
= &operand_array
[destination
];
2079 size
= sizeof (expressionS
);
2081 /* Make copy of operand to swap with and swap. */
2082 memcpy (&cpy_operand
, dst_operand
, size
);
2083 memcpy (dst_operand
, src_operand
, size
);
2084 memcpy (src_operand
, &cpy_operand
, size
);
2087 /* Check if *op matches *tok type.
2088 Returns FALSE if they don't match, TRUE if they match. */
2091 pseudo_operand_match (const expressionS
*tok
,
2092 const struct arc_operand_operation
*op
)
2094 offsetT min
, max
, val
;
2096 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
2102 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
2104 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
2106 val
= tok
->X_add_number
+ op
->count
;
2107 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
2109 max
= (1 << (operand_real
->bits
- 1)) - 1;
2110 min
= -(1 << (operand_real
->bits
- 1));
2114 max
= (1 << operand_real
->bits
) - 1;
2117 if (min
<= val
&& val
<= max
)
2123 /* Handle all symbols as long immediates or signed 9. */
2124 if (operand_real
->flags
& ARC_OPERAND_LIMM
2125 || ((operand_real
->flags
& ARC_OPERAND_SIGNED
)
2126 && operand_real
->bits
== 9))
2131 if (operand_real
->flags
& ARC_OPERAND_IR
)
2136 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2147 /* Find pseudo instruction in array. */
2149 static const struct arc_pseudo_insn
*
2150 find_pseudo_insn (const char *opname
,
2152 const expressionS
*tok
)
2154 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2155 const struct arc_operand_operation
*op
;
2159 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
2161 pseudo_insn
= &arc_pseudo_insns
[i
];
2162 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
2164 op
= pseudo_insn
->operand
;
2165 for (j
= 0; j
< ntok
; ++j
)
2166 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
2169 /* Found the right instruction. */
2177 /* Assumes the expressionS *tok is of sufficient size. */
2179 static const struct arc_opcode_hash_entry
*
2180 find_special_case_pseudo (const char *opname
,
2184 struct arc_flags
*pflags
)
2186 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2187 const struct arc_operand_operation
*operand_pseudo
;
2188 const struct arc_operand
*operand_real
;
2190 char construct_operand
[MAX_CONSTR_STR
];
2192 /* Find whether opname is in pseudo instruction array. */
2193 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
2195 if (pseudo_insn
== NULL
)
2198 /* Handle flag, Limited to one flag at the moment. */
2199 if (pseudo_insn
->flag_r
!= NULL
)
2200 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
2201 MAX_INSN_FLGS
- *nflgs
);
2203 /* Handle operand operations. */
2204 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2206 operand_pseudo
= &pseudo_insn
->operand
[i
];
2207 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
2209 if (operand_real
->flags
& ARC_OPERAND_BRAKET
2210 && !operand_pseudo
->needs_insert
)
2213 /* Has to be inserted (i.e. this token does not exist yet). */
2214 if (operand_pseudo
->needs_insert
)
2216 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2218 tok
[i
].X_op
= O_bracket
;
2223 /* Check if operand is a register or constant and handle it
2225 if (operand_real
->flags
& ARC_OPERAND_IR
)
2226 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
2227 operand_pseudo
->count
);
2229 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
2230 operand_pseudo
->count
);
2232 tokenize_arguments (construct_operand
, &tok
[i
], 1);
2236 else if (operand_pseudo
->count
)
2238 /* Operand number has to be adjusted accordingly (by operand
2240 switch (tok
[i
].X_op
)
2243 tok
[i
].X_add_number
+= operand_pseudo
->count
;
2256 /* Swap operands if necessary. Only supports one swap at the
2258 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2260 operand_pseudo
= &pseudo_insn
->operand
[i
];
2262 if (operand_pseudo
->swap_operand_idx
== i
)
2265 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
2267 /* Prevent a swap back later by breaking out. */
2271 return arc_find_opcode (pseudo_insn
->mnemonic_r
);
2274 static const struct arc_opcode_hash_entry
*
2275 find_special_case_flag (const char *opname
,
2277 struct arc_flags
*pflags
)
2281 unsigned flag_idx
, flag_arr_idx
;
2282 size_t flaglen
, oplen
;
2283 const struct arc_flag_special
*arc_flag_special_opcode
;
2284 const struct arc_opcode_hash_entry
*entry
;
2286 /* Search for special case instruction. */
2287 for (i
= 0; i
< arc_num_flag_special
; i
++)
2289 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
2290 oplen
= strlen (arc_flag_special_opcode
->name
);
2292 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
2295 /* Found a potential special case instruction, now test for
2297 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
2299 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
2301 break; /* End of array, nothing found. */
2303 flagnm
= arc_flag_operands
[flag_idx
].name
;
2304 flaglen
= strlen (flagnm
);
2305 if (strcmp (opname
+ oplen
, flagnm
) == 0)
2307 entry
= arc_find_opcode (arc_flag_special_opcode
->name
);
2309 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
2311 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
2312 pflags
[*nflgs
].name
[flaglen
] = '\0';
2321 /* Used to find special case opcode. */
2323 static const struct arc_opcode_hash_entry
*
2324 find_special_case (const char *opname
,
2326 struct arc_flags
*pflags
,
2330 const struct arc_opcode_hash_entry
*entry
;
2332 entry
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
2335 entry
= find_special_case_flag (opname
, nflgs
, pflags
);
2340 /* Autodetect cpu attribute list. */
2343 autodetect_attributes (const struct arc_opcode
*opcode
,
2344 const expressionS
*tok
,
2352 } mpy_list
[] = {{ MPY1E
, 1 }, { MPY6E
, 6 }, { MPY7E
, 7 }, { MPY8E
, 8 },
2355 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
2356 if (opcode
->subclass
== feature_list
[i
].feature
)
2357 selected_cpu
.features
|= feature_list
[i
].feature
;
2359 for (i
= 0; i
< ARRAY_SIZE (mpy_list
); i
++)
2360 if (opcode
->subclass
== mpy_list
[i
].feature
)
2361 mpy_option
= mpy_list
[i
].encoding
;
2363 for (i
= 0; i
< (unsigned) ntok
; i
++)
2365 switch (tok
[i
].X_md
)
2389 /* Given an opcode name, pre-tockenized set of argumenst and the
2390 opcode flags, take it all the way through emission. */
2393 assemble_tokens (const char *opname
,
2396 struct arc_flags
*pflags
,
2399 bfd_boolean found_something
= FALSE
;
2400 const struct arc_opcode_hash_entry
*entry
;
2402 const char *errmsg
= NULL
;
2404 /* Search opcodes. */
2405 entry
= arc_find_opcode (opname
);
2407 /* Couldn't find opcode conventional way, try special cases. */
2409 entry
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
2413 const struct arc_opcode
*opcode
;
2415 pr_debug ("%s:%d: assemble_tokens: %s\n",
2416 frag_now
->fr_file
, frag_now
->fr_line
, opname
);
2417 found_something
= TRUE
;
2418 opcode
= find_opcode_match (entry
, tok
, &ntok
, pflags
,
2419 nflgs
, &cpumatch
, &errmsg
);
2422 struct arc_insn insn
;
2424 autodetect_attributes (opcode
, tok
, ntok
);
2425 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
2431 if (found_something
)
2435 as_bad (_("%s for instruction '%s'"), errmsg
, opname
);
2437 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
2439 as_bad (_("opcode '%s' not supported for target %s"), opname
,
2443 as_bad (_("unknown opcode '%s'"), opname
);
2446 /* The public interface to the instruction assembler. */
2449 md_assemble (char *str
)
2452 expressionS tok
[MAX_INSN_ARGS
];
2455 struct arc_flags flags
[MAX_INSN_FLGS
];
2457 /* Split off the opcode. */
2458 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
2459 opname
= xmemdup0 (str
, opnamelen
);
2461 /* Signalize we are assembling the instructions. */
2462 assembling_insn
= TRUE
;
2464 /* Tokenize the flags. */
2465 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2467 as_bad (_("syntax error"));
2471 /* Scan up to the end of the mnemonic which must end in space or end
2474 for (; *str
!= '\0'; str
++)
2478 /* Tokenize the rest of the line. */
2479 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2481 as_bad (_("syntax error"));
2485 /* Finish it off. */
2486 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2487 assembling_insn
= FALSE
;
2490 /* Callback to insert a register into the hash table. */
2493 declare_register (const char *name
, int number
)
2496 symbolS
*regS
= symbol_create (name
, reg_section
,
2497 number
, &zero_address_frag
);
2499 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
2501 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2505 /* Construct symbols for each of the general registers. */
2508 declare_register_set (void)
2511 for (i
= 0; i
< 64; ++i
)
2515 sprintf (name
, "r%d", i
);
2516 declare_register (name
, i
);
2517 if ((i
& 0x01) == 0)
2519 sprintf (name
, "r%dr%d", i
, i
+1);
2520 declare_register (name
, i
);
2525 /* Construct a symbol for an address type. */
2528 declare_addrtype (const char *name
, int number
)
2531 symbolS
*addrtypeS
= symbol_create (name
, undefined_section
,
2532 number
, &zero_address_frag
);
2534 err
= hash_insert (arc_addrtype_hash
, S_GET_NAME (addrtypeS
),
2535 (void *) addrtypeS
);
2537 as_fatal (_("Inserting \"%s\" into address type table failed: %s"),
2541 /* Port-specific assembler initialization. This function is called
2542 once, at assembler startup time. */
2547 const struct arc_opcode
*opcode
= arc_opcodes
;
2549 if (mach_selection_mode
== MACH_SELECTION_NONE
)
2550 arc_select_cpu (TARGET_WITH_CPU
, MACH_SELECTION_FROM_DEFAULT
);
2552 /* The endianness can be chosen "at the factory". */
2553 target_big_endian
= byte_order
== BIG_ENDIAN
;
2555 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
2556 as_warn (_("could not set architecture and machine"));
2558 /* Set elf header flags. */
2559 bfd_set_private_flags (stdoutput
, selected_cpu
.eflags
);
2561 /* Set up a hash table for the instructions. */
2562 arc_opcode_hash
= hash_new ();
2563 if (arc_opcode_hash
== NULL
)
2564 as_fatal (_("Virtual memory exhausted"));
2566 /* Initialize the hash table with the insns. */
2569 const char *name
= opcode
->name
;
2571 arc_insert_opcode (opcode
);
2573 while (++opcode
&& opcode
->name
2574 && (opcode
->name
== name
2575 || !strcmp (opcode
->name
, name
)))
2577 }while (opcode
->name
);
2579 /* Register declaration. */
2580 arc_reg_hash
= hash_new ();
2581 if (arc_reg_hash
== NULL
)
2582 as_fatal (_("Virtual memory exhausted"));
2584 declare_register_set ();
2585 declare_register ("gp", 26);
2586 declare_register ("fp", 27);
2587 declare_register ("sp", 28);
2588 declare_register ("ilink", 29);
2589 declare_register ("ilink1", 29);
2590 declare_register ("ilink2", 30);
2591 declare_register ("blink", 31);
2593 /* XY memory registers. */
2594 declare_register ("x0_u0", 32);
2595 declare_register ("x0_u1", 33);
2596 declare_register ("x1_u0", 34);
2597 declare_register ("x1_u1", 35);
2598 declare_register ("x2_u0", 36);
2599 declare_register ("x2_u1", 37);
2600 declare_register ("x3_u0", 38);
2601 declare_register ("x3_u1", 39);
2602 declare_register ("y0_u0", 40);
2603 declare_register ("y0_u1", 41);
2604 declare_register ("y1_u0", 42);
2605 declare_register ("y1_u1", 43);
2606 declare_register ("y2_u0", 44);
2607 declare_register ("y2_u1", 45);
2608 declare_register ("y3_u0", 46);
2609 declare_register ("y3_u1", 47);
2610 declare_register ("x0_nu", 48);
2611 declare_register ("x1_nu", 49);
2612 declare_register ("x2_nu", 50);
2613 declare_register ("x3_nu", 51);
2614 declare_register ("y0_nu", 52);
2615 declare_register ("y1_nu", 53);
2616 declare_register ("y2_nu", 54);
2617 declare_register ("y3_nu", 55);
2619 declare_register ("mlo", 57);
2620 declare_register ("mmid", 58);
2621 declare_register ("mhi", 59);
2623 declare_register ("acc1", 56);
2624 declare_register ("acc2", 57);
2626 declare_register ("lp_count", 60);
2627 declare_register ("pcl", 63);
2629 /* Initialize the last instructions. */
2630 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2632 /* Aux register declaration. */
2633 arc_aux_hash
= hash_new ();
2634 if (arc_aux_hash
== NULL
)
2635 as_fatal (_("Virtual memory exhausted"));
2637 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
2639 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
2643 if (!(auxr
->cpu
& selected_cpu
.flags
))
2646 if ((auxr
->subclass
!= NONE
)
2647 && !check_cpu_feature (auxr
->subclass
))
2650 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
2652 as_fatal (_("internal error: can't hash aux register '%s': %s"),
2653 auxr
->name
, retval
);
2656 /* Address type declaration. */
2657 arc_addrtype_hash
= hash_new ();
2658 if (arc_addrtype_hash
== NULL
)
2659 as_fatal (_("Virtual memory exhausted"));
2661 declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD
);
2662 declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID
);
2663 declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD
);
2664 declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD
);
2665 declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD
);
2666 declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM
);
2667 declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA
);
2668 declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD
);
2669 declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD
);
2670 declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD
);
2671 declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID
);
2672 declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD
);
2673 declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM
);
2674 declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD
);
2675 declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA
);
2676 declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD
);
2679 /* Write a value out to the object file, using the appropriate
2683 md_number_to_chars (char *buf
,
2687 if (target_big_endian
)
2688 number_to_chars_bigendian (buf
, val
, n
);
2690 number_to_chars_littleendian (buf
, val
, n
);
2693 /* Round up a section size to the appropriate boundary. */
2696 md_section_align (segT segment
,
2699 int align
= bfd_get_section_alignment (stdoutput
, segment
);
2701 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2704 /* The location from which a PC relative jump should be calculated,
2705 given a PC relative reloc. */
2708 md_pcrel_from_section (fixS
*fixP
,
2711 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2713 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2715 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2716 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2717 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2719 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2721 /* The symbol is undefined (or is defined but not in this section).
2722 Let the linker figure it out. */
2726 if ((int) fixP
->fx_r_type
< 0)
2728 /* These are the "internal" relocations. Align them to
2729 32 bit boundary (PCL), for the moment. */
2734 switch (fixP
->fx_r_type
)
2736 case BFD_RELOC_ARC_PC32
:
2737 /* The hardware calculates relative to the start of the
2738 insn, but this relocation is relative to location of the
2739 LIMM, compensate. The base always needs to be
2740 subtracted by 4 as we do not support this type of PCrel
2741 relocation for short instructions. */
2744 case BFD_RELOC_ARC_PLT32
:
2745 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2746 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2747 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2748 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2750 case BFD_RELOC_ARC_S21H_PCREL
:
2751 case BFD_RELOC_ARC_S25H_PCREL
:
2752 case BFD_RELOC_ARC_S13_PCREL
:
2753 case BFD_RELOC_ARC_S21W_PCREL
:
2754 case BFD_RELOC_ARC_S25W_PCREL
:
2758 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2759 _("unhandled reloc %s in md_pcrel_from_section"),
2760 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2765 pr_debug ("pcrel from %"BFD_VMA_FMT
"x + %lx = %"BFD_VMA_FMT
"x, "
2766 "symbol: %s (%"BFD_VMA_FMT
"x)\n",
2767 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
2768 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2769 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
2774 /* Given a BFD relocation find the corresponding operand. */
2776 static const struct arc_operand
*
2777 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2781 for (i
= 0; i
< arc_num_operands
; i
++)
2782 if (arc_operands
[i
].default_reloc
== reloc
)
2783 return &arc_operands
[i
];
2787 /* Insert an operand value into an instruction. */
2789 static unsigned long long
2790 insert_operand (unsigned long long insn
,
2791 const struct arc_operand
*operand
,
2796 offsetT min
= 0, max
= 0;
2798 if (operand
->bits
!= 32
2799 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2800 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2802 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2804 max
= (1 << (operand
->bits
- 1)) - 1;
2805 min
= -(1 << (operand
->bits
- 1));
2809 max
= (1 << operand
->bits
) - 1;
2813 if (val
< min
|| val
> max
)
2814 as_bad_value_out_of_range (_("operand"),
2815 val
, min
, max
, file
, line
);
2818 pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
2819 min
, val
, max
, insn
);
2821 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2823 as_bad_where (file
, line
,
2824 _("Unaligned operand. Needs to be 32bit aligned"));
2826 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2828 as_bad_where (file
, line
,
2829 _("Unaligned operand. Needs to be 16bit aligned"));
2831 if (operand
->insert
)
2833 const char *errmsg
= NULL
;
2835 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2837 as_warn_where (file
, line
, "%s", errmsg
);
2841 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2843 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2845 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2848 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2853 /* Apply a fixup to the object code. At this point all symbol values
2854 should be fully resolved, and we attempt to completely resolve the
2855 reloc. If we can not do that, we determine the correct reloc code
2856 and put it back in the fixup. To indicate that a fixup has been
2857 eliminated, set fixP->fx_done. */
2860 md_apply_fix (fixS
*fixP
,
2864 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2865 valueT value
= *valP
;
2867 symbolS
*fx_addsy
, *fx_subsy
;
2869 segT add_symbol_segment
= absolute_section
;
2870 segT sub_symbol_segment
= absolute_section
;
2871 const struct arc_operand
*operand
= NULL
;
2872 extended_bfd_reloc_code_real_type reloc
;
2874 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2875 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2876 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2877 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2880 fx_addsy
= fixP
->fx_addsy
;
2881 fx_subsy
= fixP
->fx_subsy
;
2886 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2890 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2891 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2892 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2894 resolve_symbol_value (fx_subsy
);
2895 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2897 if (sub_symbol_segment
== absolute_section
)
2899 /* The symbol is really a constant. */
2900 fx_offset
-= S_GET_VALUE (fx_subsy
);
2905 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2906 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2907 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
2908 segment_name (add_symbol_segment
),
2909 S_GET_NAME (fx_subsy
),
2910 segment_name (sub_symbol_segment
));
2916 && !S_IS_WEAK (fx_addsy
))
2918 if (add_symbol_segment
== seg
2921 value
+= S_GET_VALUE (fx_addsy
);
2922 value
-= md_pcrel_from_section (fixP
, seg
);
2924 fixP
->fx_pcrel
= FALSE
;
2926 else if (add_symbol_segment
== absolute_section
)
2928 value
= fixP
->fx_offset
;
2929 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2931 fixP
->fx_pcrel
= FALSE
;
2936 fixP
->fx_done
= TRUE
;
2941 && ((S_IS_DEFINED (fx_addsy
)
2942 && S_GET_SEGMENT (fx_addsy
) != seg
)
2943 || S_IS_WEAK (fx_addsy
)))
2944 value
+= md_pcrel_from_section (fixP
, seg
);
2946 switch (fixP
->fx_r_type
)
2948 case BFD_RELOC_ARC_32_ME
:
2949 /* This is a pc-relative value in a LIMM. Adjust it to the
2950 address of the instruction not to the address of the
2951 LIMM. Note: it is not any longer valid this affirmation as
2952 the linker consider ARC_PC32 a fixup to entire 64 bit
2954 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
2957 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
2959 case BFD_RELOC_ARC_PC32
:
2960 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2963 if ((int) fixP
->fx_r_type
< 0)
2964 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2965 _("PC relative relocation not allowed for (internal)"
2972 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2973 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2974 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2975 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2979 /* Now check for TLS relocations. */
2980 reloc
= fixP
->fx_r_type
;
2983 case BFD_RELOC_ARC_TLS_DTPOFF
:
2984 case BFD_RELOC_ARC_TLS_LE_32
:
2988 case BFD_RELOC_ARC_TLS_GD_GOT
:
2989 case BFD_RELOC_ARC_TLS_IE_GOT
:
2990 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2993 case BFD_RELOC_ARC_TLS_GD_LD
:
2994 gas_assert (!fixP
->fx_offset
);
2997 = (S_GET_VALUE (fixP
->fx_subsy
)
2998 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
2999 fixP
->fx_subsy
= NULL
;
3001 case BFD_RELOC_ARC_TLS_GD_CALL
:
3002 /* These two relocs are there just to allow ld to change the tls
3003 model for this symbol, by patching the code. The offset -
3004 and scale, if any - will be installed by the linker. */
3005 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
3008 case BFD_RELOC_ARC_TLS_LE_S9
:
3009 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
3010 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3022 /* Adjust the value if we have a constant. */
3025 /* For hosts with longs bigger than 32-bits make sure that the top
3026 bits of a 32-bit negative value read in by the parser are set,
3027 so that the correct comparisons are made. */
3028 if (value
& 0x80000000)
3029 value
|= (-1UL << 31);
3031 reloc
= fixP
->fx_r_type
;
3039 case BFD_RELOC_ARC_32_PCREL
:
3040 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
3043 case BFD_RELOC_ARC_GOTPC32
:
3044 /* I cannot fix an GOTPC relocation because I need to relax it
3045 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
3046 as_bad (_("Unsupported operation on reloc"));
3049 case BFD_RELOC_ARC_TLS_DTPOFF
:
3050 case BFD_RELOC_ARC_TLS_LE_32
:
3051 gas_assert (!fixP
->fx_addsy
);
3052 gas_assert (!fixP
->fx_subsy
);
3055 case BFD_RELOC_ARC_GOTOFF
:
3056 case BFD_RELOC_ARC_32_ME
:
3057 case BFD_RELOC_ARC_PC32
:
3058 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
3061 case BFD_RELOC_ARC_PLT32
:
3062 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
3065 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
3066 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
3069 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
3070 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
3073 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
3074 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
3077 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
3078 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
3081 case BFD_RELOC_ARC_S25W_PCREL
:
3082 case BFD_RELOC_ARC_S21W_PCREL
:
3083 case BFD_RELOC_ARC_S21H_PCREL
:
3084 case BFD_RELOC_ARC_S25H_PCREL
:
3085 case BFD_RELOC_ARC_S13_PCREL
:
3087 operand
= find_operand_for_reloc (reloc
);
3088 gas_assert (operand
);
3093 if ((int) fixP
->fx_r_type
>= 0)
3094 as_fatal (_("unhandled relocation type %s"),
3095 bfd_get_reloc_code_name (fixP
->fx_r_type
));
3097 /* The rest of these fixups needs to be completely resolved as
3099 if (fixP
->fx_addsy
!= 0
3100 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
3101 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3102 _("non-absolute expression in constant field"));
3104 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
3105 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
3110 if (target_big_endian
)
3112 switch (fixP
->fx_size
)
3115 insn
= bfd_getb32 (fixpos
);
3118 insn
= bfd_getb16 (fixpos
);
3121 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3122 _("unknown fixup size"));
3128 switch (fixP
->fx_size
)
3131 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
3134 insn
= bfd_getl16 (fixpos
);
3137 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3138 _("unknown fixup size"));
3142 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
3143 fixP
->fx_file
, fixP
->fx_line
);
3145 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
3148 /* Prepare machine-dependent frags for relaxation.
3150 Called just before relaxation starts. Any symbol that is now undefined
3151 will not become defined.
3153 Return the correct fr_subtype in the frag.
3155 Return the initial "guess for fr_var" to caller. The guess for fr_var
3156 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3157 or fr_var contributes to our returned value.
3159 Although it may not be explicit in the frag, pretend
3160 fr_var starts with a value. */
3163 md_estimate_size_before_relax (fragS
*fragP
,
3168 /* If the symbol is not located within the same section AND it's not
3169 an absolute section, use the maximum. OR if the symbol is a
3170 constant AND the insn is by nature not pc-rel, use the maximum.
3171 OR if the symbol is being equated against another symbol, use the
3172 maximum. OR if the symbol is weak use the maximum. */
3173 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
3174 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
3175 || (symbol_constant_p (fragP
->fr_symbol
)
3176 && !fragP
->tc_frag_data
.pcrel
)
3177 || symbol_equated_p (fragP
->fr_symbol
)
3178 || S_IS_WEAK (fragP
->fr_symbol
))
3180 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
3181 ++fragP
->fr_subtype
;
3184 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3185 fragP
->fr_var
= growth
;
3187 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3188 fragP
->fr_file
, fragP
->fr_line
, growth
);
3193 /* Translate internal representation of relocation info to BFD target
3197 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
3201 bfd_reloc_code_real_type code
;
3203 reloc
= XNEW (arelent
);
3204 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3205 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3206 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3208 /* Make sure none of our internal relocations make it this far.
3209 They'd better have been fully resolved by this point. */
3210 gas_assert ((int) fixP
->fx_r_type
> 0);
3212 code
= fixP
->fx_r_type
;
3214 /* if we have something like add gp, pcl,
3215 _GLOBAL_OFFSET_TABLE_@gotpc. */
3216 if (code
== BFD_RELOC_ARC_GOTPC32
3218 && fixP
->fx_addsy
== GOT_symbol
)
3219 code
= BFD_RELOC_ARC_GOTPC
;
3221 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
3222 if (reloc
->howto
== NULL
)
3224 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3225 _("cannot represent `%s' relocation in object file"),
3226 bfd_get_reloc_code_name (code
));
3230 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
3231 as_fatal (_("internal error? cannot generate `%s' relocation"),
3232 bfd_get_reloc_code_name (code
));
3234 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
3236 reloc
->addend
= fixP
->fx_offset
;
3241 /* Perform post-processing of machine-dependent frags after relaxation.
3242 Called after relaxation is finished.
3243 In: Address of frag.
3244 fr_type == rs_machine_dependent.
3245 fr_subtype is what the address relaxed to.
3247 Out: Any fixS:s and constants are set up. */
3250 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
3251 segT segment ATTRIBUTE_UNUSED
,
3254 const relax_typeS
*table_entry
;
3256 const struct arc_opcode
*opcode
;
3257 struct arc_insn insn
;
3259 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
3261 fix
= (fragP
->fr_fix
< 0 ? 0 : fragP
->fr_fix
);
3262 dest
= fragP
->fr_literal
+ fix
;
3263 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
3265 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3266 "var: %"BFD_VMA_FMT
"d\n",
3267 fragP
->fr_file
, fragP
->fr_line
,
3268 fragP
->fr_subtype
, fix
, fragP
->fr_var
);
3270 if (fragP
->fr_subtype
<= 0
3271 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
3272 as_fatal (_("no relaxation found for this instruction."));
3274 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
3276 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
3277 relax_arg
->nflg
, &insn
);
3279 apply_fixups (&insn
, fragP
, fix
);
3281 size
= insn
.len
+ (insn
.has_limm
? 4 : 0);
3282 gas_assert (table_entry
->rlx_length
== size
);
3283 emit_insn0 (&insn
, dest
, TRUE
);
3285 fragP
->fr_fix
+= table_entry
->rlx_length
;
3289 /* We have no need to default values of symbols. We could catch
3290 register names here, but that is handled by inserting them all in
3291 the symbol table to begin with. */
3294 md_undefined_symbol (char *name
)
3296 /* The arc abi demands that a GOT[0] should be referencible as
3297 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3298 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3300 && (*(name
+1) == 'G')
3301 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0)))
3305 if (symbol_find (name
))
3306 as_bad ("GOT already in symbol table");
3308 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
3309 (valueT
) 0, &zero_address_frag
);
3316 /* Turn a string in input_line_pointer into a floating point constant
3317 of type type, and store the appropriate bytes in *litP. The number
3318 of LITTLENUMS emitted is stored in *sizeP. An error message is
3319 returned, or NULL on OK. */
3322 md_atof (int type
, char *litP
, int *sizeP
)
3324 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
3327 /* Called for any expression that can not be recognized. When the
3328 function is called, `input_line_pointer' will point to the start of
3332 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
3334 char *p
= input_line_pointer
;
3337 input_line_pointer
++;
3338 expressionP
->X_op
= O_symbol
;
3339 expression (expressionP
);
3343 /* This function is called from the function 'expression', it attempts
3344 to parse special names (in our case register names). It fills in
3345 the expression with the identified register. It returns TRUE if
3346 it is a register and FALSE otherwise. */
3349 arc_parse_name (const char *name
,
3350 struct expressionS
*e
)
3354 if (!assembling_insn
)
3357 if (e
->X_op
== O_symbol
)
3360 sym
= hash_find (arc_reg_hash
, name
);
3363 e
->X_op
= O_register
;
3364 e
->X_add_number
= S_GET_VALUE (sym
);
3368 sym
= hash_find (arc_addrtype_hash
, name
);
3371 e
->X_op
= O_addrtype
;
3372 e
->X_add_number
= S_GET_VALUE (sym
);
3380 Invocation line includes a switch not recognized by the base assembler.
3381 See if it's a processor-specific option.
3383 New options (supported) are:
3385 -mcpu=<cpu name> Assemble for selected processor
3386 -EB/-mbig-endian Big-endian
3387 -EL/-mlittle-endian Little-endian
3388 -mrelax Enable relaxation
3390 The following CPU names are recognized:
3391 arc600, arc700, arcem, archs, nps400. */
3394 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
3400 return md_parse_option (OPTION_MCPU
, "arc600");
3403 return md_parse_option (OPTION_MCPU
, "arc700");
3406 return md_parse_option (OPTION_MCPU
, "arcem");
3409 return md_parse_option (OPTION_MCPU
, "archs");
3413 arc_select_cpu (arg
, MACH_SELECTION_FROM_COMMAND_LINE
);
3418 arc_target_format
= "elf32-bigarc";
3419 byte_order
= BIG_ENDIAN
;
3423 arc_target_format
= "elf32-littlearc";
3424 byte_order
= LITTLE_ENDIAN
;
3428 selected_cpu
.features
|= CD
;
3430 arc_check_feature ();
3434 relaxation_state
= 1;
3438 selected_cpu
.features
|= NPS400
;
3439 cl_features
|= NPS400
;
3440 arc_check_feature ();
3444 selected_cpu
.features
|= SPX
;
3446 arc_check_feature ();
3450 selected_cpu
.features
|= DPX
;
3452 arc_check_feature ();
3456 selected_cpu
.features
|= DPA
;
3458 arc_check_feature ();
3461 /* Dummy options are accepted but have no effect. */
3462 case OPTION_USER_MODE
:
3463 case OPTION_LD_EXT_MASK
:
3466 case OPTION_BARREL_SHIFT
:
3467 case OPTION_MIN_MAX
:
3472 case OPTION_XMAC_D16
:
3473 case OPTION_XMAC_24
:
3474 case OPTION_DSP_PACKA
:
3477 case OPTION_TELEPHONY
:
3478 case OPTION_XYMEMORY
:
3491 /* Display the list of cpu names for use in the help text. */
3494 arc_show_cpu_list (FILE *stream
)
3497 static const char *space_buf
= " ";
3499 fprintf (stream
, "%s", space_buf
);
3500 offset
= strlen (space_buf
);
3501 for (i
= 0; cpu_types
[i
].name
!= NULL
; ++i
)
3503 bfd_boolean last
= (cpu_types
[i
+ 1].name
== NULL
);
3505 /* If displaying the new cpu name string, and the ', ' (for all
3506 but the last one) will take us past a target width of 80
3507 characters, then it's time for a new line. */
3508 if (offset
+ strlen (cpu_types
[i
].name
) + (last
? 0 : 2) > 80)
3510 fprintf (stream
, "\n%s", space_buf
);
3511 offset
= strlen (space_buf
);
3514 fprintf (stream
, "%s%s", cpu_types
[i
].name
, (last
? "\n" : ", "));
3515 offset
+= strlen (cpu_types
[i
].name
) + (last
? 0 : 2);
3520 md_show_usage (FILE *stream
)
3522 fprintf (stream
, _("ARC-specific assembler options:\n"));
3524 fprintf (stream
, " -mcpu=<cpu name>\t (default: %s), assemble for"
3525 " CPU <cpu name>, one of:\n", TARGET_WITH_CPU
);
3526 arc_show_cpu_list (stream
);
3527 fprintf (stream
, "\n");
3528 fprintf (stream
, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3529 fprintf (stream
, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3530 fprintf (stream
, " -mEM\t\t\t same as -mcpu=arcem\n");
3531 fprintf (stream
, " -mHS\t\t\t same as -mcpu=archs\n");
3533 fprintf (stream
, " -mnps400\t\t enable NPS-400 extended instructions\n");
3534 fprintf (stream
, " -mspfp\t\t enable single-precision floating point"
3536 fprintf (stream
, " -mdpfp\t\t enable double-precision floating point"
3538 fprintf (stream
, " -mfpuda\t\t enable double-precision assist floating "
3539 "point\n\t\t\t instructions for ARC EM\n");
3542 " -mcode-density\t enable code density option for ARC EM\n");
3544 fprintf (stream
, _("\
3545 -EB assemble code for a big-endian cpu\n"));
3546 fprintf (stream
, _("\
3547 -EL assemble code for a little-endian cpu\n"));
3548 fprintf (stream
, _("\
3549 -mrelax enable relaxation\n"));
3551 fprintf (stream
, _("The following ARC-specific assembler options are "
3552 "deprecated and are accepted\nfor compatibility only:\n"));
3554 fprintf (stream
, _(" -mEA\n"
3555 " -mbarrel-shifter\n"
3556 " -mbarrel_shifter\n"
3561 " -mld-extension-reg-mask\n"
3577 " -muser-mode-only\n"
3581 /* Find the proper relocation for the given opcode. */
3583 static extended_bfd_reloc_code_real_type
3584 find_reloc (const char *name
,
3585 const char *opcodename
,
3586 const struct arc_flags
*pflags
,
3588 extended_bfd_reloc_code_real_type reloc
)
3592 bfd_boolean found_flag
, tmp
;
3593 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
3595 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
3597 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3599 /* Find the entry. */
3600 if (strcmp (name
, r
->name
))
3602 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3609 unsigned * psflg
= (unsigned *)r
->flags
;
3613 for (j
= 0; j
< nflg
; j
++)
3614 if (!strcmp (pflags
[j
].name
,
3615 arc_flag_operands
[*psflg
].name
))
3636 if (reloc
!= r
->oldreloc
)
3643 if (ret
== BFD_RELOC_UNUSED
)
3644 as_bad (_("Unable to find %s relocation for instruction %s"),
3649 /* All the symbol types that are allowed to be used for
3653 may_relax_expr (expressionS tok
)
3655 /* Check if we have unrelaxable relocs. */
3680 /* Checks if flags are in line with relaxable insn. */
3683 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3684 const struct arc_flags
*pflags
,
3687 unsigned flag_class
,
3692 const struct arc_flag_operand
*flag_opand
;
3693 int i
, counttrue
= 0;
3695 /* Iterate through flags classes. */
3696 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3698 /* Iterate through flags in flag class. */
3699 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3702 flag_opand
= &arc_flag_operands
[flag
];
3703 /* Iterate through flags in ins to compare. */
3704 for (i
= 0; i
< nflgs
; ++i
)
3706 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3717 /* If counttrue == nflgs, then all flags have been found. */
3718 return (counttrue
== nflgs
? TRUE
: FALSE
);
3721 /* Checks if operands are in line with relaxable insn. */
3724 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3725 const expressionS
*tok
,
3728 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3731 while (*operand
!= EMPTY
)
3733 const expressionS
*epr
= &tok
[i
];
3735 if (i
!= 0 && i
>= ntok
)
3741 if (!(epr
->X_op
== O_multiply
3742 || epr
->X_op
== O_divide
3743 || epr
->X_op
== O_modulus
3744 || epr
->X_op
== O_add
3745 || epr
->X_op
== O_subtract
3746 || epr
->X_op
== O_symbol
))
3752 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3756 if (epr
->X_op
!= O_register
)
3761 if (epr
->X_op
!= O_register
)
3764 switch (epr
->X_add_number
)
3766 case 0: case 1: case 2: case 3:
3767 case 12: case 13: case 14: case 15:
3774 case REGISTER_NO_GP
:
3775 if ((epr
->X_op
!= O_register
)
3776 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3781 if (epr
->X_op
!= O_bracket
)
3786 /* Don't understand, bail out. */
3792 operand
= &ins
->operands
[i
];
3795 return (i
== ntok
? TRUE
: FALSE
);
3798 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3801 relax_insn_p (const struct arc_opcode
*opcode
,
3802 const expressionS
*tok
,
3804 const struct arc_flags
*pflags
,
3808 bfd_boolean rv
= FALSE
;
3810 /* Check the relaxation table. */
3811 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3813 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3815 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3816 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3817 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3818 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3821 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3822 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3823 sizeof (expressionS
) * ntok
);
3824 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3825 sizeof (struct arc_flags
) * nflg
);
3826 frag_now
->tc_frag_data
.nflg
= nflg
;
3827 frag_now
->tc_frag_data
.ntok
= ntok
;
3835 /* Turn an opcode description and a set of arguments into
3836 an instruction and a fixup. */
3839 assemble_insn (const struct arc_opcode
*opcode
,
3840 const expressionS
*tok
,
3842 const struct arc_flags
*pflags
,
3844 struct arc_insn
*insn
)
3846 const expressionS
*reloc_exp
= NULL
;
3847 unsigned long long image
;
3848 const unsigned char *argidx
;
3851 unsigned char pcrel
= 0;
3852 bfd_boolean needGOTSymbol
;
3853 bfd_boolean has_delay_slot
= FALSE
;
3854 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3856 memset (insn
, 0, sizeof (*insn
));
3857 image
= opcode
->opcode
;
3859 pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
3860 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3863 /* Handle operands. */
3864 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3866 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3867 const expressionS
*t
= (const expressionS
*) 0;
3869 if (ARC_OPERAND_IS_FAKE (operand
))
3872 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3874 /* Duplicate operand, already inserted. */
3886 /* Regardless if we have a reloc or not mark the instruction
3887 limm if it is the case. */
3888 if (operand
->flags
& ARC_OPERAND_LIMM
)
3889 insn
->has_limm
= TRUE
;
3894 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3899 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3901 if (operand
->flags
& ARC_OPERAND_LIMM
)
3902 insn
->limm
= t
->X_add_number
;
3908 /* Ignore brackets, colons, and address types. */
3912 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3916 /* Maybe register range. */
3917 if ((t
->X_add_number
== 0)
3918 && contains_register (t
->X_add_symbol
)
3919 && contains_register (t
->X_op_symbol
))
3923 regs
= get_register (t
->X_add_symbol
);
3925 regs
|= get_register (t
->X_op_symbol
);
3926 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3932 /* This operand needs a relocation. */
3933 needGOTSymbol
= FALSE
;
3938 if (opcode
->insn_class
== JUMP
)
3939 as_bad (_("Unable to use @plt relocation for insn %s"),
3941 needGOTSymbol
= TRUE
;
3942 reloc
= find_reloc ("plt", opcode
->name
,
3944 operand
->default_reloc
);
3949 needGOTSymbol
= TRUE
;
3950 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3953 if (operand
->flags
& ARC_OPERAND_LIMM
)
3955 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3956 if (arc_opcode_len (opcode
) == 2
3957 || opcode
->insn_class
== JUMP
)
3958 as_bad (_("Unable to use @pcl relocation for insn %s"),
3963 /* This is a relaxed operand which initially was
3964 limm, choose whatever we have defined in the
3966 reloc
= operand
->default_reloc
;
3970 reloc
= find_reloc ("sda", opcode
->name
,
3972 operand
->default_reloc
);
3976 needGOTSymbol
= TRUE
;
3981 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3984 case O_tpoff9
: /*FIXME! Check for the conditionality of
3986 case O_dtpoff9
: /*FIXME! Check for the conditionality of
3988 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3992 /* Just consider the default relocation. */
3993 reloc
= operand
->default_reloc
;
3997 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
3998 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
4005 /* sanity checks. */
4006 reloc_howto_type
*reloc_howto
4007 = bfd_reloc_type_lookup (stdoutput
,
4008 (bfd_reloc_code_real_type
) reloc
);
4009 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
4010 if (reloc_howto
->rightshift
)
4011 reloc_bitsize
-= reloc_howto
->rightshift
;
4012 if (reloc_bitsize
!= operand
->bits
)
4014 as_bad (_("invalid relocation %s for field"),
4015 bfd_get_reloc_code_name (reloc
));
4020 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
4021 as_fatal (_("too many fixups"));
4023 struct arc_fixup
*fixup
;
4024 fixup
= &insn
->fixups
[insn
->nfixups
++];
4026 fixup
->reloc
= reloc
;
4027 if ((int) reloc
< 0)
4028 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
4031 reloc_howto_type
*reloc_howto
=
4032 bfd_reloc_type_lookup (stdoutput
,
4033 (bfd_reloc_code_real_type
) fixup
->reloc
);
4034 pcrel
= reloc_howto
->pc_relative
;
4036 fixup
->pcrel
= pcrel
;
4037 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
4044 for (i
= 0; i
< nflg
; i
++)
4046 const struct arc_flag_operand
*flg_operand
= pflags
[i
].flgp
;
4048 /* Check if the instruction has a delay slot. */
4049 if (!strcmp (flg_operand
->name
, "d"))
4050 has_delay_slot
= TRUE
;
4052 /* There is an exceptional case when we cannot insert a flag just as
4053 it is. On ARCv2 the '.t' and '.nt' flags must be handled in
4054 relation with the relative address. Unfortunately, some of the
4055 ARC700 extensions (NPS400) also have a '.nt' flag that should be
4056 handled in the normal way.
4058 Flag operands don't have an architecture field, so we can't
4059 directly validate that FLAG_OPERAND is valid for the current
4060 architecture, what we do instead is just validate that we're
4061 assembling for an ARCv2 architecture. */
4062 if ((selected_cpu
.flags
& ARC_OPCODE_ARCV2
)
4063 && (!strcmp (flg_operand
->name
, "t")
4064 || !strcmp (flg_operand
->name
, "nt")))
4066 unsigned bitYoperand
= 0;
4067 /* FIXME! move selection bbit/brcc in arc-opc.c. */
4068 if (!strcmp (flg_operand
->name
, "t"))
4069 if (!strcmp (opcode
->name
, "bbit0")
4070 || !strcmp (opcode
->name
, "bbit1"))
4071 bitYoperand
= arc_NToperand
;
4073 bitYoperand
= arc_Toperand
;
4075 if (!strcmp (opcode
->name
, "bbit0")
4076 || !strcmp (opcode
->name
, "bbit1"))
4077 bitYoperand
= arc_Toperand
;
4079 bitYoperand
= arc_NToperand
;
4081 gas_assert (reloc_exp
!= NULL
);
4082 if (reloc_exp
->X_op
== O_constant
)
4084 /* Check if we have a constant and solved it
4086 offsetT val
= reloc_exp
->X_add_number
;
4087 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
4092 struct arc_fixup
*fixup
;
4094 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
4095 as_fatal (_("too many fixups"));
4097 fixup
= &insn
->fixups
[insn
->nfixups
++];
4098 fixup
->exp
= *reloc_exp
;
4099 fixup
->reloc
= -bitYoperand
;
4100 fixup
->pcrel
= pcrel
;
4101 fixup
->islong
= FALSE
;
4105 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
4106 << flg_operand
->shift
;
4109 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
4111 /* Instruction length. */
4112 insn
->len
= arc_opcode_len (opcode
);
4116 /* Update last insn status. */
4117 arc_last_insns
[1] = arc_last_insns
[0];
4118 arc_last_insns
[0].opcode
= opcode
;
4119 arc_last_insns
[0].has_limm
= insn
->has_limm
;
4120 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
4122 /* Check if the current instruction is legally used. */
4123 if (arc_last_insns
[1].has_delay_slot
4124 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4125 as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."),
4126 arc_last_insns
[1].opcode
->name
,
4127 arc_last_insns
[0].opcode
->name
);
4128 if (arc_last_insns
[1].has_delay_slot
4129 && arc_last_insns
[0].has_limm
)
4130 as_bad (_("Insn %s has an instruction %s with limm in its delay slot."),
4131 arc_last_insns
[1].opcode
->name
,
4132 arc_last_insns
[0].opcode
->name
);
4136 arc_handle_align (fragS
* fragP
)
4138 if ((fragP
)->fr_type
== rs_align_code
)
4140 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
4141 valueT count
= ((fragP
)->fr_next
->fr_address
4142 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
4144 (fragP
)->fr_var
= 2;
4146 if (count
& 1)/* Padding in the gap till the next 2-byte
4147 boundary with 0s. */
4152 /* Writing nop_s. */
4153 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
4157 /* Here we decide which fixups can be adjusted to make them relative
4158 to the beginning of the section instead of the symbol. Basically
4159 we need to make sure that the dynamic relocations are done
4160 correctly, so in some cases we force the original symbol to be
4164 tc_arc_fix_adjustable (fixS
*fixP
)
4167 /* Prevent all adjustments to global symbols. */
4168 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
4170 if (S_IS_WEAK (fixP
->fx_addsy
))
4173 /* Adjust_reloc_syms doesn't know about the GOT. */
4174 switch (fixP
->fx_r_type
)
4176 case BFD_RELOC_ARC_GOTPC32
:
4177 case BFD_RELOC_ARC_PLT32
:
4178 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
4179 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
4180 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
4181 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
4191 /* Compute the reloc type of an expression EXP. */
4194 arc_check_reloc (expressionS
*exp
,
4195 bfd_reloc_code_real_type
*r_type_p
)
4197 if (*r_type_p
== BFD_RELOC_32
4198 && exp
->X_op
== O_subtract
4199 && exp
->X_op_symbol
!= NULL
4200 && exp
->X_op_symbol
->bsym
->section
== now_seg
)
4201 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
4205 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4208 arc_cons_fix_new (fragS
*frag
,
4212 bfd_reloc_code_real_type r_type
)
4214 r_type
= BFD_RELOC_UNUSED
;
4219 r_type
= BFD_RELOC_8
;
4223 r_type
= BFD_RELOC_16
;
4227 r_type
= BFD_RELOC_24
;
4231 r_type
= BFD_RELOC_32
;
4232 arc_check_reloc (exp
, &r_type
);
4236 r_type
= BFD_RELOC_64
;
4240 as_bad (_("unsupported BFD relocation size %u"), size
);
4241 r_type
= BFD_RELOC_UNUSED
;
4244 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
4247 /* The actual routine that checks the ZOL conditions. */
4250 check_zol (symbolS
*s
)
4252 switch (selected_cpu
.mach
)
4254 case bfd_mach_arc_arcv2
:
4255 if (selected_cpu
.flags
& ARC_OPCODE_ARCv2EM
)
4258 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
4259 || arc_last_insns
[1].has_delay_slot
)
4260 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4264 case bfd_mach_arc_arc600
:
4266 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
4267 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4270 if (arc_last_insns
[0].has_limm
4271 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4272 as_bad (_("A jump instruction with long immediate detected at the \
4273 end of the ZOL label @%s"), S_GET_NAME (s
));
4276 case bfd_mach_arc_arc700
:
4277 if (arc_last_insns
[0].has_delay_slot
)
4278 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4287 /* If ZOL end check the last two instruction for illegals. */
4289 arc_frob_label (symbolS
* sym
)
4291 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
4294 dwarf2_emit_label (sym
);
4297 /* Used because generic relaxation assumes a pc-rel value whilst we
4298 also relax instructions that use an absolute value resolved out of
4299 relative values (if that makes any sense). An example: 'add r1,
4300 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4301 but if they're in the same section we can subtract the section
4302 offset relocation which ends up in a resolved value. So if @.L2 is
4303 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4304 .text + 0x40 = 0x10. */
4306 arc_pcrel_adjust (fragS
*fragP
)
4308 pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
4309 fragP
->fr_address
, fragP
->fr_fix
,
4310 fragP
->tc_frag_data
.pcrel
? "Y" : "N");
4312 if (!fragP
->tc_frag_data
.pcrel
)
4313 return fragP
->fr_address
+ fragP
->fr_fix
;
4315 /* Take into account the PCL rounding. */
4316 return (fragP
->fr_address
+ fragP
->fr_fix
) & 0x03;
4319 /* Initialize the DWARF-2 unwind information for this procedure. */
4322 tc_arc_frame_initial_instructions (void)
4324 /* Stack pointer is register 28. */
4325 cfi_add_CFA_def_cfa (28, 0);
4329 tc_arc_regname_to_dw2regnum (char *regname
)
4333 sym
= hash_find (arc_reg_hash
, regname
);
4335 return S_GET_VALUE (sym
);
4340 /* Adjust the symbol table. Delete found AUX register symbols. */
4343 arc_adjust_symtab (void)
4347 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
4349 /* I've created a symbol during parsing process. Now, remove
4350 the symbol as it is found to be an AUX register. */
4351 if (ARC_GET_FLAG (sym
) & ARC_FLAG_AUX
)
4352 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
4355 /* Now do generic ELF adjustments. */
4356 elf_adjust_symtab ();
4360 tokenize_extinsn (extInstruction_t
*einsn
)
4364 unsigned char major_opcode
;
4365 unsigned char sub_opcode
;
4366 unsigned char syntax_class
= 0;
4367 unsigned char syntax_class_modifiers
= 0;
4368 unsigned char suffix_class
= 0;
4373 /* 1st: get instruction name. */
4374 p
= input_line_pointer
;
4375 c
= get_symbol_name (&p
);
4377 insn_name
= xstrdup (p
);
4378 restore_line_pointer (c
);
4380 /* Convert to lower case. */
4381 for (p
= insn_name
; *p
; ++p
)
4384 /* 2nd: get major opcode. */
4385 if (*input_line_pointer
!= ',')
4387 as_bad (_("expected comma after instruction name"));
4388 ignore_rest_of_line ();
4391 input_line_pointer
++;
4392 major_opcode
= get_absolute_expression ();
4394 /* 3rd: get sub-opcode. */
4397 if (*input_line_pointer
!= ',')
4399 as_bad (_("expected comma after major opcode"));
4400 ignore_rest_of_line ();
4403 input_line_pointer
++;
4404 sub_opcode
= get_absolute_expression ();
4406 /* 4th: get suffix class. */
4409 if (*input_line_pointer
!= ',')
4411 as_bad ("expected comma after sub opcode");
4412 ignore_rest_of_line ();
4415 input_line_pointer
++;
4421 for (i
= 0; i
< ARRAY_SIZE (suffixclass
); i
++)
4423 if (!strncmp (suffixclass
[i
].name
, input_line_pointer
,
4424 suffixclass
[i
].len
))
4426 suffix_class
|= suffixclass
[i
].attr_class
;
4427 input_line_pointer
+= suffixclass
[i
].len
;
4432 if (i
== ARRAY_SIZE (suffixclass
))
4434 as_bad ("invalid suffix class");
4435 ignore_rest_of_line ();
4441 if (*input_line_pointer
== '|')
4442 input_line_pointer
++;
4447 /* 5th: get syntax class and syntax class modifiers. */
4448 if (*input_line_pointer
!= ',')
4450 as_bad ("expected comma after suffix class");
4451 ignore_rest_of_line ();
4454 input_line_pointer
++;
4460 for (i
= 0; i
< ARRAY_SIZE (syntaxclassmod
); i
++)
4462 if (!strncmp (syntaxclassmod
[i
].name
,
4464 syntaxclassmod
[i
].len
))
4466 syntax_class_modifiers
|= syntaxclassmod
[i
].attr_class
;
4467 input_line_pointer
+= syntaxclassmod
[i
].len
;
4472 if (i
== ARRAY_SIZE (syntaxclassmod
))
4474 for (i
= 0; i
< ARRAY_SIZE (syntaxclass
); i
++)
4476 if (!strncmp (syntaxclass
[i
].name
,
4478 syntaxclass
[i
].len
))
4480 syntax_class
|= syntaxclass
[i
].attr_class
;
4481 input_line_pointer
+= syntaxclass
[i
].len
;
4486 if (i
== ARRAY_SIZE (syntaxclass
))
4488 as_bad ("missing syntax class");
4489 ignore_rest_of_line ();
4496 if (*input_line_pointer
== '|')
4497 input_line_pointer
++;
4502 demand_empty_rest_of_line ();
4504 einsn
->name
= insn_name
;
4505 einsn
->major
= major_opcode
;
4506 einsn
->minor
= sub_opcode
;
4507 einsn
->syntax
= syntax_class
;
4508 einsn
->modsyn
= syntax_class_modifiers
;
4509 einsn
->suffix
= suffix_class
;
4510 einsn
->flags
= syntax_class
4511 | (syntax_class_modifiers
& ARC_OP1_IMM_IMPLIED
? 0x10 : 0);
4514 /* Generate an extension section. */
4517 arc_set_ext_seg (void)
4519 if (!arcext_section
)
4521 arcext_section
= subseg_new (".arcextmap", 0);
4522 bfd_set_section_flags (stdoutput
, arcext_section
,
4523 SEC_READONLY
| SEC_HAS_CONTENTS
);
4526 subseg_set (arcext_section
, 0);
4530 /* Create an extension instruction description in the arc extension
4531 section of the output file.
4532 The structure for an instruction is like this:
4533 [0]: Length of the record.
4534 [1]: Type of the record.
4538 [4]: Syntax (flags).
4539 [5]+ Name instruction.
4541 The sequence is terminated by an empty entry. */
4544 create_extinst_section (extInstruction_t
*einsn
)
4547 segT old_sec
= now_seg
;
4548 int old_subsec
= now_subseg
;
4550 int name_len
= strlen (einsn
->name
);
4555 *p
= 5 + name_len
+ 1;
4557 *p
= EXT_INSTRUCTION
;
4564 p
= frag_more (name_len
+ 1);
4565 strcpy (p
, einsn
->name
);
4567 subseg_set (old_sec
, old_subsec
);
4570 /* Handler .extinstruction pseudo-op. */
4573 arc_extinsn (int ignore ATTRIBUTE_UNUSED
)
4575 extInstruction_t einsn
;
4576 struct arc_opcode
*arc_ext_opcodes
;
4577 const char *errmsg
= NULL
;
4578 unsigned char moplow
, mophigh
;
4580 memset (&einsn
, 0, sizeof (einsn
));
4581 tokenize_extinsn (&einsn
);
4583 /* Check if the name is already used. */
4584 if (arc_find_opcode (einsn
.name
))
4585 as_warn (_("Pseudocode already used %s"), einsn
.name
);
4587 /* Check the opcode ranges. */
4589 mophigh
= (selected_cpu
.flags
& (ARC_OPCODE_ARCv2EM
4590 | ARC_OPCODE_ARCv2HS
)) ? 0x07 : 0x0a;
4592 if ((einsn
.major
> mophigh
) || (einsn
.major
< moplow
))
4593 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow
, mophigh
);
4595 if ((einsn
.minor
> 0x3f) && (einsn
.major
!= 0x0a)
4596 && (einsn
.major
!= 5) && (einsn
.major
!= 9))
4597 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4599 switch (einsn
.syntax
& ARC_SYNTAX_MASK
)
4601 case ARC_SYNTAX_3OP
:
4602 if (einsn
.modsyn
& ARC_OP1_IMM_IMPLIED
)
4603 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4605 case ARC_SYNTAX_2OP
:
4606 case ARC_SYNTAX_1OP
:
4607 case ARC_SYNTAX_NOP
:
4608 if (einsn
.modsyn
& ARC_OP1_MUST_BE_IMM
)
4609 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4615 arc_ext_opcodes
= arcExtMap_genOpcode (&einsn
, selected_cpu
.flags
, &errmsg
);
4616 if (arc_ext_opcodes
== NULL
)
4619 as_fatal ("%s", errmsg
);
4621 as_fatal (_("Couldn't generate extension instruction opcodes"));
4624 as_warn ("%s", errmsg
);
4626 /* Insert the extension instruction. */
4627 arc_insert_opcode ((const struct arc_opcode
*) arc_ext_opcodes
);
4629 create_extinst_section (&einsn
);
4633 tokenize_extregister (extRegister_t
*ereg
, int opertype
)
4639 int number
, imode
= 0;
4640 bfd_boolean isCore_p
= (opertype
== EXT_CORE_REGISTER
) ? TRUE
: FALSE
;
4641 bfd_boolean isReg_p
= (opertype
== EXT_CORE_REGISTER
4642 || opertype
== EXT_AUX_REGISTER
) ? TRUE
: FALSE
;
4644 /* 1st: get register name. */
4646 p
= input_line_pointer
;
4647 c
= get_symbol_name (&p
);
4650 restore_line_pointer (c
);
4652 /* 2nd: get register number. */
4655 if (*input_line_pointer
!= ',')
4657 as_bad (_("expected comma after name"));
4658 ignore_rest_of_line ();
4662 input_line_pointer
++;
4663 number
= get_absolute_expression ();
4666 && (opertype
!= EXT_AUX_REGISTER
))
4668 as_bad (_("%s second argument cannot be a negative number %d"),
4669 isCore_p
? "extCoreRegister's" : "extCondCode's",
4671 ignore_rest_of_line ();
4678 /* 3rd: get register mode. */
4681 if (*input_line_pointer
!= ',')
4683 as_bad (_("expected comma after register number"));
4684 ignore_rest_of_line ();
4689 input_line_pointer
++;
4690 mode
= input_line_pointer
;
4692 if (!strncmp (mode
, "r|w", 3))
4695 input_line_pointer
+= 3;
4697 else if (!strncmp (mode
, "r", 1))
4699 imode
= ARC_REGISTER_READONLY
;
4700 input_line_pointer
+= 1;
4702 else if (strncmp (mode
, "w", 1))
4704 as_bad (_("invalid mode"));
4705 ignore_rest_of_line ();
4711 imode
= ARC_REGISTER_WRITEONLY
;
4712 input_line_pointer
+= 1;
4718 /* 4th: get core register shortcut. */
4720 if (*input_line_pointer
!= ',')
4722 as_bad (_("expected comma after register mode"));
4723 ignore_rest_of_line ();
4728 input_line_pointer
++;
4730 if (!strncmp (input_line_pointer
, "cannot_shortcut", 15))
4732 imode
|= ARC_REGISTER_NOSHORT_CUT
;
4733 input_line_pointer
+= 15;
4735 else if (strncmp (input_line_pointer
, "can_shortcut", 12))
4737 as_bad (_("shortcut designator invalid"));
4738 ignore_rest_of_line ();
4744 input_line_pointer
+= 12;
4747 demand_empty_rest_of_line ();
4750 ereg
->number
= number
;
4751 ereg
->imode
= imode
;
4755 /* Create an extension register/condition description in the arc
4756 extension section of the output file.
4758 The structure for an instruction is like this:
4759 [0]: Length of the record.
4760 [1]: Type of the record.
4762 For core regs and condition codes:
4766 For auxiliary registers:
4770 The sequence is terminated by an empty entry. */
4773 create_extcore_section (extRegister_t
*ereg
, int opertype
)
4775 segT old_sec
= now_seg
;
4776 int old_subsec
= now_subseg
;
4778 int name_len
= strlen (ereg
->name
);
4785 case EXT_CORE_REGISTER
:
4787 *p
= 3 + name_len
+ 1;
4793 case EXT_AUX_REGISTER
:
4795 *p
= 6 + name_len
+ 1;
4797 *p
= EXT_AUX_REGISTER
;
4799 *p
= (ereg
->number
>> 24) & 0xff;
4801 *p
= (ereg
->number
>> 16) & 0xff;
4803 *p
= (ereg
->number
>> 8) & 0xff;
4805 *p
= (ereg
->number
) & 0xff;
4811 p
= frag_more (name_len
+ 1);
4812 strcpy (p
, ereg
->name
);
4814 subseg_set (old_sec
, old_subsec
);
4817 /* Handler .extCoreRegister pseudo-op. */
4820 arc_extcorereg (int opertype
)
4823 struct arc_aux_reg
*auxr
;
4825 struct arc_flag_operand
*ccode
;
4827 memset (&ereg
, 0, sizeof (ereg
));
4828 if (!tokenize_extregister (&ereg
, opertype
))
4833 case EXT_CORE_REGISTER
:
4834 /* Core register. */
4835 if (ereg
.number
> 60)
4836 as_bad (_("core register %s value (%d) too large"), ereg
.name
,
4838 declare_register (ereg
.name
, ereg
.number
);
4840 case EXT_AUX_REGISTER
:
4841 /* Auxiliary register. */
4842 auxr
= XNEW (struct arc_aux_reg
);
4843 auxr
->name
= ereg
.name
;
4844 auxr
->cpu
= selected_cpu
.flags
;
4845 auxr
->subclass
= NONE
;
4846 auxr
->address
= ereg
.number
;
4847 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
4849 as_fatal (_("internal error: can't hash aux register '%s': %s"),
4850 auxr
->name
, retval
);
4853 /* Condition code. */
4854 if (ereg
.number
> 31)
4855 as_bad (_("condition code %s value (%d) too large"), ereg
.name
,
4857 ext_condcode
.size
++;
4858 ext_condcode
.arc_ext_condcode
=
4859 XRESIZEVEC (struct arc_flag_operand
, ext_condcode
.arc_ext_condcode
,
4860 ext_condcode
.size
+ 1);
4861 if (ext_condcode
.arc_ext_condcode
== NULL
)
4862 as_fatal (_("Virtual memory exhausted"));
4864 ccode
= ext_condcode
.arc_ext_condcode
+ ext_condcode
.size
- 1;
4865 ccode
->name
= ereg
.name
;
4866 ccode
->code
= ereg
.number
;
4869 ccode
->favail
= 0; /* not used. */
4871 memset (ccode
, 0, sizeof (struct arc_flag_operand
));
4874 as_bad (_("Unknown extension"));
4877 create_extcore_section (&ereg
, opertype
);
4880 /* Parse a .arc_attribute directive. */
4883 arc_attribute (int ignored ATTRIBUTE_UNUSED
)
4885 int tag
= obj_elf_vendor_attribute (OBJ_ATTR_PROC
);
4887 if (tag
< NUM_KNOWN_OBJ_ATTRIBUTES
)
4888 attributes_set_explicitly
[tag
] = TRUE
;
4891 /* Set an attribute if it has not already been set by the user. */
4894 arc_set_attribute_int (int tag
, int value
)
4897 || tag
>= NUM_KNOWN_OBJ_ATTRIBUTES
4898 || !attributes_set_explicitly
[tag
])
4899 bfd_elf_add_proc_attr_int (stdoutput
, tag
, value
);
4903 arc_set_attribute_string (int tag
, const char *value
)
4906 || tag
>= NUM_KNOWN_OBJ_ATTRIBUTES
4907 || !attributes_set_explicitly
[tag
])
4908 bfd_elf_add_proc_attr_string (stdoutput
, tag
, value
);
4911 /* Allocate and concatenate two strings. s1 can be NULL but not
4912 s2. s1 pointer is freed at end of this procedure. */
4915 arc_stralloc (char * s1
, const char * s2
)
4921 len
= strlen (s1
) + 1;
4923 /* Only s1 can be null. */
4925 len
+= strlen (s2
) + 1;
4927 p
= (char *) xmalloc (len
);
4929 as_fatal (_("Virtual memory exhausted"));
4944 /* Set the public ARC object attributes. */
4947 arc_set_public_attributes (void)
4953 /* Tag_ARC_CPU_name. */
4954 arc_set_attribute_string (Tag_ARC_CPU_name
, selected_cpu
.name
);
4956 /* Tag_ARC_CPU_base. */
4957 switch (selected_cpu
.eflags
& EF_ARC_MACH_MSK
)
4959 case E_ARC_MACH_ARC600
:
4960 case E_ARC_MACH_ARC601
:
4961 base
= TAG_CPU_ARC6xx
;
4963 case E_ARC_MACH_ARC700
:
4964 base
= TAG_CPU_ARC7xx
;
4966 case EF_ARC_CPU_ARCV2EM
:
4967 base
= TAG_CPU_ARCEM
;
4969 case EF_ARC_CPU_ARCV2HS
:
4970 base
= TAG_CPU_ARCHS
;
4976 if (attributes_set_explicitly
[Tag_ARC_CPU_base
]
4977 && (base
!= bfd_elf_get_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
4979 as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
4980 bfd_elf_add_proc_attr_int (stdoutput
, Tag_ARC_CPU_base
, base
);
4982 /* Tag_ARC_ABI_osver. */
4983 if (attributes_set_explicitly
[Tag_ARC_ABI_osver
])
4985 int val
= bfd_elf_get_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
4988 selected_cpu
.eflags
= ((selected_cpu
.eflags
& ~EF_ARC_OSABI_MSK
)
4989 | (val
& 0x0f << 8));
4993 arc_set_attribute_int (Tag_ARC_ABI_osver
, E_ARC_OSABI_CURRENT
>> 8);
4996 /* Tag_ARC_ISA_config. */
4997 arc_check_feature();
4999 for (i
= 0; i
< ARRAY_SIZE (feature_list
); i
++)
5000 if (selected_cpu
.features
& feature_list
[i
].feature
)
5001 s
= arc_stralloc (s
, feature_list
[i
].attr
);
5004 arc_set_attribute_string (Tag_ARC_ISA_config
, s
);
5006 /* Tag_ARC_ISA_mpy_option. */
5007 arc_set_attribute_int (Tag_ARC_ISA_mpy_option
, mpy_option
);
5009 /* Tag_ARC_ABI_pic. */
5010 arc_set_attribute_int (Tag_ARC_ABI_pic
, pic_option
);
5012 /* Tag_ARC_ABI_sda. */
5013 arc_set_attribute_int (Tag_ARC_ABI_sda
, sda_option
);
5015 /* Tag_ARC_ABI_tls. */
5016 arc_set_attribute_int (Tag_ARC_ABI_tls
, tls_option
);
5018 /* Tag_ARC_ATR_version. */
5019 arc_set_attribute_int (Tag_ARC_ATR_version
, 1);
5022 /* Add the default contents for the .ARC.attributes section. */
5027 arc_set_public_attributes ();
5029 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
5030 as_fatal (_("could not set architecture and machine"));
5032 bfd_set_private_flags (stdoutput
, selected_cpu
.eflags
);
5035 void arc_copy_symbol_attributes (symbolS
*dest
, symbolS
*src
)
5037 ARC_GET_FLAG (dest
) = ARC_GET_FLAG (src
);
5040 int arc_convert_symbolic_attribute (const char *name
)
5049 #define T(tag) {#tag, tag}
5050 T (Tag_ARC_PCS_config
),
5051 T (Tag_ARC_CPU_base
),
5052 T (Tag_ARC_CPU_variation
),
5053 T (Tag_ARC_CPU_name
),
5054 T (Tag_ARC_ABI_rf16
),
5055 T (Tag_ARC_ABI_osver
),
5056 T (Tag_ARC_ABI_sda
),
5057 T (Tag_ARC_ABI_pic
),
5058 T (Tag_ARC_ABI_tls
),
5059 T (Tag_ARC_ABI_enumsize
),
5060 T (Tag_ARC_ABI_exceptions
),
5061 T (Tag_ARC_ABI_double_size
),
5062 T (Tag_ARC_ISA_config
),
5063 T (Tag_ARC_ISA_apex
),
5064 T (Tag_ARC_ISA_mpy_option
),
5065 T (Tag_ARC_ATR_version
)
5073 for (i
= 0; i
< ARRAY_SIZE (attribute_table
); i
++)
5074 if (streq (name
, attribute_table
[i
].name
))
5075 return attribute_table
[i
].tag
;
5081 eval: (c-set-style "gnu")