1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
25 #include "struc-symbol.h"
26 #include "dwarf2dbg.h"
27 #include "dw2gencfi.h"
28 #include "safe-ctype.h"
30 #include "opcode/arc.h"
32 #include "../opcodes/arc-ext.h"
34 /* Defines section. */
36 #define MAX_INSN_FIXUPS 2
37 #define MAX_CONSTR_STR 20
38 #define FRAG_MAX_GROWTH 8
41 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
43 # define pr_debug(fmt, args...)
46 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
47 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
48 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \
49 (SUB_OPCODE (x) == 0x28))
51 /* Equal to MAX_PRECISION in atof-ieee.c. */
52 #define MAX_LITTLENUMS 6
54 /* Enum used to enumerate the relaxable ins operands. */
59 REGISTER_S
, /* Register for short instruction(s). */
60 REGISTER_NO_GP
, /* Is a register but not gp register specifically. */
61 REGISTER_DUP
, /* Duplication of previous operand of type register. */
95 #define regno(x) ((x) & 0x3F)
96 #define is_ir_num(x) (((x) & ~0x3F) == 0)
97 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
98 #define is_spfp_p(op) (((sc) == SPX))
99 #define is_dpfp_p(op) (((sc) == DPX))
100 #define is_fpuda_p(op) (((sc) == DPA))
101 #define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH || (op)->insn_class == JUMP))
102 #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL))
103 #define is_nps400_p(op) (((sc) == NPS400))
105 /* Generic assembler global variables which must be defined by all
108 /* Characters which always start a comment. */
109 const char comment_chars
[] = "#;";
111 /* Characters which start a comment at the beginning of a line. */
112 const char line_comment_chars
[] = "#";
114 /* Characters which may be used to separate multiple commands on a
116 const char line_separator_chars
[] = "`";
118 /* Characters which are used to indicate an exponent in a floating
120 const char EXP_CHARS
[] = "eE";
122 /* Chars that mean this number is a floating point constant
123 As in 0f12.456 or 0d1.2345e12. */
124 const char FLT_CHARS
[] = "rRsSfFdD";
127 extern int target_big_endian
;
128 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
129 static int byte_order
= DEFAULT_BYTE_ORDER
;
131 /* Arc extension section. */
132 static segT arcext_section
;
134 /* By default relaxation is disabled. */
135 static int relaxation_state
= 0;
137 extern int arc_get_mach (char *);
139 /* Forward declarations. */
140 static void arc_lcomm (int);
141 static void arc_option (int);
142 static void arc_extra_reloc (int);
143 static void arc_extinsn (int);
144 static void arc_extcorereg (int);
146 const pseudo_typeS md_pseudo_table
[] =
148 /* Make sure that .word is 32 bits. */
151 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
152 { "lcomm", arc_lcomm
, 0 },
153 { "lcommon", arc_lcomm
, 0 },
154 { "cpu", arc_option
, 0 },
156 { "extinstruction", arc_extinsn
, 0 },
157 { "extcoreregister", arc_extcorereg
, EXT_CORE_REGISTER
},
158 { "extauxregister", arc_extcorereg
, EXT_AUX_REGISTER
},
159 { "extcondcode", arc_extcorereg
, EXT_COND_CODE
},
161 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
162 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
167 const char *md_shortopts
= "";
171 OPTION_EB
= OPTION_MD_BASE
,
185 /* The following options are deprecated and provided here only for
186 compatibility reasons. */
212 struct option md_longopts
[] =
214 { "EB", no_argument
, NULL
, OPTION_EB
},
215 { "EL", no_argument
, NULL
, OPTION_EL
},
216 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
217 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
218 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
219 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
220 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
221 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
222 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
223 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
224 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
225 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
226 { "mnps400", no_argument
, NULL
, OPTION_NPS400
},
228 /* The following options are deprecated and provided here only for
229 compatibility reasons. */
230 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
231 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
232 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
233 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
234 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
235 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
236 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
237 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
238 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
239 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
240 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
241 { "mea", no_argument
, NULL
, OPTION_EA
},
242 { "mEA", no_argument
, NULL
, OPTION_EA
},
243 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
244 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
245 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
246 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
247 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
248 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
249 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
250 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
251 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
252 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
253 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
254 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
255 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
256 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
257 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
258 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
259 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
260 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
261 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
262 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
263 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
264 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
265 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
266 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
267 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
268 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
270 { NULL
, no_argument
, NULL
, 0 }
273 size_t md_longopts_size
= sizeof (md_longopts
);
275 /* Local data and data types. */
277 /* Used since new relocation types are introduced in this
278 file (DUMMY_RELOC_LITUSE_*). */
279 typedef int extended_bfd_reloc_code_real_type
;
285 extended_bfd_reloc_code_real_type reloc
;
287 /* index into arc_operands. */
288 unsigned int opindex
;
290 /* PC-relative, used by internals fixups. */
293 /* TRUE if this fixup is for LIMM operand. */
301 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
303 bfd_boolean short_insn
; /* Boolean value: TRUE if current insn is
305 bfd_boolean has_limm
; /* Boolean value: TRUE if limm field is
307 bfd_boolean relax
; /* Boolean value: TRUE if needs
311 /* Structure to hold any last two instructions. */
312 static struct arc_last_insn
314 /* Saved instruction opcode. */
315 const struct arc_opcode
*opcode
;
317 /* Boolean value: TRUE if current insn is short. */
318 bfd_boolean has_limm
;
320 /* Boolean value: TRUE if current insn has delay slot. */
321 bfd_boolean has_delay_slot
;
324 /* Extension instruction suffix classes. */
332 static const attributes_t suffixclass
[] =
334 { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG
},
335 { "SUFFIX_COND", 11, ARC_SUFFIX_COND
},
336 { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE
}
339 /* Extension instruction syntax classes. */
340 static const attributes_t syntaxclass
[] =
342 { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP
},
343 { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP
},
344 { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP
},
345 { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP
}
348 /* Extension instruction syntax classes modifiers. */
349 static const attributes_t syntaxclassmod
[] =
351 { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED
},
352 { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM
}
355 /* Extension register type. */
363 /* A structure to hold the additional conditional codes. */
366 struct arc_flag_operand
*arc_ext_condcode
;
368 } ext_condcode
= { NULL
, 0 };
370 /* Structure to hold an entry in ARC_OPCODE_HASH. */
371 struct arc_opcode_hash_entry
373 /* The number of pointers in the OPCODE list. */
376 /* Points to a list of opcode pointers. */
377 const struct arc_opcode
**opcode
;
380 /* Structure used for iterating through an arc_opcode_hash_entry. */
381 struct arc_opcode_hash_entry_iterator
383 /* Index into the OPCODE element of the arc_opcode_hash_entry. */
386 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
387 returned by this iterator. */
388 const struct arc_opcode
*opcode
;
391 /* Forward declaration. */
392 static void assemble_insn
393 (const struct arc_opcode
*, const expressionS
*, int,
394 const struct arc_flags
*, int, struct arc_insn
*);
396 /* The cpu for which we are generating code. */
397 static unsigned arc_target
;
398 static const char *arc_target_name
;
399 static unsigned arc_features
;
401 /* The default architecture. */
402 static int arc_mach_type
;
404 /* TRUE if the cpu type has been explicitly specified. */
405 static bfd_boolean mach_type_specified_p
= FALSE
;
407 /* The hash table of instruction opcodes. */
408 static struct hash_control
*arc_opcode_hash
;
410 /* The hash table of register symbols. */
411 static struct hash_control
*arc_reg_hash
;
413 /* The hash table of aux register symbols. */
414 static struct hash_control
*arc_aux_hash
;
416 /* A table of CPU names and opcode sets. */
417 static const struct cpu_type
427 { "arc600", ARC_OPCODE_ARC600
, bfd_mach_arc_arc600
,
428 E_ARC_MACH_ARC600
, 0x00},
429 { "arc700", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
430 E_ARC_MACH_ARC700
, 0x00},
431 { "nps400", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
432 E_ARC_MACH_ARC700
, ARC_NPS400
},
433 { "arcem", ARC_OPCODE_ARCv2EM
, bfd_mach_arc_arcv2
,
434 EF_ARC_CPU_ARCV2EM
, 0x00},
435 { "archs", ARC_OPCODE_ARCv2HS
, bfd_mach_arc_arcv2
,
436 EF_ARC_CPU_ARCV2HS
, ARC_CD
},
440 /* Used by the arc_reloc_op table. Order is important. */
441 #define O_gotoff O_md1 /* @gotoff relocation. */
442 #define O_gotpc O_md2 /* @gotpc relocation. */
443 #define O_plt O_md3 /* @plt relocation. */
444 #define O_sda O_md4 /* @sda relocation. */
445 #define O_pcl O_md5 /* @pcl relocation. */
446 #define O_tlsgd O_md6 /* @tlsgd relocation. */
447 #define O_tlsie O_md7 /* @tlsie relocation. */
448 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
449 #define O_tpoff O_md9 /* @tpoff relocation. */
450 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
451 #define O_dtpoff O_md11 /* @dtpoff relocation. */
452 #define O_last O_dtpoff
454 /* Used to define a bracket as operand in tokens. */
455 #define O_bracket O_md32
457 /* Dummy relocation, to be sorted out. */
458 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
460 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
462 /* A table to map the spelling of a relocation operand into an appropriate
463 bfd_reloc_code_real_type type. The table is assumed to be ordered such
464 that op-O_literal indexes into it. */
465 #define ARC_RELOC_TABLE(op) \
466 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
468 : (int) (op) - (int) O_gotoff) ])
470 #define DEF(NAME, RELOC, REQ) \
471 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
473 static const struct arc_reloc_op_tag
475 /* String to lookup. */
477 /* Size of the string. */
479 /* Which operator to use. */
481 extended_bfd_reloc_code_real_type reloc
;
482 /* Allows complex relocation expression like identifier@reloc +
484 unsigned int complex_expr
: 1;
488 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
489 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
490 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
491 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
492 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
493 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
494 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
495 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
496 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
497 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
498 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 0),
501 static const int arc_num_reloc_op
502 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
504 /* Structure for relaxable instruction that have to be swapped with a
505 smaller alternative instruction. */
506 struct arc_relaxable_ins
508 /* Mnemonic that should be checked. */
509 const char *mnemonic_r
;
511 /* Operands that should be checked.
512 Indexes of operands from operand array. */
513 enum rlx_operand_type operands
[6];
515 /* Flags that should be checked. */
516 unsigned flag_classes
[5];
518 /* Mnemonic (smaller) alternative to be used later for relaxation. */
519 const char *mnemonic_alt
;
521 /* Index of operand that generic relaxation has to check. */
524 /* Base subtype index used. */
525 enum arc_rlx_types subtype
;
528 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
529 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
530 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
534 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
535 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
536 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
541 /* ARC relaxation table. */
542 const relax_typeS md_relax_table
[] =
549 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL
),
550 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
554 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B
),
555 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
560 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6
),
561 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM
),
562 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
564 /* LD_S a, [b, u7] ->
565 LD<zz><.x><.aa><.di> a, [b, s9] ->
566 LD<zz><.x><.aa><.di> a, [b, limm] */
567 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9
),
568 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM
),
569 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE
),
574 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12
),
575 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM
),
576 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
580 SUB<.f> a, b, limm. */
581 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6
),
582 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM
),
583 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
585 /* MPY<.f> a, b, u6 ->
586 MPY<.f> a, b, limm. */
587 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM
),
588 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
590 /* MOV<.f><.cc> b, u6 ->
591 MOV<.f><.cc> b, limm. */
592 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM
),
593 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
595 /* ADD<.f><.cc> b, b, u6 ->
596 ADD<.f><.cc> b, b, limm. */
597 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM
),
598 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
601 /* Order of this table's entries matters! */
602 const struct arc_relaxable_ins arc_relaxable_insns
[] =
604 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
605 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
606 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
607 2, ARC_RLX_ADD_RRU6
},
608 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
610 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
612 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
613 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
614 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
615 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
616 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
617 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
618 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
619 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
621 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
623 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
627 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
629 /* Flags to set in the elf header. */
630 static flagword arc_eflag
= 0x00;
632 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
633 symbolS
* GOT_symbol
= 0;
635 /* Set to TRUE when we assemble instructions. */
636 static bfd_boolean assembling_insn
= FALSE
;
638 /* Functions implementation. */
640 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
641 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
642 are no matching entries in ARC_OPCODE_HASH. */
644 static const struct arc_opcode_hash_entry
*
645 arc_find_opcode (const char *name
)
647 const struct arc_opcode_hash_entry
*entry
;
649 entry
= hash_find (arc_opcode_hash
, name
);
653 /* Initialise the iterator ITER. */
656 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator
*iter
)
662 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
663 calls to this function. Return NULL when all ARC_OPCODE entries have
666 static const struct arc_opcode
*
667 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry
*entry
,
668 struct arc_opcode_hash_entry_iterator
*iter
)
670 if (iter
->opcode
== NULL
&& iter
->index
== 0)
672 gas_assert (entry
->count
> 0);
673 iter
->opcode
= entry
->opcode
[iter
->index
];
675 else if (iter
->opcode
!= NULL
)
677 const char *old_name
= iter
->opcode
->name
;
680 if (iter
->opcode
->name
== NULL
681 || strcmp (old_name
, iter
->opcode
->name
) != 0)
684 if (iter
->index
== entry
->count
)
687 iter
->opcode
= entry
->opcode
[iter
->index
];
694 /* Insert an opcode into opcode hash structure. */
697 arc_insert_opcode (const struct arc_opcode
*opcode
)
699 const char *name
, *retval
;
700 struct arc_opcode_hash_entry
*entry
;
703 entry
= hash_find (arc_opcode_hash
, name
);
706 entry
= XNEW (struct arc_opcode_hash_entry
);
708 entry
->opcode
= NULL
;
710 retval
= hash_insert (arc_opcode_hash
, name
, (void *) entry
);
712 as_fatal (_("internal error: can't hash opcode '%s': %s"),
716 entry
->opcode
= XRESIZEVEC (const struct arc_opcode
*, entry
->opcode
,
719 if (entry
->opcode
== NULL
)
720 as_fatal (_("Virtual memory exhausted"));
722 entry
->opcode
[entry
->count
] = opcode
;
727 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
728 is encoded as 'middle-endian' for a little-endian target. FIXME!
729 this function is used for regular 4 byte instructions as well. */
732 md_number_to_chars_midend (char *buf
, valueT val
, int n
)
736 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
737 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
741 md_number_to_chars (buf
, val
, n
);
745 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
746 the relevant static global variables. */
749 arc_select_cpu (const char *arg
)
754 for (i
= 0; cpu_types
[i
].name
; ++i
)
756 if (!strcasecmp (cpu_types
[i
].name
, arg
))
758 arc_target
= cpu_types
[i
].flags
;
759 arc_target_name
= cpu_types
[i
].name
;
760 arc_features
= cpu_types
[i
].features
;
761 arc_mach_type
= cpu_types
[i
].mach
;
762 cpu_flags
= cpu_types
[i
].eflags
;
767 if (!cpu_types
[i
].name
)
768 as_fatal (_("unknown architecture: %s\n"), arg
);
769 gas_assert (cpu_flags
!= 0);
770 arc_eflag
= (arc_eflag
& ~EF_ARC_MACH_MSK
) | cpu_flags
;
773 /* Here ends all the ARCompact extension instruction assembling
777 arc_extra_reloc (int r_type
)
780 symbolS
*sym
, *lab
= NULL
;
782 if (*input_line_pointer
== '@')
783 input_line_pointer
++;
784 c
= get_symbol_name (&sym_name
);
785 sym
= symbol_find_or_make (sym_name
);
786 restore_line_pointer (c
);
787 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
789 ++input_line_pointer
;
791 c
= get_symbol_name (&lab_name
);
792 lab
= symbol_find_or_make (lab_name
);
793 restore_line_pointer (c
);
796 /* These relocations exist as a mechanism for the compiler to tell the
797 linker how to patch the code if the tls model is optimised. However,
798 the relocation itself does not require any space within the assembler
799 fragment, and so we pass a size of 0.
801 The lines that generate these relocations look like this:
803 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
805 The '.tls_gd_ld @.tdata' is processed first and generates the
806 additional relocation, while the 'bl __tls_get_addr@plt' is processed
807 second and generates the additional branch.
809 It is possible that the additional relocation generated by the
810 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
811 while the 'bl __tls_get_addr@plt' will be generated as the first thing
812 in the next fragment. This will be fine; both relocations will still
813 appear to be at the same address in the generated object file.
814 However, this only works as the additional relocation is generated
815 with size of 0 bytes. */
817 = fix_new (frag_now
, /* Which frag? */
818 frag_now_fix (), /* Where in that frag? */
819 0, /* size: 1, 2, or 4 usually. */
820 sym
, /* X_add_symbol. */
821 0, /* X_add_number. */
822 FALSE
, /* TRUE if PC-relative relocation. */
823 r_type
/* Relocation type. */);
824 fixP
->fx_subsy
= lab
;
828 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
829 symbolS
*symbolP
, addressT size
)
834 if (*input_line_pointer
== ',')
836 align
= parse_align (1);
838 if (align
== (addressT
) -1)
853 bss_alloc (symbolP
, size
, align
);
854 S_CLEAR_EXTERNAL (symbolP
);
860 arc_lcomm (int ignore
)
862 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
865 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
868 /* Select the cpu we're assembling for. */
871 arc_option (int ignore ATTRIBUTE_UNUSED
)
877 c
= get_symbol_name (&cpu
);
878 mach
= arc_get_mach (cpu
);
883 if (!mach_type_specified_p
)
885 if ((!strcmp ("ARC600", cpu
))
886 || (!strcmp ("ARC601", cpu
))
887 || (!strcmp ("A6", cpu
)))
889 md_parse_option (OPTION_MCPU
, "arc600");
891 else if ((!strcmp ("ARC700", cpu
))
892 || (!strcmp ("A7", cpu
)))
894 md_parse_option (OPTION_MCPU
, "arc700");
896 else if (!strcmp ("EM", cpu
))
898 md_parse_option (OPTION_MCPU
, "arcem");
900 else if (!strcmp ("HS", cpu
))
902 md_parse_option (OPTION_MCPU
, "archs");
904 else if (!strcmp ("NPS400", cpu
))
906 md_parse_option (OPTION_MCPU
, "nps400");
909 as_fatal (_("could not find the architecture"));
911 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, mach
))
912 as_fatal (_("could not set architecture and machine"));
914 /* Set elf header flags. */
915 bfd_set_private_flags (stdoutput
, arc_eflag
);
918 if (arc_mach_type
!= mach
)
919 as_warn (_("Command-line value overrides \".cpu\" directive"));
921 restore_line_pointer (c
);
922 demand_empty_rest_of_line ();
926 restore_line_pointer (c
);
927 as_bad (_("invalid identifier for \".cpu\""));
928 ignore_rest_of_line ();
931 /* Smartly print an expression. */
934 debug_exp (expressionS
*t
)
936 const char *name ATTRIBUTE_UNUSED
;
937 const char *namemd ATTRIBUTE_UNUSED
;
939 pr_debug ("debug_exp: ");
943 default: name
= "unknown"; break;
944 case O_illegal
: name
= "O_illegal"; break;
945 case O_absent
: name
= "O_absent"; break;
946 case O_constant
: name
= "O_constant"; break;
947 case O_symbol
: name
= "O_symbol"; break;
948 case O_symbol_rva
: name
= "O_symbol_rva"; break;
949 case O_register
: name
= "O_register"; break;
950 case O_big
: name
= "O_big"; break;
951 case O_uminus
: name
= "O_uminus"; break;
952 case O_bit_not
: name
= "O_bit_not"; break;
953 case O_logical_not
: name
= "O_logical_not"; break;
954 case O_multiply
: name
= "O_multiply"; break;
955 case O_divide
: name
= "O_divide"; break;
956 case O_modulus
: name
= "O_modulus"; break;
957 case O_left_shift
: name
= "O_left_shift"; break;
958 case O_right_shift
: name
= "O_right_shift"; break;
959 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
960 case O_bit_or_not
: name
= "O_bit_or_not"; break;
961 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
962 case O_bit_and
: name
= "O_bit_and"; break;
963 case O_add
: name
= "O_add"; break;
964 case O_subtract
: name
= "O_subtract"; break;
965 case O_eq
: name
= "O_eq"; break;
966 case O_ne
: name
= "O_ne"; break;
967 case O_lt
: name
= "O_lt"; break;
968 case O_le
: name
= "O_le"; break;
969 case O_ge
: name
= "O_ge"; break;
970 case O_gt
: name
= "O_gt"; break;
971 case O_logical_and
: name
= "O_logical_and"; break;
972 case O_logical_or
: name
= "O_logical_or"; break;
973 case O_index
: name
= "O_index"; break;
974 case O_bracket
: name
= "O_bracket"; break;
979 default: namemd
= "unknown"; break;
980 case O_gotoff
: namemd
= "O_gotoff"; break;
981 case O_gotpc
: namemd
= "O_gotpc"; break;
982 case O_plt
: namemd
= "O_plt"; break;
983 case O_sda
: namemd
= "O_sda"; break;
984 case O_pcl
: namemd
= "O_pcl"; break;
985 case O_tlsgd
: namemd
= "O_tlsgd"; break;
986 case O_tlsie
: namemd
= "O_tlsie"; break;
987 case O_tpoff9
: namemd
= "O_tpoff9"; break;
988 case O_tpoff
: namemd
= "O_tpoff"; break;
989 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
990 case O_dtpoff
: namemd
= "O_dtpoff"; break;
993 pr_debug ("%s (%s, %s, %d, %s)", name
,
994 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
995 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
996 (int) t
->X_add_number
,
997 (t
->X_md
) ? namemd
: "--");
1002 /* Parse the arguments to an opcode. */
1005 tokenize_arguments (char *str
,
1009 char *old_input_line_pointer
;
1010 bfd_boolean saw_comma
= FALSE
;
1011 bfd_boolean saw_arg
= FALSE
;
1016 const struct arc_reloc_op_tag
*r
;
1018 char *reloc_name
, c
;
1020 memset (tok
, 0, sizeof (*tok
) * ntok
);
1022 /* Save and restore input_line_pointer around this function. */
1023 old_input_line_pointer
= input_line_pointer
;
1024 input_line_pointer
= str
;
1026 while (*input_line_pointer
)
1029 switch (*input_line_pointer
)
1035 input_line_pointer
++;
1036 if (saw_comma
|| !saw_arg
)
1043 ++input_line_pointer
;
1045 if (!saw_arg
|| num_args
== ntok
)
1047 tok
->X_op
= O_bracket
;
1054 input_line_pointer
++;
1055 if (brk_lvl
|| num_args
== ntok
)
1058 tok
->X_op
= O_bracket
;
1064 /* We have labels, function names and relocations, all
1065 starting with @ symbol. Sort them out. */
1066 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1070 tok
->X_op
= O_symbol
;
1071 tok
->X_md
= O_absent
;
1073 if (*input_line_pointer
!= '@')
1074 goto normalsymbol
; /* This is not a relocation. */
1078 /* A relocation opernad has the following form
1079 @identifier@relocation_type. The identifier is already
1081 if (tok
->X_op
!= O_symbol
)
1083 as_bad (_("No valid label relocation operand"));
1087 /* Parse @relocation_type. */
1088 input_line_pointer
++;
1089 c
= get_symbol_name (&reloc_name
);
1090 len
= input_line_pointer
- reloc_name
;
1093 as_bad (_("No relocation operand"));
1097 /* Go through known relocation and try to find a match. */
1098 r
= &arc_reloc_op
[0];
1099 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1100 if (len
== r
->length
1101 && memcmp (reloc_name
, r
->name
, len
) == 0)
1105 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
1109 *input_line_pointer
= c
;
1110 SKIP_WHITESPACE_AFTER_NAME ();
1111 /* Extra check for TLS: base. */
1112 if (*input_line_pointer
== '@')
1115 if (tok
->X_op_symbol
!= NULL
1116 || tok
->X_op
!= O_symbol
)
1118 as_bad (_("Unable to parse TLS base: %s"),
1119 input_line_pointer
);
1122 input_line_pointer
++;
1124 c
= get_symbol_name (&sym_name
);
1125 base
= symbol_find_or_make (sym_name
);
1126 tok
->X_op
= O_subtract
;
1127 tok
->X_op_symbol
= base
;
1128 restore_line_pointer (c
);
1129 tmpE
.X_add_number
= 0;
1131 else if ((*input_line_pointer
!= '+')
1132 && (*input_line_pointer
!= '-'))
1134 tmpE
.X_add_number
= 0;
1138 /* Parse the constant of a complex relocation expression
1139 like @identifier@reloc +/- const. */
1140 if (! r
->complex_expr
)
1142 as_bad (_("@%s is not a complex relocation."), r
->name
);
1146 if (tmpE
.X_op
!= O_constant
)
1148 as_bad (_("Bad expression: @%s + %s."),
1149 r
->name
, input_line_pointer
);
1155 tok
->X_add_number
= tmpE
.X_add_number
;
1166 /* Can be a register. */
1167 ++input_line_pointer
;
1171 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1174 tok
->X_op
= O_absent
;
1175 tok
->X_md
= O_absent
;
1178 /* Legacy: There are cases when we have
1179 identifier@relocation_type, if it is the case parse the
1180 relocation type as well. */
1181 if (*input_line_pointer
== '@')
1187 if (tok
->X_op
== O_illegal
1188 || tok
->X_op
== O_absent
1189 || num_args
== ntok
)
1201 if (saw_comma
|| brk_lvl
)
1203 input_line_pointer
= old_input_line_pointer
;
1209 as_bad (_("Brackets in operand field incorrect"));
1211 as_bad (_("extra comma"));
1213 as_bad (_("missing argument"));
1215 as_bad (_("missing comma or colon"));
1216 input_line_pointer
= old_input_line_pointer
;
1220 /* Parse the flags to a structure. */
1223 tokenize_flags (const char *str
,
1224 struct arc_flags flags
[],
1227 char *old_input_line_pointer
;
1228 bfd_boolean saw_flg
= FALSE
;
1229 bfd_boolean saw_dot
= FALSE
;
1233 memset (flags
, 0, sizeof (*flags
) * nflg
);
1235 /* Save and restore input_line_pointer around this function. */
1236 old_input_line_pointer
= input_line_pointer
;
1237 input_line_pointer
= (char *) str
;
1239 while (*input_line_pointer
)
1241 switch (*input_line_pointer
)
1248 input_line_pointer
++;
1256 if (saw_flg
&& !saw_dot
)
1259 if (num_flags
>= nflg
)
1262 flgnamelen
= strspn (input_line_pointer
,
1263 "abcdefghijklmnopqrstuvwxyz0123456789");
1264 if (flgnamelen
> MAX_FLAG_NAME_LENGTH
)
1267 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1269 input_line_pointer
+= flgnamelen
;
1279 input_line_pointer
= old_input_line_pointer
;
1284 as_bad (_("extra dot"));
1286 as_bad (_("unrecognized flag"));
1288 as_bad (_("failed to parse flags"));
1289 input_line_pointer
= old_input_line_pointer
;
1293 /* Apply the fixups in order. */
1296 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1300 for (i
= 0; i
< insn
->nfixups
; i
++)
1302 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1303 int size
, pcrel
, offset
= 0;
1305 /* FIXME! the reloc size is wrong in the BFD file.
1306 When it is fixed please delete me. */
1307 size
= (insn
->short_insn
&& !fixup
->islong
) ? 2 : 4;
1310 offset
= (insn
->short_insn
) ? 2 : 4;
1312 /* Some fixups are only used internally, thus no howto. */
1313 if ((int) fixup
->reloc
== 0)
1314 as_fatal (_("Unhandled reloc type"));
1316 if ((int) fixup
->reloc
< 0)
1318 /* FIXME! the reloc size is wrong in the BFD file.
1319 When it is fixed please enable me.
1320 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1321 pcrel
= fixup
->pcrel
;
1325 reloc_howto_type
*reloc_howto
=
1326 bfd_reloc_type_lookup (stdoutput
,
1327 (bfd_reloc_code_real_type
) fixup
->reloc
);
1328 gas_assert (reloc_howto
);
1330 /* FIXME! the reloc size is wrong in the BFD file.
1331 When it is fixed please enable me.
1332 size = bfd_get_reloc_size (reloc_howto); */
1333 pcrel
= reloc_howto
->pc_relative
;
1336 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1338 fragP
->fr_file
, fragP
->fr_line
,
1339 (fixup
->reloc
< 0) ? "Internal" :
1340 bfd_get_reloc_code_name (fixup
->reloc
),
1343 fix_new_exp (fragP
, fix
+ offset
,
1344 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1346 /* Check for ZOLs, and update symbol info if any. */
1347 if (LP_INSN (insn
->insn
))
1349 gas_assert (fixup
->exp
.X_add_symbol
);
1350 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1355 /* Actually output an instruction with its fixup. */
1358 emit_insn0 (struct arc_insn
*insn
, char *where
, bfd_boolean relax
)
1362 pr_debug ("Emit insn : 0x%x\n", insn
->insn
);
1363 pr_debug ("\tShort : 0x%d\n", insn
->short_insn
);
1364 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1366 /* Write out the instruction. */
1367 if (insn
->short_insn
)
1373 md_number_to_chars (f
, insn
->insn
, 2);
1374 md_number_to_chars_midend (f
+ 2, insn
->limm
, 4);
1375 dwarf2_emit_insn (6);
1381 md_number_to_chars (f
, insn
->insn
, 2);
1382 dwarf2_emit_insn (2);
1391 md_number_to_chars_midend (f
, insn
->insn
, 4);
1392 md_number_to_chars_midend (f
+ 4, insn
->limm
, 4);
1393 dwarf2_emit_insn (8);
1399 md_number_to_chars_midend (f
, insn
->insn
, 4);
1400 dwarf2_emit_insn (4);
1405 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1409 emit_insn1 (struct arc_insn
*insn
)
1411 /* How frag_var's args are currently configured:
1412 - rs_machine_dependent, to dictate it's a relaxation frag.
1413 - FRAG_MAX_GROWTH, maximum size of instruction
1414 - 0, variable size that might grow...unused by generic relaxation.
1415 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1416 - s, opand expression.
1417 - 0, offset but it's unused.
1418 - 0, opcode but it's unused. */
1419 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1420 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1422 if (frag_room () < FRAG_MAX_GROWTH
)
1424 /* Handle differently when frag literal memory is exhausted.
1425 This is used because when there's not enough memory left in
1426 the current frag, a new frag is created and the information
1427 we put into frag_now->tc_frag_data is disregarded. */
1429 struct arc_relax_type relax_info_copy
;
1430 relax_substateT subtype
= frag_now
->fr_subtype
;
1432 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1433 sizeof (struct arc_relax_type
));
1435 frag_wane (frag_now
);
1436 frag_grow (FRAG_MAX_GROWTH
);
1438 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1439 sizeof (struct arc_relax_type
));
1441 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1445 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1446 frag_now
->fr_subtype
, s
, 0, 0);
1450 emit_insn (struct arc_insn
*insn
)
1455 emit_insn0 (insn
, NULL
, FALSE
);
1458 /* Check whether a symbol involves a register. */
1461 contains_register (symbolS
*sym
)
1465 expressionS
*ex
= symbol_get_value_expression (sym
);
1467 return ((O_register
== ex
->X_op
)
1468 && !contains_register (ex
->X_add_symbol
)
1469 && !contains_register (ex
->X_op_symbol
));
1475 /* Returns the register number within a symbol. */
1478 get_register (symbolS
*sym
)
1480 if (!contains_register (sym
))
1483 expressionS
*ex
= symbol_get_value_expression (sym
);
1484 return regno (ex
->X_add_number
);
1487 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1488 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1491 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1498 case BFD_RELOC_ARC_SDA_LDST
:
1499 case BFD_RELOC_ARC_SDA_LDST1
:
1500 case BFD_RELOC_ARC_SDA_LDST2
:
1501 case BFD_RELOC_ARC_SDA16_LD
:
1502 case BFD_RELOC_ARC_SDA16_LD1
:
1503 case BFD_RELOC_ARC_SDA16_LD2
:
1504 case BFD_RELOC_ARC_SDA16_ST2
:
1505 case BFD_RELOC_ARC_SDA32_ME
:
1512 /* Allocates a tok entry. */
1515 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1517 if (ntok
> MAX_INSN_ARGS
- 2)
1518 return 0; /* No space left. */
1521 return 0; /* Incorect args. */
1523 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1526 return 1; /* Success. */
1527 return allocate_tok (tok
, ntok
- 1, cidx
);
1530 /* Check if an particular ARC feature is enabled. */
1533 check_cpu_feature (insn_subclass_t sc
)
1535 if (is_code_density_p (sc
) && !(arc_features
& ARC_CD
))
1538 if (is_spfp_p (sc
) && !(arc_features
& ARC_SPFP
))
1541 if (is_dpfp_p (sc
) && !(arc_features
& ARC_DPFP
))
1544 if (is_fpuda_p (sc
) && !(arc_features
& ARC_FPUDA
))
1547 if (is_nps400_p (sc
) && !(arc_features
& ARC_NPS400
))
1553 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1554 operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG
1555 array and returns TRUE if the flag operands all match, otherwise,
1556 returns FALSE, in which case the FIRST_PFLAG array may have been
1560 parse_opcode_flags (const struct arc_opcode
*opcode
,
1562 struct arc_flags
*first_pflag
)
1565 const unsigned char *flgidx
;
1568 for (i
= 0; i
< nflgs
; i
++)
1569 first_pflag
[i
].flgp
= NULL
;
1571 /* Check the flags. Iterate over the valid flag classes. */
1572 for (flgidx
= opcode
->flags
; *flgidx
; ++flgidx
)
1574 /* Get a valid flag class. */
1575 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1576 const unsigned *flgopridx
;
1578 struct arc_flags
*pflag
= NULL
;
1580 /* Check for extension conditional codes. */
1581 if (ext_condcode
.arc_ext_condcode
1582 && cl_flags
->flag_class
& F_CLASS_EXTEND
)
1584 struct arc_flag_operand
*pf
= ext_condcode
.arc_ext_condcode
;
1587 pflag
= first_pflag
;
1588 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1590 if (!strcmp (pf
->name
, pflag
->name
))
1592 if (pflag
->flgp
!= NULL
)
1605 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1607 const struct arc_flag_operand
*flg_operand
;
1609 pflag
= first_pflag
;
1610 flg_operand
= &arc_flag_operands
[*flgopridx
];
1611 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1613 /* Match against the parsed flags. */
1614 if (!strcmp (flg_operand
->name
, pflag
->name
))
1616 if (pflag
->flgp
!= NULL
)
1619 pflag
->flgp
= flg_operand
;
1621 break; /* goto next flag class and parsed flag. */
1626 if ((cl_flags
->flag_class
& F_CLASS_REQUIRED
) && cl_matches
== 0)
1628 if ((cl_flags
->flag_class
& F_CLASS_OPTIONAL
) && cl_matches
> 1)
1632 /* Did I check all the parsed flags? */
1633 return lnflg
? FALSE
: TRUE
;
1637 /* Search forward through all variants of an opcode looking for a
1640 static const struct arc_opcode
*
1641 find_opcode_match (const struct arc_opcode_hash_entry
*entry
,
1644 struct arc_flags
*first_pflag
,
1648 const struct arc_opcode
*opcode
;
1649 struct arc_opcode_hash_entry_iterator iter
;
1651 int got_cpu_match
= 0;
1652 expressionS bktok
[MAX_INSN_ARGS
];
1656 arc_opcode_hash_entry_iterator_init (&iter
);
1657 memset (&emptyE
, 0, sizeof (emptyE
));
1658 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1661 for (opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
);
1663 opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
))
1665 const unsigned char *opidx
;
1667 const expressionS
*t
= &emptyE
;
1669 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1670 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1672 /* Don't match opcodes that don't exist on this
1674 if (!(opcode
->cpu
& arc_target
))
1677 if (!check_cpu_feature (opcode
->subclass
))
1683 /* Check the operands. */
1684 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1686 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1688 /* Only take input from real operands. */
1689 if ((operand
->flags
& ARC_OPERAND_FAKE
)
1690 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
1693 /* When we expect input, make sure we have it. */
1697 /* Match operand type with expression type. */
1698 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1700 case ARC_OPERAND_IR
:
1701 /* Check to be a register. */
1702 if ((tok
[tokidx
].X_op
!= O_register
1703 || !is_ir_num (tok
[tokidx
].X_add_number
))
1704 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1707 /* If expect duplicate, make sure it is duplicate. */
1708 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1710 /* Check for duplicate. */
1711 if (t
->X_op
!= O_register
1712 || !is_ir_num (t
->X_add_number
)
1713 || (regno (t
->X_add_number
) !=
1714 regno (tok
[tokidx
].X_add_number
)))
1718 /* Special handling? */
1719 if (operand
->insert
)
1721 const char *errmsg
= NULL
;
1722 (*operand
->insert
)(0,
1723 regno (tok
[tokidx
].X_add_number
),
1727 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1729 /* Missing argument, create one. */
1730 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1733 tok
[tokidx
].X_op
= O_absent
;
1744 case ARC_OPERAND_BRAKET
:
1745 /* Check if bracket is also in opcode table as
1747 if (tok
[tokidx
].X_op
!= O_bracket
)
1751 case ARC_OPERAND_LIMM
:
1752 case ARC_OPERAND_SIGNED
:
1753 case ARC_OPERAND_UNSIGNED
:
1754 switch (tok
[tokidx
].X_op
)
1762 /* Got an (too) early bracket, check if it is an
1763 ignored operand. N.B. This procedure works only
1764 when bracket is the last operand! */
1765 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1767 /* Insert the missing operand. */
1768 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1771 tok
[tokidx
].X_op
= O_absent
;
1778 const struct arc_aux_reg
*auxr
;
1780 if (opcode
->insn_class
!= AUXREG
)
1782 p
= S_GET_NAME (tok
[tokidx
].X_add_symbol
);
1784 auxr
= hash_find (arc_aux_hash
, p
);
1787 /* We modify the token array here, safe in the
1788 knowledge, that if this was the wrong
1789 choice then the original contents will be
1790 restored from BKTOK. */
1791 tok
[tokidx
].X_op
= O_constant
;
1792 tok
[tokidx
].X_add_number
= auxr
->address
;
1793 ARC_SET_FLAG (tok
[tokidx
].X_add_symbol
, ARC_FLAG_AUX
);
1796 if (tok
[tokidx
].X_op
!= O_constant
)
1801 /* Check the range. */
1802 if (operand
->bits
!= 32
1803 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1805 offsetT min
, max
, val
;
1806 val
= tok
[tokidx
].X_add_number
;
1808 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1810 max
= (1 << (operand
->bits
- 1)) - 1;
1811 min
= -(1 << (operand
->bits
- 1));
1815 max
= (1 << operand
->bits
) - 1;
1819 if (val
< min
|| val
> max
)
1822 /* Check alignmets. */
1823 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1827 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1831 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1833 if (operand
->insert
)
1835 const char *errmsg
= NULL
;
1836 (*operand
->insert
)(0,
1837 tok
[tokidx
].X_add_number
,
1842 else if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1848 /* Check if it is register range. */
1849 if ((tok
[tokidx
].X_add_number
== 0)
1850 && contains_register (tok
[tokidx
].X_add_symbol
)
1851 && contains_register (tok
[tokidx
].X_op_symbol
))
1855 regs
= get_register (tok
[tokidx
].X_add_symbol
);
1857 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
1858 if (operand
->insert
)
1860 const char *errmsg
= NULL
;
1861 (*operand
->insert
)(0,
1873 if (operand
->default_reloc
== 0)
1874 goto match_failed
; /* The operand needs relocation. */
1876 /* Relocs requiring long immediate. FIXME! make it
1877 generic and move it to a function. */
1878 switch (tok
[tokidx
].X_md
)
1887 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
1890 if (!generic_reloc_p (operand
->default_reloc
))
1897 /* If expect duplicate, make sure it is duplicate. */
1898 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1900 if (t
->X_op
== O_illegal
1901 || t
->X_op
== O_absent
1902 || t
->X_op
== O_register
1903 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
1910 /* Everything else should have been fake. */
1918 /* Setup ready for flag parsing. */
1919 if (!parse_opcode_flags (opcode
, nflgs
, first_pflag
))
1923 /* Possible match -- did we use all of our input? */
1933 /* Restore the original parameters. */
1934 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
1939 *pcpumatch
= got_cpu_match
;
1944 /* Swap operand tokens. */
1947 swap_operand (expressionS
*operand_array
,
1949 unsigned destination
)
1951 expressionS cpy_operand
;
1952 expressionS
*src_operand
;
1953 expressionS
*dst_operand
;
1956 if (source
== destination
)
1959 src_operand
= &operand_array
[source
];
1960 dst_operand
= &operand_array
[destination
];
1961 size
= sizeof (expressionS
);
1963 /* Make copy of operand to swap with and swap. */
1964 memcpy (&cpy_operand
, dst_operand
, size
);
1965 memcpy (dst_operand
, src_operand
, size
);
1966 memcpy (src_operand
, &cpy_operand
, size
);
1969 /* Check if *op matches *tok type.
1970 Returns FALSE if they don't match, TRUE if they match. */
1973 pseudo_operand_match (const expressionS
*tok
,
1974 const struct arc_operand_operation
*op
)
1976 offsetT min
, max
, val
;
1978 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
1984 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
1986 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
1988 val
= tok
->X_add_number
+ op
->count
;
1989 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
1991 max
= (1 << (operand_real
->bits
- 1)) - 1;
1992 min
= -(1 << (operand_real
->bits
- 1));
1996 max
= (1 << operand_real
->bits
) - 1;
1999 if (min
<= val
&& val
<= max
)
2005 /* Handle all symbols as long immediates or signed 9. */
2006 if (operand_real
->flags
& ARC_OPERAND_LIMM
||
2007 ((operand_real
->flags
& ARC_OPERAND_SIGNED
) && operand_real
->bits
== 9))
2012 if (operand_real
->flags
& ARC_OPERAND_IR
)
2017 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2028 /* Find pseudo instruction in array. */
2030 static const struct arc_pseudo_insn
*
2031 find_pseudo_insn (const char *opname
,
2033 const expressionS
*tok
)
2035 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2036 const struct arc_operand_operation
*op
;
2040 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
2042 pseudo_insn
= &arc_pseudo_insns
[i
];
2043 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
2045 op
= pseudo_insn
->operand
;
2046 for (j
= 0; j
< ntok
; ++j
)
2047 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
2050 /* Found the right instruction. */
2058 /* Assumes the expressionS *tok is of sufficient size. */
2060 static const struct arc_opcode_hash_entry
*
2061 find_special_case_pseudo (const char *opname
,
2065 struct arc_flags
*pflags
)
2067 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2068 const struct arc_operand_operation
*operand_pseudo
;
2069 const struct arc_operand
*operand_real
;
2071 char construct_operand
[MAX_CONSTR_STR
];
2073 /* Find whether opname is in pseudo instruction array. */
2074 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
2076 if (pseudo_insn
== NULL
)
2079 /* Handle flag, Limited to one flag at the moment. */
2080 if (pseudo_insn
->flag_r
!= NULL
)
2081 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
2082 MAX_INSN_FLGS
- *nflgs
);
2084 /* Handle operand operations. */
2085 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2087 operand_pseudo
= &pseudo_insn
->operand
[i
];
2088 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
2090 if (operand_real
->flags
& ARC_OPERAND_BRAKET
&&
2091 !operand_pseudo
->needs_insert
)
2094 /* Has to be inserted (i.e. this token does not exist yet). */
2095 if (operand_pseudo
->needs_insert
)
2097 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2099 tok
[i
].X_op
= O_bracket
;
2104 /* Check if operand is a register or constant and handle it
2106 if (operand_real
->flags
& ARC_OPERAND_IR
)
2107 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
2108 operand_pseudo
->count
);
2110 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
2111 operand_pseudo
->count
);
2113 tokenize_arguments (construct_operand
, &tok
[i
], 1);
2117 else if (operand_pseudo
->count
)
2119 /* Operand number has to be adjusted accordingly (by operand
2121 switch (tok
[i
].X_op
)
2124 tok
[i
].X_add_number
+= operand_pseudo
->count
;
2137 /* Swap operands if necessary. Only supports one swap at the
2139 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2141 operand_pseudo
= &pseudo_insn
->operand
[i
];
2143 if (operand_pseudo
->swap_operand_idx
== i
)
2146 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
2148 /* Prevent a swap back later by breaking out. */
2152 return arc_find_opcode (pseudo_insn
->mnemonic_r
);
2155 static const struct arc_opcode_hash_entry
*
2156 find_special_case_flag (const char *opname
,
2158 struct arc_flags
*pflags
)
2162 unsigned flag_idx
, flag_arr_idx
;
2163 size_t flaglen
, oplen
;
2164 const struct arc_flag_special
*arc_flag_special_opcode
;
2165 const struct arc_opcode_hash_entry
*entry
;
2167 /* Search for special case instruction. */
2168 for (i
= 0; i
< arc_num_flag_special
; i
++)
2170 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
2171 oplen
= strlen (arc_flag_special_opcode
->name
);
2173 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
2176 /* Found a potential special case instruction, now test for
2178 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
2180 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
2182 break; /* End of array, nothing found. */
2184 flagnm
= arc_flag_operands
[flag_idx
].name
;
2185 flaglen
= strlen (flagnm
);
2186 if (strcmp (opname
+ oplen
, flagnm
) == 0)
2188 entry
= arc_find_opcode (arc_flag_special_opcode
->name
);
2190 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
2192 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
2193 pflags
[*nflgs
].name
[flaglen
] = '\0';
2202 /* The long instructions are not stored in a hash (there's not many of
2203 them) and so there's no arc_opcode_hash_entry structure to return. This
2204 helper function for find_special_case_long_opcode takes an arc_opcode
2205 result and places it into a fake arc_opcode_hash_entry that points to
2206 the single arc_opcode OPCODE, which is then returned. */
2208 static const struct arc_opcode_hash_entry
*
2209 build_fake_opcode_hash_entry (const struct arc_opcode
*opcode
)
2211 static struct arc_opcode_hash_entry entry
;
2212 static struct arc_opcode tmp
[2];
2213 static const struct arc_opcode
*ptr
[2];
2215 memcpy (&tmp
[0], opcode
, sizeof (struct arc_opcode
));
2216 memset (&tmp
[1], 0, sizeof (struct arc_opcode
));
2225 /* Used by the assembler to match the list of tokens against a long (48 or
2226 64 bits) instruction. If a matching long instruction is found, then
2227 some of the tokens are consumed in this function and converted into a
2228 single LIMM value, which is then added to the end of the token list,
2229 where it will be consumed by a LIMM operand that exists in the base
2230 opcode of the long instruction. */
2232 static const struct arc_opcode_hash_entry
*
2233 find_special_case_long_opcode (const char *opname
,
2234 int *ntok ATTRIBUTE_UNUSED
,
2235 expressionS
*tok ATTRIBUTE_UNUSED
,
2237 struct arc_flags
*pflags
)
2241 if (*ntok
== MAX_INSN_ARGS
)
2244 for (i
= 0; i
< arc_num_long_opcodes
; ++i
)
2246 struct arc_opcode fake_opcode
;
2247 const struct arc_opcode
*opcode
;
2248 struct arc_insn insn
;
2249 expressionS
*limm_token
;
2251 opcode
= &arc_long_opcodes
[i
].base_opcode
;
2253 if (!(opcode
->cpu
& arc_target
))
2256 if (!check_cpu_feature (opcode
->subclass
))
2259 if (strcmp (opname
, opcode
->name
) != 0)
2262 /* Check that the flags are a match. */
2263 if (!parse_opcode_flags (opcode
, *nflgs
, pflags
))
2266 /* Parse the LIMM operands into the LIMM template. */
2267 memset (&fake_opcode
, 0, sizeof (fake_opcode
));
2268 fake_opcode
.name
= "fake limm";
2269 fake_opcode
.opcode
= arc_long_opcodes
[i
].limm_template
;
2270 fake_opcode
.mask
= arc_long_opcodes
[i
].limm_mask
;
2271 fake_opcode
.cpu
= opcode
->cpu
;
2272 fake_opcode
.insn_class
= opcode
->insn_class
;
2273 fake_opcode
.subclass
= opcode
->subclass
;
2274 memcpy (&fake_opcode
.operands
[0],
2275 &arc_long_opcodes
[i
].operands
,
2277 /* Leave fake_opcode.flags as zero. */
2279 pr_debug ("Calling assemble_insn to build fake limm value\n");
2280 assemble_insn (&fake_opcode
, tok
, *ntok
,
2282 pr_debug (" got limm value: 0x%x\n", insn
.insn
);
2284 /* Now create a new token at the end of the token array (We know this
2285 is safe as the token array is always created with enough space for
2286 MAX_INSN_ARGS, and we check at the start at the start of this
2287 function that we're not there yet). This new token will
2288 correspond to a LIMM operand that will be contained in the
2289 base_opcode of the arc_long_opcode. */
2290 limm_token
= &tok
[(*ntok
)];
2293 /* Modify the LIMM token to hold the constant. */
2294 limm_token
->X_op
= O_constant
;
2295 limm_token
->X_add_number
= insn
.insn
;
2297 /* Return the base opcode. */
2298 return build_fake_opcode_hash_entry (opcode
);
2304 /* Used to find special case opcode. */
2306 static const struct arc_opcode_hash_entry
*
2307 find_special_case (const char *opname
,
2309 struct arc_flags
*pflags
,
2313 const struct arc_opcode_hash_entry
*entry
;
2315 entry
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
2318 entry
= find_special_case_flag (opname
, nflgs
, pflags
);
2321 entry
= find_special_case_long_opcode (opname
, ntok
, tok
, nflgs
, pflags
);
2326 /* Given an opcode name, pre-tockenized set of argumenst and the
2327 opcode flags, take it all the way through emission. */
2330 assemble_tokens (const char *opname
,
2333 struct arc_flags
*pflags
,
2336 bfd_boolean found_something
= FALSE
;
2337 const struct arc_opcode_hash_entry
*entry
;
2340 /* Search opcodes. */
2341 entry
= arc_find_opcode (opname
);
2343 /* Couldn't find opcode conventional way, try special cases. */
2345 entry
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
2349 const struct arc_opcode
*opcode
;
2351 pr_debug ("%s:%d: assemble_tokens: %s\n",
2352 frag_now
->fr_file
, frag_now
->fr_line
, opname
);
2353 found_something
= TRUE
;
2354 opcode
= find_opcode_match (entry
, tok
, &ntok
, pflags
,
2358 struct arc_insn insn
;
2360 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
2366 if (found_something
)
2369 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
2371 as_bad (_("opcode '%s' not supported for target %s"), opname
,
2375 as_bad (_("unknown opcode '%s'"), opname
);
2378 /* The public interface to the instruction assembler. */
2381 md_assemble (char *str
)
2384 expressionS tok
[MAX_INSN_ARGS
];
2387 struct arc_flags flags
[MAX_INSN_FLGS
];
2389 /* Split off the opcode. */
2390 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
2391 opname
= xmemdup0 (str
, opnamelen
);
2393 /* Signalize we are assmbling the instructions. */
2394 assembling_insn
= TRUE
;
2396 /* Tokenize the flags. */
2397 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2399 as_bad (_("syntax error"));
2403 /* Scan up to the end of the mnemonic which must end in space or end
2406 for (; *str
!= '\0'; str
++)
2410 /* Tokenize the rest of the line. */
2411 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2413 as_bad (_("syntax error"));
2417 /* Finish it off. */
2418 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2419 assembling_insn
= FALSE
;
2422 /* Callback to insert a register into the hash table. */
2425 declare_register (const char *name
, int number
)
2428 symbolS
*regS
= symbol_create (name
, reg_section
,
2429 number
, &zero_address_frag
);
2431 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
2433 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2437 /* Construct symbols for each of the general registers. */
2440 declare_register_set (void)
2443 for (i
= 0; i
< 64; ++i
)
2447 sprintf (name
, "r%d", i
);
2448 declare_register (name
, i
);
2449 if ((i
& 0x01) == 0)
2451 sprintf (name
, "r%dr%d", i
, i
+1);
2452 declare_register (name
, i
);
2457 /* Port-specific assembler initialization. This function is called
2458 once, at assembler startup time. */
2463 const struct arc_opcode
*opcode
= arc_opcodes
;
2465 if (!mach_type_specified_p
)
2466 arc_select_cpu ("arc700");
2468 /* The endianness can be chosen "at the factory". */
2469 target_big_endian
= byte_order
== BIG_ENDIAN
;
2471 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, arc_mach_type
))
2472 as_warn (_("could not set architecture and machine"));
2474 /* Set elf header flags. */
2475 bfd_set_private_flags (stdoutput
, arc_eflag
);
2477 /* Set up a hash table for the instructions. */
2478 arc_opcode_hash
= hash_new ();
2479 if (arc_opcode_hash
== NULL
)
2480 as_fatal (_("Virtual memory exhausted"));
2482 /* Initialize the hash table with the insns. */
2485 const char *name
= opcode
->name
;
2487 arc_insert_opcode (opcode
);
2489 while (++opcode
&& opcode
->name
2490 && (opcode
->name
== name
2491 || !strcmp (opcode
->name
, name
)))
2493 }while (opcode
->name
);
2495 /* Register declaration. */
2496 arc_reg_hash
= hash_new ();
2497 if (arc_reg_hash
== NULL
)
2498 as_fatal (_("Virtual memory exhausted"));
2500 declare_register_set ();
2501 declare_register ("gp", 26);
2502 declare_register ("fp", 27);
2503 declare_register ("sp", 28);
2504 declare_register ("ilink", 29);
2505 declare_register ("ilink1", 29);
2506 declare_register ("ilink2", 30);
2507 declare_register ("blink", 31);
2509 /* XY memory registers. */
2510 declare_register ("x0_u0", 32);
2511 declare_register ("x0_u1", 33);
2512 declare_register ("x1_u0", 34);
2513 declare_register ("x1_u1", 35);
2514 declare_register ("x2_u0", 36);
2515 declare_register ("x2_u1", 37);
2516 declare_register ("x3_u0", 38);
2517 declare_register ("x3_u1", 39);
2518 declare_register ("y0_u0", 40);
2519 declare_register ("y0_u1", 41);
2520 declare_register ("y1_u0", 42);
2521 declare_register ("y1_u1", 43);
2522 declare_register ("y2_u0", 44);
2523 declare_register ("y2_u1", 45);
2524 declare_register ("y3_u0", 46);
2525 declare_register ("y3_u1", 47);
2526 declare_register ("x0_nu", 48);
2527 declare_register ("x1_nu", 49);
2528 declare_register ("x2_nu", 50);
2529 declare_register ("x3_nu", 51);
2530 declare_register ("y0_nu", 52);
2531 declare_register ("y1_nu", 53);
2532 declare_register ("y2_nu", 54);
2533 declare_register ("y3_nu", 55);
2535 declare_register ("mlo", 57);
2536 declare_register ("mmid", 58);
2537 declare_register ("mhi", 59);
2539 declare_register ("acc1", 56);
2540 declare_register ("acc2", 57);
2542 declare_register ("lp_count", 60);
2543 declare_register ("pcl", 63);
2545 /* Initialize the last instructions. */
2546 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2548 /* Aux register declaration. */
2549 arc_aux_hash
= hash_new ();
2550 if (arc_aux_hash
== NULL
)
2551 as_fatal (_("Virtual memory exhausted"));
2553 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
2555 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
2559 if (!(auxr
->cpu
& arc_target
))
2562 if ((auxr
->subclass
!= NONE
)
2563 && !check_cpu_feature (auxr
->subclass
))
2566 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
2568 as_fatal (_("internal error: can't hash aux register '%s': %s"),
2569 auxr
->name
, retval
);
2573 /* Write a value out to the object file, using the appropriate
2577 md_number_to_chars (char *buf
,
2581 if (target_big_endian
)
2582 number_to_chars_bigendian (buf
, val
, n
);
2584 number_to_chars_littleendian (buf
, val
, n
);
2587 /* Round up a section size to the appropriate boundary. */
2590 md_section_align (segT segment
,
2593 int align
= bfd_get_section_alignment (stdoutput
, segment
);
2595 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2598 /* The location from which a PC relative jump should be calculated,
2599 given a PC relative reloc. */
2602 md_pcrel_from_section (fixS
*fixP
,
2605 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2607 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2609 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2610 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2611 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2613 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2615 /* The symbol is undefined (or is defined but not in this section).
2616 Let the linker figure it out. */
2620 if ((int) fixP
->fx_r_type
< 0)
2622 /* These are the "internal" relocations. Align them to
2623 32 bit boundary (PCL), for the moment. */
2628 switch (fixP
->fx_r_type
)
2630 case BFD_RELOC_ARC_PC32
:
2631 /* The hardware calculates relative to the start of the
2632 insn, but this relocation is relative to location of the
2633 LIMM, compensate. The base always needs to be
2634 substracted by 4 as we do not support this type of PCrel
2635 relocation for short instructions. */
2638 case BFD_RELOC_ARC_PLT32
:
2639 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2640 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2641 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2642 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2644 case BFD_RELOC_ARC_S21H_PCREL
:
2645 case BFD_RELOC_ARC_S25H_PCREL
:
2646 case BFD_RELOC_ARC_S13_PCREL
:
2647 case BFD_RELOC_ARC_S21W_PCREL
:
2648 case BFD_RELOC_ARC_S25W_PCREL
:
2652 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2653 _("unhandled reloc %s in md_pcrel_from_section"),
2654 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2659 pr_debug ("pcrel from %"BFD_VMA_FMT
"x + %lx = %"BFD_VMA_FMT
"x, "
2660 "symbol: %s (%"BFD_VMA_FMT
"x)\n",
2661 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
2662 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2663 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
2668 /* Given a BFD relocation find the coresponding operand. */
2670 static const struct arc_operand
*
2671 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2675 for (i
= 0; i
< arc_num_operands
; i
++)
2676 if (arc_operands
[i
].default_reloc
== reloc
)
2677 return &arc_operands
[i
];
2681 /* Insert an operand value into an instruction. */
2684 insert_operand (unsigned insn
,
2685 const struct arc_operand
*operand
,
2690 offsetT min
= 0, max
= 0;
2692 if (operand
->bits
!= 32
2693 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2694 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2696 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2698 max
= (1 << (operand
->bits
- 1)) - 1;
2699 min
= -(1 << (operand
->bits
- 1));
2703 max
= (1 << operand
->bits
) - 1;
2707 if (val
< min
|| val
> max
)
2708 as_bad_value_out_of_range (_("operand"),
2709 val
, min
, max
, file
, line
);
2712 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2713 min
, val
, max
, insn
);
2715 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2717 as_bad_where (file
, line
,
2718 _("Unaligned operand. Needs to be 32bit aligned"));
2720 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2722 as_bad_where (file
, line
,
2723 _("Unaligned operand. Needs to be 16bit aligned"));
2725 if (operand
->insert
)
2727 const char *errmsg
= NULL
;
2729 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2731 as_warn_where (file
, line
, "%s", errmsg
);
2735 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2737 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2739 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2742 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2747 /* Apply a fixup to the object code. At this point all symbol values
2748 should be fully resolved, and we attempt to completely resolve the
2749 reloc. If we can not do that, we determine the correct reloc code
2750 and put it back in the fixup. To indicate that a fixup has been
2751 eliminated, set fixP->fx_done. */
2754 md_apply_fix (fixS
*fixP
,
2758 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2759 valueT value
= *valP
;
2761 symbolS
*fx_addsy
, *fx_subsy
;
2763 segT add_symbol_segment
= absolute_section
;
2764 segT sub_symbol_segment
= absolute_section
;
2765 const struct arc_operand
*operand
= NULL
;
2766 extended_bfd_reloc_code_real_type reloc
;
2768 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2769 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2770 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2771 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2774 fx_addsy
= fixP
->fx_addsy
;
2775 fx_subsy
= fixP
->fx_subsy
;
2780 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2784 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2785 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2786 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2788 resolve_symbol_value (fx_subsy
);
2789 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2791 if (sub_symbol_segment
== absolute_section
)
2793 /* The symbol is really a constant. */
2794 fx_offset
-= S_GET_VALUE (fx_subsy
);
2799 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2800 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2801 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
2802 segment_name (add_symbol_segment
),
2803 S_GET_NAME (fx_subsy
),
2804 segment_name (sub_symbol_segment
));
2810 && !S_IS_WEAK (fx_addsy
))
2812 if (add_symbol_segment
== seg
2815 value
+= S_GET_VALUE (fx_addsy
);
2816 value
-= md_pcrel_from_section (fixP
, seg
);
2818 fixP
->fx_pcrel
= FALSE
;
2820 else if (add_symbol_segment
== absolute_section
)
2822 value
= fixP
->fx_offset
;
2823 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2825 fixP
->fx_pcrel
= FALSE
;
2830 fixP
->fx_done
= TRUE
;
2835 && ((S_IS_DEFINED (fx_addsy
)
2836 && S_GET_SEGMENT (fx_addsy
) != seg
)
2837 || S_IS_WEAK (fx_addsy
)))
2838 value
+= md_pcrel_from_section (fixP
, seg
);
2840 switch (fixP
->fx_r_type
)
2842 case BFD_RELOC_ARC_32_ME
:
2843 /* This is a pc-relative value in a LIMM. Adjust it to the
2844 address of the instruction not to the address of the
2845 LIMM. Note: it is not anylonger valid this afirmation as
2846 the linker consider ARC_PC32 a fixup to entire 64 bit
2848 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
2851 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
2853 case BFD_RELOC_ARC_PC32
:
2854 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2857 if ((int) fixP
->fx_r_type
< 0)
2858 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2864 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2865 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2866 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2867 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2871 /* Now check for TLS relocations. */
2872 reloc
= fixP
->fx_r_type
;
2875 case BFD_RELOC_ARC_TLS_DTPOFF
:
2876 case BFD_RELOC_ARC_TLS_LE_32
:
2880 case BFD_RELOC_ARC_TLS_GD_GOT
:
2881 case BFD_RELOC_ARC_TLS_IE_GOT
:
2882 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2885 case BFD_RELOC_ARC_TLS_GD_LD
:
2886 gas_assert (!fixP
->fx_offset
);
2889 = (S_GET_VALUE (fixP
->fx_subsy
)
2890 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
2891 fixP
->fx_subsy
= NULL
;
2893 case BFD_RELOC_ARC_TLS_GD_CALL
:
2894 /* These two relocs are there just to allow ld to change the tls
2895 model for this symbol, by patching the code. The offset -
2896 and scale, if any - will be installed by the linker. */
2897 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2900 case BFD_RELOC_ARC_TLS_LE_S9
:
2901 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
2902 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2914 /* Addjust the value if we have a constant. */
2917 /* For hosts with longs bigger than 32-bits make sure that the top
2918 bits of a 32-bit negative value read in by the parser are set,
2919 so that the correct comparisons are made. */
2920 if (value
& 0x80000000)
2921 value
|= (-1UL << 31);
2923 reloc
= fixP
->fx_r_type
;
2931 case BFD_RELOC_ARC_32_PCREL
:
2932 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
2935 case BFD_RELOC_ARC_GOTPC32
:
2936 /* I cannot fix an GOTPC relocation because I need to relax it
2937 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2938 as_bad (_("Unsupported operation on reloc"));
2941 case BFD_RELOC_ARC_TLS_DTPOFF
:
2942 case BFD_RELOC_ARC_TLS_LE_32
:
2943 gas_assert (!fixP
->fx_addsy
);
2944 gas_assert (!fixP
->fx_subsy
);
2946 case BFD_RELOC_ARC_GOTOFF
:
2947 case BFD_RELOC_ARC_32_ME
:
2948 case BFD_RELOC_ARC_PC32
:
2949 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2952 case BFD_RELOC_ARC_PLT32
:
2953 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2956 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2957 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2960 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2961 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
2964 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2965 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2968 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2969 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
2971 case BFD_RELOC_ARC_S25W_PCREL
:
2972 case BFD_RELOC_ARC_S21W_PCREL
:
2973 case BFD_RELOC_ARC_S21H_PCREL
:
2974 case BFD_RELOC_ARC_S25H_PCREL
:
2975 case BFD_RELOC_ARC_S13_PCREL
:
2977 operand
= find_operand_for_reloc (reloc
);
2978 gas_assert (operand
);
2983 if ((int) fixP
->fx_r_type
>= 0)
2984 as_fatal (_("unhandled relocation type %s"),
2985 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2987 /* The rest of these fixups needs to be completely resolved as
2989 if (fixP
->fx_addsy
!= 0
2990 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
2991 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2992 _("non-absolute expression in constant field"));
2994 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
2995 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
3000 if (target_big_endian
)
3002 switch (fixP
->fx_size
)
3005 insn
= bfd_getb32 (fixpos
);
3008 insn
= bfd_getb16 (fixpos
);
3011 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3012 _("unknown fixup size"));
3018 switch (fixP
->fx_size
)
3021 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
3024 insn
= bfd_getl16 (fixpos
);
3027 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3028 _("unknown fixup size"));
3032 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
3033 fixP
->fx_file
, fixP
->fx_line
);
3035 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
3038 /* Prepare machine-dependent frags for relaxation.
3040 Called just before relaxation starts. Any symbol that is now undefined
3041 will not become defined.
3043 Return the correct fr_subtype in the frag.
3045 Return the initial "guess for fr_var" to caller. The guess for fr_var
3046 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3047 or fr_var contributes to our returned value.
3049 Although it may not be explicit in the frag, pretend
3050 fr_var starts with a value. */
3053 md_estimate_size_before_relax (fragS
*fragP
,
3058 /* If the symbol is not located within the same section AND it's not
3059 an absolute section, use the maximum. OR if the symbol is a
3060 constant AND the insn is by nature not pc-rel, use the maximum.
3061 OR if the symbol is being equated against another symbol, use the
3062 maximum. OR if the symbol is weak use the maximum. */
3063 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
3064 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
3065 || (symbol_constant_p (fragP
->fr_symbol
)
3066 && !fragP
->tc_frag_data
.pcrel
)
3067 || symbol_equated_p (fragP
->fr_symbol
)
3068 || S_IS_WEAK (fragP
->fr_symbol
))
3070 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
3071 ++fragP
->fr_subtype
;
3074 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3075 fragP
->fr_var
= growth
;
3077 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3078 fragP
->fr_file
, fragP
->fr_line
, growth
);
3083 /* Translate internal representation of relocation info to BFD target
3087 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
3091 bfd_reloc_code_real_type code
;
3093 reloc
= XNEW (arelent
);
3094 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3095 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3096 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3098 /* Make sure none of our internal relocations make it this far.
3099 They'd better have been fully resolved by this point. */
3100 gas_assert ((int) fixP
->fx_r_type
> 0);
3102 code
= fixP
->fx_r_type
;
3104 /* if we have something like add gp, pcl,
3105 _GLOBAL_OFFSET_TABLE_@gotpc. */
3106 if (code
== BFD_RELOC_ARC_GOTPC32
3108 && fixP
->fx_addsy
== GOT_symbol
)
3109 code
= BFD_RELOC_ARC_GOTPC
;
3111 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
3112 if (reloc
->howto
== NULL
)
3114 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3115 _("cannot represent `%s' relocation in object file"),
3116 bfd_get_reloc_code_name (code
));
3120 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
3121 as_fatal (_("internal error? cannot generate `%s' relocation"),
3122 bfd_get_reloc_code_name (code
));
3124 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
3126 if (code
== BFD_RELOC_ARC_TLS_DTPOFF
3127 || code
== BFD_RELOC_ARC_TLS_DTPOFF_S9
)
3130 = fixP
->fx_subsy
? symbol_get_bfdsym (fixP
->fx_subsy
) : NULL
;
3131 /* We just want to store a 24 bit index, but we have to wait
3132 till after write_contents has been called via
3133 bfd_map_over_sections before we can get the index from
3134 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
3135 function is elf32-arc.c has to pick up the slack.
3136 Unfortunately, this leads to problems with hosts that have
3137 pointers wider than long (bfd_vma). There would be various
3138 ways to handle this, all error-prone :-( */
3139 reloc
->addend
= (bfd_vma
) sym
;
3140 if ((asymbol
*) reloc
->addend
!= sym
)
3142 as_bad ("Can't store pointer\n");
3147 reloc
->addend
= fixP
->fx_offset
;
3152 /* Perform post-processing of machine-dependent frags after relaxation.
3153 Called after relaxation is finished.
3154 In: Address of frag.
3155 fr_type == rs_machine_dependent.
3156 fr_subtype is what the address relaxed to.
3158 Out: Any fixS:s and constants are set up. */
3161 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
3162 segT segment ATTRIBUTE_UNUSED
,
3165 const relax_typeS
*table_entry
;
3167 const struct arc_opcode
*opcode
;
3168 struct arc_insn insn
;
3170 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
3172 fix
= (fragP
->fr_fix
< 0 ? 0 : fragP
->fr_fix
);
3173 dest
= fragP
->fr_literal
+ fix
;
3174 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
3176 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3177 "var: %"BFD_VMA_FMT
"d\n",
3178 fragP
->fr_file
, fragP
->fr_line
,
3179 fragP
->fr_subtype
, fix
, fragP
->fr_var
);
3181 if (fragP
->fr_subtype
<= 0
3182 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
3183 as_fatal (_("no relaxation found for this instruction."));
3185 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
3187 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
3188 relax_arg
->nflg
, &insn
);
3190 apply_fixups (&insn
, fragP
, fix
);
3192 size
= insn
.short_insn
? (insn
.has_limm
? 6 : 2) : (insn
.has_limm
? 8 : 4);
3193 gas_assert (table_entry
->rlx_length
== size
);
3194 emit_insn0 (&insn
, dest
, TRUE
);
3196 fragP
->fr_fix
+= table_entry
->rlx_length
;
3200 /* We have no need to default values of symbols. We could catch
3201 register names here, but that is handled by inserting them all in
3202 the symbol table to begin with. */
3205 md_undefined_symbol (char *name
)
3207 /* The arc abi demands that a GOT[0] should be referencible as
3208 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3209 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3211 && (*(name
+1) == 'G')
3212 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0))
3214 && (*(name
+1) == 'D')
3215 && (strcmp (name
, DYNAMIC_STRUCT_NAME
) == 0)))
3219 if (symbol_find (name
))
3220 as_bad ("GOT already in symbol table");
3222 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
3223 (valueT
) 0, &zero_address_frag
);
3230 /* Turn a string in input_line_pointer into a floating point constant
3231 of type type, and store the appropriate bytes in *litP. The number
3232 of LITTLENUMS emitted is stored in *sizeP. An error message is
3233 returned, or NULL on OK. */
3236 md_atof (int type
, char *litP
, int *sizeP
)
3238 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
3241 /* Called for any expression that can not be recognized. When the
3242 function is called, `input_line_pointer' will point to the start of
3246 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
3248 char *p
= input_line_pointer
;
3251 input_line_pointer
++;
3252 expressionP
->X_op
= O_symbol
;
3253 expression (expressionP
);
3257 /* This function is called from the function 'expression', it attempts
3258 to parse special names (in our case register names). It fills in
3259 the expression with the identified register. It returns TRUE if
3260 it is a register and FALSE otherwise. */
3263 arc_parse_name (const char *name
,
3264 struct expressionS
*e
)
3268 if (!assembling_insn
)
3271 /* Handle only registers. */
3272 if (e
->X_op
!= O_absent
)
3275 sym
= hash_find (arc_reg_hash
, name
);
3278 e
->X_op
= O_register
;
3279 e
->X_add_number
= S_GET_VALUE (sym
);
3286 Invocation line includes a switch not recognized by the base assembler.
3287 See if it's a processor-specific option.
3289 New options (supported) are:
3291 -mcpu=<cpu name> Assemble for selected processor
3292 -EB/-mbig-endian Big-endian
3293 -EL/-mlittle-endian Little-endian
3294 -mrelax Enable relaxation
3296 The following CPU names are recognized:
3297 arc700, av2em, av2hs. */
3300 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
3306 return md_parse_option (OPTION_MCPU
, "arc600");
3309 return md_parse_option (OPTION_MCPU
, "arc700");
3312 return md_parse_option (OPTION_MCPU
, "arcem");
3315 return md_parse_option (OPTION_MCPU
, "archs");
3319 arc_select_cpu (arg
);
3320 mach_type_specified_p
= TRUE
;
3325 arc_target_format
= "elf32-bigarc";
3326 byte_order
= BIG_ENDIAN
;
3330 arc_target_format
= "elf32-littlearc";
3331 byte_order
= LITTLE_ENDIAN
;
3335 /* This option has an effect only on ARC EM. */
3336 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3337 arc_features
|= ARC_CD
;
3339 as_warn (_("Code density option invalid for selected CPU"));
3343 relaxation_state
= 1;
3347 arc_features
|= ARC_NPS400
;
3349 case OPTION_USER_MODE
:
3350 case OPTION_LD_EXT_MASK
:
3353 case OPTION_BARREL_SHIFT
:
3354 case OPTION_MIN_MAX
:
3359 /* Dummy options are accepted but have no effect. */
3363 arc_features
|= ARC_SPFP
;
3367 arc_features
|= ARC_DPFP
;
3370 case OPTION_XMAC_D16
:
3371 case OPTION_XMAC_24
:
3372 case OPTION_DSP_PACKA
:
3375 case OPTION_TELEPHONY
:
3376 case OPTION_XYMEMORY
:
3380 /* Dummy options are accepted but have no effect. */
3384 /* This option has an effect only on ARC EM. */
3385 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3386 arc_features
|= ARC_FPUDA
;
3388 as_warn (_("FPUDA invalid for selected CPU"));
3399 md_show_usage (FILE *stream
)
3401 fprintf (stream
, _("ARC-specific assembler options:\n"));
3403 fprintf (stream
, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
3404 fprintf (stream
, " -mcpu=nps400\t\t same as -mcpu=arc700 -mnps400\n");
3405 fprintf (stream
, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3406 fprintf (stream
, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3407 fprintf (stream
, " -mEM\t\t\t same as -mcpu=arcem\n");
3408 fprintf (stream
, " -mHS\t\t\t same as -mcpu=archs\n");
3410 fprintf (stream
, " -mnps400\t\t enable NPS-400 extended instructions\n");
3411 fprintf (stream
, " -mspfp\t\t enable single-precision floating point instructions\n");
3412 fprintf (stream
, " -mdpfp\t\t enable double-precision floating point instructions\n");
3413 fprintf (stream
, " -mfpuda\t\t enable double-precision assist floating "
3414 "point\n\t\t\t instructions for ARC EM\n");
3417 " -mcode-density\t enable code density option for ARC EM\n");
3419 fprintf (stream
, _("\
3420 -EB assemble code for a big-endian cpu\n"));
3421 fprintf (stream
, _("\
3422 -EL assemble code for a little-endian cpu\n"));
3423 fprintf (stream
, _("\
3424 -mrelax enable relaxation\n"));
3426 fprintf (stream
, _("The following ARC-specific assembler options are "
3427 "deprecated and are accepted\nfor compatibility only:\n"));
3429 fprintf (stream
, _(" -mEA\n"
3430 " -mbarrel-shifter\n"
3431 " -mbarrel_shifter\n"
3436 " -mld-extension-reg-mask\n"
3452 " -muser-mode-only\n"
3456 /* Find the proper relocation for the given opcode. */
3458 static extended_bfd_reloc_code_real_type
3459 find_reloc (const char *name
,
3460 const char *opcodename
,
3461 const struct arc_flags
*pflags
,
3463 extended_bfd_reloc_code_real_type reloc
)
3467 bfd_boolean found_flag
, tmp
;
3468 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
3470 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
3472 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3474 /* Find the entry. */
3475 if (strcmp (name
, r
->name
))
3477 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3484 unsigned * psflg
= (unsigned *)r
->flags
;
3488 for (j
= 0; j
< nflg
; j
++)
3489 if (!strcmp (pflags
[j
].name
,
3490 arc_flag_operands
[*psflg
].name
))
3511 if (reloc
!= r
->oldreloc
)
3518 if (ret
== BFD_RELOC_UNUSED
)
3519 as_bad (_("Unable to find %s relocation for instruction %s"),
3524 /* All the symbol types that are allowed to be used for
3528 may_relax_expr (expressionS tok
)
3530 /* Check if we have unrelaxable relocs. */
3555 /* Checks if flags are in line with relaxable insn. */
3558 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3559 const struct arc_flags
*pflags
,
3562 unsigned flag_class
,
3567 const struct arc_flag_operand
*flag_opand
;
3568 int i
, counttrue
= 0;
3570 /* Iterate through flags classes. */
3571 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3573 /* Iterate through flags in flag class. */
3574 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3577 flag_opand
= &arc_flag_operands
[flag
];
3578 /* Iterate through flags in ins to compare. */
3579 for (i
= 0; i
< nflgs
; ++i
)
3581 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3592 /* If counttrue == nflgs, then all flags have been found. */
3593 return (counttrue
== nflgs
? TRUE
: FALSE
);
3596 /* Checks if operands are in line with relaxable insn. */
3599 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3600 const expressionS
*tok
,
3603 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3606 while (*operand
!= EMPTY
)
3608 const expressionS
*epr
= &tok
[i
];
3610 if (i
!= 0 && i
>= ntok
)
3616 if (!(epr
->X_op
== O_multiply
3617 || epr
->X_op
== O_divide
3618 || epr
->X_op
== O_modulus
3619 || epr
->X_op
== O_add
3620 || epr
->X_op
== O_subtract
3621 || epr
->X_op
== O_symbol
))
3627 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3631 if (epr
->X_op
!= O_register
)
3636 if (epr
->X_op
!= O_register
)
3639 switch (epr
->X_add_number
)
3641 case 0: case 1: case 2: case 3:
3642 case 12: case 13: case 14: case 15:
3649 case REGISTER_NO_GP
:
3650 if ((epr
->X_op
!= O_register
)
3651 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3656 if (epr
->X_op
!= O_bracket
)
3661 /* Don't understand, bail out. */
3667 operand
= &ins
->operands
[i
];
3670 return (i
== ntok
? TRUE
: FALSE
);
3673 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3676 relax_insn_p (const struct arc_opcode
*opcode
,
3677 const expressionS
*tok
,
3679 const struct arc_flags
*pflags
,
3683 bfd_boolean rv
= FALSE
;
3685 /* Check the relaxation table. */
3686 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3688 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3690 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3691 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3692 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3693 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3696 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3697 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3698 sizeof (expressionS
) * ntok
);
3699 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3700 sizeof (struct arc_flags
) * nflg
);
3701 frag_now
->tc_frag_data
.nflg
= nflg
;
3702 frag_now
->tc_frag_data
.ntok
= ntok
;
3710 /* Turn an opcode description and a set of arguments into
3711 an instruction and a fixup. */
3714 assemble_insn (const struct arc_opcode
*opcode
,
3715 const expressionS
*tok
,
3717 const struct arc_flags
*pflags
,
3719 struct arc_insn
*insn
)
3721 const expressionS
*reloc_exp
= NULL
;
3723 const unsigned char *argidx
;
3726 unsigned char pcrel
= 0;
3727 bfd_boolean needGOTSymbol
;
3728 bfd_boolean has_delay_slot
= FALSE
;
3729 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3731 memset (insn
, 0, sizeof (*insn
));
3732 image
= opcode
->opcode
;
3734 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3735 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3738 /* Handle operands. */
3739 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3741 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3742 const expressionS
*t
= (const expressionS
*) 0;
3744 if ((operand
->flags
& ARC_OPERAND_FAKE
)
3745 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
3748 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3750 /* Duplicate operand, already inserted. */
3762 /* Regardless if we have a reloc or not mark the instruction
3763 limm if it is the case. */
3764 if (operand
->flags
& ARC_OPERAND_LIMM
)
3765 insn
->has_limm
= TRUE
;
3770 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3775 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3777 if (operand
->flags
& ARC_OPERAND_LIMM
)
3778 insn
->limm
= t
->X_add_number
;
3782 /* Ignore brackets. */
3786 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3790 /* Maybe register range. */
3791 if ((t
->X_add_number
== 0)
3792 && contains_register (t
->X_add_symbol
)
3793 && contains_register (t
->X_op_symbol
))
3797 regs
= get_register (t
->X_add_symbol
);
3799 regs
|= get_register (t
->X_op_symbol
);
3800 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3805 /* This operand needs a relocation. */
3806 needGOTSymbol
= FALSE
;
3811 if (opcode
->insn_class
== JUMP
)
3812 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3813 _("Unable to use @plt relocatio for insn %s"),
3815 needGOTSymbol
= TRUE
;
3816 reloc
= find_reloc ("plt", opcode
->name
,
3818 operand
->default_reloc
);
3823 needGOTSymbol
= TRUE
;
3824 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3827 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3828 if (ARC_SHORT (opcode
->mask
) || opcode
->insn_class
== JUMP
)
3829 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3830 _("Unable to use @pcl relocation for insn %s"),
3834 reloc
= find_reloc ("sda", opcode
->name
,
3836 operand
->default_reloc
);
3840 needGOTSymbol
= TRUE
;
3845 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3848 case O_tpoff9
: /*FIXME! Check for the conditionality of
3850 case O_dtpoff9
: /*FIXME! Check for the conditionality of
3852 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3856 /* Just consider the default relocation. */
3857 reloc
= operand
->default_reloc
;
3861 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
3862 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
3869 /* sanity checks. */
3870 reloc_howto_type
*reloc_howto
3871 = bfd_reloc_type_lookup (stdoutput
,
3872 (bfd_reloc_code_real_type
) reloc
);
3873 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
3874 if (reloc_howto
->rightshift
)
3875 reloc_bitsize
-= reloc_howto
->rightshift
;
3876 if (reloc_bitsize
!= operand
->bits
)
3878 as_bad (_("invalid relocation %s for field"),
3879 bfd_get_reloc_code_name (reloc
));
3884 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3885 as_fatal (_("too many fixups"));
3887 struct arc_fixup
*fixup
;
3888 fixup
= &insn
->fixups
[insn
->nfixups
++];
3890 fixup
->reloc
= reloc
;
3891 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
3892 fixup
->pcrel
= pcrel
;
3893 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
3900 for (i
= 0; i
< nflg
; i
++)
3902 const struct arc_flag_operand
*flg_operand
= pflags
[i
].flgp
;
3904 /* Check if the instruction has a delay slot. */
3905 if (!strcmp (flg_operand
->name
, "d"))
3906 has_delay_slot
= TRUE
;
3908 /* There is an exceptional case when we cannot insert a flag
3909 just as it is. The .T flag must be handled in relation with
3910 the relative address. */
3911 if (!strcmp (flg_operand
->name
, "t")
3912 || !strcmp (flg_operand
->name
, "nt"))
3914 unsigned bitYoperand
= 0;
3915 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3916 if (!strcmp (flg_operand
->name
, "t"))
3917 if (!strcmp (opcode
->name
, "bbit0")
3918 || !strcmp (opcode
->name
, "bbit1"))
3919 bitYoperand
= arc_NToperand
;
3921 bitYoperand
= arc_Toperand
;
3923 if (!strcmp (opcode
->name
, "bbit0")
3924 || !strcmp (opcode
->name
, "bbit1"))
3925 bitYoperand
= arc_Toperand
;
3927 bitYoperand
= arc_NToperand
;
3929 gas_assert (reloc_exp
!= NULL
);
3930 if (reloc_exp
->X_op
== O_constant
)
3932 /* Check if we have a constant and solved it
3934 offsetT val
= reloc_exp
->X_add_number
;
3935 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
3940 struct arc_fixup
*fixup
;
3942 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3943 as_fatal (_("too many fixups"));
3945 fixup
= &insn
->fixups
[insn
->nfixups
++];
3946 fixup
->exp
= *reloc_exp
;
3947 fixup
->reloc
= -bitYoperand
;
3948 fixup
->pcrel
= pcrel
;
3949 fixup
->islong
= FALSE
;
3953 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
3954 << flg_operand
->shift
;
3957 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
3959 /* Short instruction? */
3960 insn
->short_insn
= ARC_SHORT (opcode
->mask
) ? TRUE
: FALSE
;
3964 /* Update last insn status. */
3965 arc_last_insns
[1] = arc_last_insns
[0];
3966 arc_last_insns
[0].opcode
= opcode
;
3967 arc_last_insns
[0].has_limm
= insn
->has_limm
;
3968 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
3970 /* Check if the current instruction is legally used. */
3971 if (arc_last_insns
[1].has_delay_slot
3972 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3973 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3974 _("A jump/branch instruction in delay slot."));
3978 arc_handle_align (fragS
* fragP
)
3980 if ((fragP
)->fr_type
== rs_align_code
)
3982 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
3983 valueT count
= ((fragP
)->fr_next
->fr_address
3984 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
3986 (fragP
)->fr_var
= 2;
3988 if (count
& 1)/* Padding in the gap till the next 2-byte
3989 boundary with 0s. */
3994 /* Writing nop_s. */
3995 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
3999 /* Here we decide which fixups can be adjusted to make them relative
4000 to the beginning of the section instead of the symbol. Basically
4001 we need to make sure that the dynamic relocations are done
4002 correctly, so in some cases we force the original symbol to be
4006 tc_arc_fix_adjustable (fixS
*fixP
)
4009 /* Prevent all adjustments to global symbols. */
4010 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
4012 if (S_IS_WEAK (fixP
->fx_addsy
))
4015 /* Adjust_reloc_syms doesn't know about the GOT. */
4016 switch (fixP
->fx_r_type
)
4018 case BFD_RELOC_ARC_GOTPC32
:
4019 case BFD_RELOC_ARC_PLT32
:
4020 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
4021 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
4022 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
4023 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
4033 /* Compute the reloc type of an expression EXP. */
4036 arc_check_reloc (expressionS
*exp
,
4037 bfd_reloc_code_real_type
*r_type_p
)
4039 if (*r_type_p
== BFD_RELOC_32
4040 && exp
->X_op
== O_subtract
4041 && exp
->X_op_symbol
!= NULL
4042 && exp
->X_op_symbol
->bsym
->section
== now_seg
)
4043 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
4047 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4050 arc_cons_fix_new (fragS
*frag
,
4054 bfd_reloc_code_real_type r_type
)
4056 r_type
= BFD_RELOC_UNUSED
;
4061 r_type
= BFD_RELOC_8
;
4065 r_type
= BFD_RELOC_16
;
4069 r_type
= BFD_RELOC_24
;
4073 r_type
= BFD_RELOC_32
;
4074 arc_check_reloc (exp
, &r_type
);
4078 r_type
= BFD_RELOC_64
;
4082 as_bad (_("unsupported BFD relocation size %u"), size
);
4083 r_type
= BFD_RELOC_UNUSED
;
4086 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
4089 /* The actual routine that checks the ZOL conditions. */
4092 check_zol (symbolS
*s
)
4094 switch (arc_mach_type
)
4096 case bfd_mach_arc_arcv2
:
4097 if (arc_target
& ARC_OPCODE_ARCv2EM
)
4100 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
4101 || arc_last_insns
[1].has_delay_slot
)
4102 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4106 case bfd_mach_arc_arc600
:
4108 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
4109 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4112 if (arc_last_insns
[0].has_limm
4113 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4114 as_bad (_("A jump instruction with long immediate detected at the \
4115 end of the ZOL label @%s"), S_GET_NAME (s
));
4118 case bfd_mach_arc_arc700
:
4119 if (arc_last_insns
[0].has_delay_slot
)
4120 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4129 /* If ZOL end check the last two instruction for illegals. */
4131 arc_frob_label (symbolS
* sym
)
4133 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
4136 dwarf2_emit_label (sym
);
4139 /* Used because generic relaxation assumes a pc-rel value whilst we
4140 also relax instructions that use an absolute value resolved out of
4141 relative values (if that makes any sense). An example: 'add r1,
4142 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4143 but if they're in the same section we can subtract the section
4144 offset relocation which ends up in a resolved value. So if @.L2 is
4145 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4146 .text + 0x40 = 0x10. */
4148 arc_pcrel_adjust (fragS
*fragP
)
4150 if (!fragP
->tc_frag_data
.pcrel
)
4151 return fragP
->fr_address
+ fragP
->fr_fix
;
4156 /* Initialize the DWARF-2 unwind information for this procedure. */
4159 tc_arc_frame_initial_instructions (void)
4161 /* Stack pointer is register 28. */
4162 cfi_add_CFA_def_cfa_register (28);
4166 tc_arc_regname_to_dw2regnum (char *regname
)
4170 sym
= hash_find (arc_reg_hash
, regname
);
4172 return S_GET_VALUE (sym
);
4177 /* Adjust the symbol table. Delete found AUX register symbols. */
4180 arc_adjust_symtab (void)
4184 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
4186 /* I've created a symbol during parsing process. Now, remove
4187 the symbol as it is found to be an AUX register. */
4188 if (ARC_GET_FLAG (sym
) & ARC_FLAG_AUX
)
4189 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
4192 /* Now do generic ELF adjustments. */
4193 elf_adjust_symtab ();
4197 tokenize_extinsn (extInstruction_t
*einsn
)
4201 unsigned char major_opcode
;
4202 unsigned char sub_opcode
;
4203 unsigned char syntax_class
= 0;
4204 unsigned char syntax_class_modifiers
= 0;
4205 unsigned char suffix_class
= 0;
4210 /* 1st: get instruction name. */
4211 p
= input_line_pointer
;
4212 c
= get_symbol_name (&p
);
4214 insn_name
= xstrdup (p
);
4215 restore_line_pointer (c
);
4217 /* 2nd: get major opcode. */
4218 if (*input_line_pointer
!= ',')
4220 as_bad (_("expected comma after instruction name"));
4221 ignore_rest_of_line ();
4224 input_line_pointer
++;
4225 major_opcode
= get_absolute_expression ();
4227 /* 3rd: get sub-opcode. */
4230 if (*input_line_pointer
!= ',')
4232 as_bad (_("expected comma after major opcode"));
4233 ignore_rest_of_line ();
4236 input_line_pointer
++;
4237 sub_opcode
= get_absolute_expression ();
4239 /* 4th: get suffix class. */
4242 if (*input_line_pointer
!= ',')
4244 as_bad ("expected comma after sub opcode");
4245 ignore_rest_of_line ();
4248 input_line_pointer
++;
4254 for (i
= 0; i
< ARRAY_SIZE (suffixclass
); i
++)
4256 if (!strncmp (suffixclass
[i
].name
, input_line_pointer
,
4257 suffixclass
[i
].len
))
4259 suffix_class
|= suffixclass
[i
].attr_class
;
4260 input_line_pointer
+= suffixclass
[i
].len
;
4265 if (i
== ARRAY_SIZE (suffixclass
))
4267 as_bad ("invalid suffix class");
4268 ignore_rest_of_line ();
4274 if (*input_line_pointer
== '|')
4275 input_line_pointer
++;
4280 /* 5th: get syntax class and syntax class modifiers. */
4281 if (*input_line_pointer
!= ',')
4283 as_bad ("expected comma after suffix class");
4284 ignore_rest_of_line ();
4287 input_line_pointer
++;
4293 for (i
= 0; i
< ARRAY_SIZE (syntaxclassmod
); i
++)
4295 if (!strncmp (syntaxclassmod
[i
].name
,
4297 syntaxclassmod
[i
].len
))
4299 syntax_class_modifiers
|= syntaxclassmod
[i
].attr_class
;
4300 input_line_pointer
+= syntaxclassmod
[i
].len
;
4305 if (i
== ARRAY_SIZE (syntaxclassmod
))
4307 for (i
= 0; i
< ARRAY_SIZE (syntaxclass
); i
++)
4309 if (!strncmp (syntaxclass
[i
].name
,
4311 syntaxclass
[i
].len
))
4313 syntax_class
|= syntaxclass
[i
].attr_class
;
4314 input_line_pointer
+= syntaxclass
[i
].len
;
4319 if (i
== ARRAY_SIZE (syntaxclass
))
4321 as_bad ("missing syntax class");
4322 ignore_rest_of_line ();
4329 if (*input_line_pointer
== '|')
4330 input_line_pointer
++;
4335 demand_empty_rest_of_line ();
4337 einsn
->name
= insn_name
;
4338 einsn
->major
= major_opcode
;
4339 einsn
->minor
= sub_opcode
;
4340 einsn
->syntax
= syntax_class
;
4341 einsn
->modsyn
= syntax_class_modifiers
;
4342 einsn
->suffix
= suffix_class
;
4343 einsn
->flags
= syntax_class
4344 | (syntax_class_modifiers
& ARC_OP1_IMM_IMPLIED
? 0x10 : 0);
4347 /* Generate an extension section. */
4350 arc_set_ext_seg (void)
4352 if (!arcext_section
)
4354 arcext_section
= subseg_new (".arcextmap", 0);
4355 bfd_set_section_flags (stdoutput
, arcext_section
,
4356 SEC_READONLY
| SEC_HAS_CONTENTS
);
4359 subseg_set (arcext_section
, 0);
4363 /* Create an extension instruction description in the arc extension
4364 section of the output file.
4365 The structure for an instruction is like this:
4366 [0]: Length of the record.
4367 [1]: Type of the record.
4371 [4]: Syntax (flags).
4372 [5]+ Name instruction.
4374 The sequence is terminated by an empty entry. */
4377 create_extinst_section (extInstruction_t
*einsn
)
4380 segT old_sec
= now_seg
;
4381 int old_subsec
= now_subseg
;
4383 int name_len
= strlen (einsn
->name
);
4388 *p
= 5 + name_len
+ 1;
4390 *p
= EXT_INSTRUCTION
;
4397 p
= frag_more (name_len
+ 1);
4398 strcpy (p
, einsn
->name
);
4400 subseg_set (old_sec
, old_subsec
);
4403 /* Handler .extinstruction pseudo-op. */
4406 arc_extinsn (int ignore ATTRIBUTE_UNUSED
)
4408 extInstruction_t einsn
;
4409 struct arc_opcode
*arc_ext_opcodes
;
4410 const char *errmsg
= NULL
;
4411 unsigned char moplow
, mophigh
;
4413 memset (&einsn
, 0, sizeof (einsn
));
4414 tokenize_extinsn (&einsn
);
4416 /* Check if the name is already used. */
4417 if (arc_find_opcode (einsn
.name
))
4418 as_warn (_("Pseudocode already used %s"), einsn
.name
);
4420 /* Check the opcode ranges. */
4422 mophigh
= (arc_target
& (ARC_OPCODE_ARCv2EM
4423 | ARC_OPCODE_ARCv2HS
)) ? 0x07 : 0x0a;
4425 if ((einsn
.major
> mophigh
) || (einsn
.major
< moplow
))
4426 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow
, mophigh
);
4428 if ((einsn
.minor
> 0x3f) && (einsn
.major
!= 0x0a)
4429 && (einsn
.major
!= 5) && (einsn
.major
!= 9))
4430 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4432 switch (einsn
.syntax
& ARC_SYNTAX_MASK
)
4434 case ARC_SYNTAX_3OP
:
4435 if (einsn
.modsyn
& ARC_OP1_IMM_IMPLIED
)
4436 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4438 case ARC_SYNTAX_2OP
:
4439 case ARC_SYNTAX_1OP
:
4440 case ARC_SYNTAX_NOP
:
4441 if (einsn
.modsyn
& ARC_OP1_MUST_BE_IMM
)
4442 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4448 arc_ext_opcodes
= arcExtMap_genOpcode (&einsn
, arc_target
, &errmsg
);
4449 if (arc_ext_opcodes
== NULL
)
4452 as_fatal ("%s", errmsg
);
4454 as_fatal (_("Couldn't generate extension instruction opcodes"));
4457 as_warn ("%s", errmsg
);
4459 /* Insert the extension instruction. */
4460 arc_insert_opcode ((const struct arc_opcode
*) arc_ext_opcodes
);
4462 create_extinst_section (&einsn
);
4466 tokenize_extregister (extRegister_t
*ereg
, int opertype
)
4472 int number
, imode
= 0;
4473 bfd_boolean isCore_p
= (opertype
== EXT_CORE_REGISTER
) ? TRUE
: FALSE
;
4474 bfd_boolean isReg_p
= (opertype
== EXT_CORE_REGISTER
4475 || opertype
== EXT_AUX_REGISTER
) ? TRUE
: FALSE
;
4477 /* 1st: get register name. */
4479 p
= input_line_pointer
;
4480 c
= get_symbol_name (&p
);
4483 restore_line_pointer (c
);
4485 /* 2nd: get register number. */
4488 if (*input_line_pointer
!= ',')
4490 as_bad (_("expected comma after register name"));
4491 ignore_rest_of_line ();
4495 input_line_pointer
++;
4496 number
= get_absolute_expression ();
4500 as_bad (_("negative operand number %d"), number
);
4501 ignore_rest_of_line ();
4508 /* 3rd: get register mode. */
4511 if (*input_line_pointer
!= ',')
4513 as_bad (_("expected comma after register number"));
4514 ignore_rest_of_line ();
4519 input_line_pointer
++;
4520 mode
= input_line_pointer
;
4522 if (!strncmp (mode
, "r|w", 3))
4525 input_line_pointer
+= 3;
4527 else if (!strncmp (mode
, "r", 1))
4529 imode
= ARC_REGISTER_READONLY
;
4530 input_line_pointer
+= 1;
4532 else if (strncmp (mode
, "w", 1))
4534 as_bad (_("invalid mode"));
4535 ignore_rest_of_line ();
4541 imode
= ARC_REGISTER_WRITEONLY
;
4542 input_line_pointer
+= 1;
4548 /* 4th: get core register shortcut. */
4550 if (*input_line_pointer
!= ',')
4552 as_bad (_("expected comma after register mode"));
4553 ignore_rest_of_line ();
4558 input_line_pointer
++;
4560 if (!strncmp (input_line_pointer
, "cannot_shortcut", 15))
4562 imode
|= ARC_REGISTER_NOSHORT_CUT
;
4563 input_line_pointer
+= 15;
4565 else if (strncmp (input_line_pointer
, "can_shortcut", 12))
4567 as_bad (_("shortcut designator invalid"));
4568 ignore_rest_of_line ();
4574 input_line_pointer
+= 12;
4577 demand_empty_rest_of_line ();
4580 ereg
->number
= number
;
4581 ereg
->imode
= imode
;
4584 /* Create an extension register/condition description in the arc
4585 extension section of the output file.
4587 The structure for an instruction is like this:
4588 [0]: Length of the record.
4589 [1]: Type of the record.
4591 For core regs and condition codes:
4595 For auxilirary registers:
4599 The sequence is terminated by an empty entry. */
4602 create_extcore_section (extRegister_t
*ereg
, int opertype
)
4604 segT old_sec
= now_seg
;
4605 int old_subsec
= now_subseg
;
4607 int name_len
= strlen (ereg
->name
);
4614 case EXT_CORE_REGISTER
:
4616 *p
= 3 + name_len
+ 1;
4622 case EXT_AUX_REGISTER
:
4624 *p
= 6 + name_len
+ 1;
4626 *p
= EXT_AUX_REGISTER
;
4628 *p
= (ereg
->number
>> 24) & 0xff;
4630 *p
= (ereg
->number
>> 16) & 0xff;
4632 *p
= (ereg
->number
>> 8) & 0xff;
4634 *p
= (ereg
->number
) & 0xff;
4640 p
= frag_more (name_len
+ 1);
4641 strcpy (p
, ereg
->name
);
4643 subseg_set (old_sec
, old_subsec
);
4646 /* Handler .extCoreRegister pseudo-op. */
4649 arc_extcorereg (int opertype
)
4652 struct arc_aux_reg
*auxr
;
4654 struct arc_flag_operand
*ccode
;
4656 memset (&ereg
, 0, sizeof (ereg
));
4657 tokenize_extregister (&ereg
, opertype
);
4661 case EXT_CORE_REGISTER
:
4662 /* Core register. */
4663 if (ereg
.number
> 60)
4664 as_bad (_("core register %s value (%d) too large"), ereg
.name
,
4666 declare_register (ereg
.name
, ereg
.number
);
4668 case EXT_AUX_REGISTER
:
4669 /* Auxiliary register. */
4670 auxr
= XNEW (struct arc_aux_reg
);
4671 auxr
->name
= ereg
.name
;
4672 auxr
->cpu
= arc_target
;
4673 auxr
->subclass
= NONE
;
4674 auxr
->address
= ereg
.number
;
4675 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
4677 as_fatal (_("internal error: can't hash aux register '%s': %s"),
4678 auxr
->name
, retval
);
4681 /* Condition code. */
4682 if (ereg
.number
> 31)
4683 as_bad (_("condition code %s value (%d) too large"), ereg
.name
,
4685 ext_condcode
.size
++;
4686 ext_condcode
.arc_ext_condcode
=
4687 XRESIZEVEC (struct arc_flag_operand
, ext_condcode
.arc_ext_condcode
,
4688 ext_condcode
.size
+ 1);
4689 if (ext_condcode
.arc_ext_condcode
== NULL
)
4690 as_fatal (_("Virtual memory exhausted"));
4692 ccode
= ext_condcode
.arc_ext_condcode
+ ext_condcode
.size
- 1;
4693 ccode
->name
= ereg
.name
;
4694 ccode
->code
= ereg
.number
;
4697 ccode
->favail
= 0; /* not used. */
4699 memset (ccode
, 0, sizeof (struct arc_flag_operand
));
4702 as_bad (_("Unknown extension"));
4705 create_extcore_section (&ereg
, opertype
);
4709 eval: (c-set-style "gnu")