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 #ifndef TARGET_WITH_CPU
55 #define TARGET_WITH_CPU "arc700"
56 #endif /* TARGET_WITH_CPU */
58 /* Enum used to enumerate the relaxable ins operands. */
63 REGISTER_S
, /* Register for short instruction(s). */
64 REGISTER_NO_GP
, /* Is a register but not gp register specifically. */
65 REGISTER_DUP
, /* Duplication of previous operand of type register. */
99 #define regno(x) ((x) & 0x3F)
100 #define is_ir_num(x) (((x) & ~0x3F) == 0)
101 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
102 #define is_spfp_p(op) (((sc) == SPX))
103 #define is_dpfp_p(op) (((sc) == DPX))
104 #define is_fpuda_p(op) (((sc) == DPA))
105 #define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH \
106 || (op)->insn_class == JUMP))
107 #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL))
108 #define is_nps400_p(op) (((sc) == NPS400))
110 /* Generic assembler global variables which must be defined by all
113 /* Characters which always start a comment. */
114 const char comment_chars
[] = "#;";
116 /* Characters which start a comment at the beginning of a line. */
117 const char line_comment_chars
[] = "#";
119 /* Characters which may be used to separate multiple commands on a
121 const char line_separator_chars
[] = "`";
123 /* Characters which are used to indicate an exponent in a floating
125 const char EXP_CHARS
[] = "eE";
127 /* Chars that mean this number is a floating point constant
128 As in 0f12.456 or 0d1.2345e12. */
129 const char FLT_CHARS
[] = "rRsSfFdD";
132 extern int target_big_endian
;
133 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
134 static int byte_order
= DEFAULT_BYTE_ORDER
;
136 /* Arc extension section. */
137 static segT arcext_section
;
139 /* By default relaxation is disabled. */
140 static int relaxation_state
= 0;
142 extern int arc_get_mach (char *);
144 /* Forward declarations. */
145 static void arc_lcomm (int);
146 static void arc_option (int);
147 static void arc_extra_reloc (int);
148 static void arc_extinsn (int);
149 static void arc_extcorereg (int);
151 const pseudo_typeS md_pseudo_table
[] =
153 /* Make sure that .word is 32 bits. */
156 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
157 { "lcomm", arc_lcomm
, 0 },
158 { "lcommon", arc_lcomm
, 0 },
159 { "cpu", arc_option
, 0 },
161 { "extinstruction", arc_extinsn
, 0 },
162 { "extcoreregister", arc_extcorereg
, EXT_CORE_REGISTER
},
163 { "extauxregister", arc_extcorereg
, EXT_AUX_REGISTER
},
164 { "extcondcode", arc_extcorereg
, EXT_COND_CODE
},
166 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
167 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
172 const char *md_shortopts
= "";
176 OPTION_EB
= OPTION_MD_BASE
,
194 /* The following options are deprecated and provided here only for
195 compatibility reasons. */
218 struct option md_longopts
[] =
220 { "EB", no_argument
, NULL
, OPTION_EB
},
221 { "EL", no_argument
, NULL
, OPTION_EL
},
222 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
223 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
224 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
225 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
226 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
227 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
228 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
229 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
230 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
231 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
232 { "mnps400", no_argument
, NULL
, OPTION_NPS400
},
234 /* Floating point options */
235 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
236 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
237 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
238 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
239 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
240 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
241 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
242 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
243 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
244 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
245 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
247 /* The following options are deprecated and provided here only for
248 compatibility reasons. */
249 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
250 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
251 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
252 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
253 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
254 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
255 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
256 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
257 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
258 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
259 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
260 { "mea", no_argument
, NULL
, OPTION_EA
},
261 { "mEA", no_argument
, NULL
, OPTION_EA
},
262 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
263 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
264 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
265 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
266 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
267 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
268 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
269 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
270 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
271 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
272 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
273 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
274 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
275 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
276 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
278 { NULL
, no_argument
, NULL
, 0 }
281 size_t md_longopts_size
= sizeof (md_longopts
);
283 /* Local data and data types. */
285 /* Used since new relocation types are introduced in this
286 file (DUMMY_RELOC_LITUSE_*). */
287 typedef int extended_bfd_reloc_code_real_type
;
293 extended_bfd_reloc_code_real_type reloc
;
295 /* index into arc_operands. */
296 unsigned int opindex
;
298 /* PC-relative, used by internals fixups. */
301 /* TRUE if this fixup is for LIMM operand. */
307 unsigned long long int insn
;
309 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
311 unsigned int len
; /* Length of instruction in bytes. */
312 bfd_boolean has_limm
; /* Boolean value: TRUE if limm field is
314 bfd_boolean relax
; /* Boolean value: TRUE if needs
318 /* Structure to hold any last two instructions. */
319 static struct arc_last_insn
321 /* Saved instruction opcode. */
322 const struct arc_opcode
*opcode
;
324 /* Boolean value: TRUE if current insn is short. */
325 bfd_boolean has_limm
;
327 /* Boolean value: TRUE if current insn has delay slot. */
328 bfd_boolean has_delay_slot
;
331 /* Extension instruction suffix classes. */
339 static const attributes_t suffixclass
[] =
341 { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG
},
342 { "SUFFIX_COND", 11, ARC_SUFFIX_COND
},
343 { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE
}
346 /* Extension instruction syntax classes. */
347 static const attributes_t syntaxclass
[] =
349 { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP
},
350 { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP
},
351 { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP
},
352 { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP
}
355 /* Extension instruction syntax classes modifiers. */
356 static const attributes_t syntaxclassmod
[] =
358 { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED
},
359 { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM
}
362 /* Extension register type. */
370 /* A structure to hold the additional conditional codes. */
373 struct arc_flag_operand
*arc_ext_condcode
;
375 } ext_condcode
= { NULL
, 0 };
377 /* Structure to hold an entry in ARC_OPCODE_HASH. */
378 struct arc_opcode_hash_entry
380 /* The number of pointers in the OPCODE list. */
383 /* Points to a list of opcode pointers. */
384 const struct arc_opcode
**opcode
;
387 /* Structure used for iterating through an arc_opcode_hash_entry. */
388 struct arc_opcode_hash_entry_iterator
390 /* Index into the OPCODE element of the arc_opcode_hash_entry. */
393 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
394 returned by this iterator. */
395 const struct arc_opcode
*opcode
;
398 /* Forward declaration. */
399 static void assemble_insn
400 (const struct arc_opcode
*, const expressionS
*, int,
401 const struct arc_flags
*, int, struct arc_insn
*);
403 /* The selection of the machine type can come from different sources. This
404 enum is used to track how the selection was made in order to perform
406 enum mach_selection_type
409 MACH_SELECTION_FROM_DEFAULT
,
410 MACH_SELECTION_FROM_CPU_DIRECTIVE
,
411 MACH_SELECTION_FROM_COMMAND_LINE
414 /* How the current machine type was selected. */
415 static enum mach_selection_type mach_selection_mode
= MACH_SELECTION_NONE
;
417 /* The hash table of instruction opcodes. */
418 static struct hash_control
*arc_opcode_hash
;
420 /* The hash table of register symbols. */
421 static struct hash_control
*arc_reg_hash
;
423 /* The hash table of aux register symbols. */
424 static struct hash_control
*arc_aux_hash
;
426 /* The hash table of address types. */
427 static struct hash_control
*arc_addrtype_hash
;
429 /* A table of CPU names and opcode sets. */
430 static const struct cpu_type
440 { "arc600", ARC_OPCODE_ARC600
, bfd_mach_arc_arc600
,
441 E_ARC_MACH_ARC600
, 0x00},
442 { "arc700", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
443 E_ARC_MACH_ARC700
, 0x00},
444 { "nps400", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
445 E_ARC_MACH_ARC700
, ARC_NPS400
},
446 { "arcem", ARC_OPCODE_ARCv2EM
, bfd_mach_arc_arcv2
,
447 EF_ARC_CPU_ARCV2EM
, 0x00},
448 { "archs", ARC_OPCODE_ARCv2HS
, bfd_mach_arc_arcv2
,
449 EF_ARC_CPU_ARCV2HS
, ARC_CD
},
453 /* Information about the cpu/variant we're assembling for. */
454 static struct cpu_type selected_cpu
;
456 /* Used by the arc_reloc_op table. Order is important. */
457 #define O_gotoff O_md1 /* @gotoff relocation. */
458 #define O_gotpc O_md2 /* @gotpc relocation. */
459 #define O_plt O_md3 /* @plt relocation. */
460 #define O_sda O_md4 /* @sda relocation. */
461 #define O_pcl O_md5 /* @pcl relocation. */
462 #define O_tlsgd O_md6 /* @tlsgd relocation. */
463 #define O_tlsie O_md7 /* @tlsie relocation. */
464 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
465 #define O_tpoff O_md9 /* @tpoff relocation. */
466 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
467 #define O_dtpoff O_md11 /* @dtpoff relocation. */
468 #define O_last O_dtpoff
470 /* Used to define a bracket as operand in tokens. */
471 #define O_bracket O_md32
473 /* Used to define a colon as an operand in tokens. */
474 #define O_colon O_md31
476 /* Used to define address types in nps400. */
477 #define O_addrtype O_md30
479 /* Dummy relocation, to be sorted out. */
480 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
482 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
484 /* A table to map the spelling of a relocation operand into an appropriate
485 bfd_reloc_code_real_type type. The table is assumed to be ordered such
486 that op-O_literal indexes into it. */
487 #define ARC_RELOC_TABLE(op) \
488 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
490 : (int) (op) - (int) O_gotoff) ])
492 #define DEF(NAME, RELOC, REQ) \
493 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
495 static const struct arc_reloc_op_tag
497 /* String to lookup. */
499 /* Size of the string. */
501 /* Which operator to use. */
503 extended_bfd_reloc_code_real_type reloc
;
504 /* Allows complex relocation expression like identifier@reloc +
506 unsigned int complex_expr
: 1;
510 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
511 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
512 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
513 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
514 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
515 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
516 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
517 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
518 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
519 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
520 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 1),
523 static const int arc_num_reloc_op
524 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
526 /* Structure for relaxable instruction that have to be swapped with a
527 smaller alternative instruction. */
528 struct arc_relaxable_ins
530 /* Mnemonic that should be checked. */
531 const char *mnemonic_r
;
533 /* Operands that should be checked.
534 Indexes of operands from operand array. */
535 enum rlx_operand_type operands
[6];
537 /* Flags that should be checked. */
538 unsigned flag_classes
[5];
540 /* Mnemonic (smaller) alternative to be used later for relaxation. */
541 const char *mnemonic_alt
;
543 /* Index of operand that generic relaxation has to check. */
546 /* Base subtype index used. */
547 enum arc_rlx_types subtype
;
550 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
551 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
552 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
556 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
557 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
558 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
563 /* ARC relaxation table. */
564 const relax_typeS md_relax_table
[] =
571 RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL
),
572 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE
),
576 RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B
),
577 RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE
),
582 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6
),
583 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM
),
584 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
586 /* LD_S a, [b, u7] ->
587 LD<zz><.x><.aa><.di> a, [b, s9] ->
588 LD<zz><.x><.aa><.di> a, [b, limm] */
589 RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9
),
590 RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM
),
591 RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE
),
596 RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12
),
597 RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM
),
598 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
602 SUB<.f> a, b, limm. */
603 RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6
),
604 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM
),
605 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
607 /* MPY<.f> a, b, u6 ->
608 MPY<.f> a, b, limm. */
609 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM
),
610 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
612 /* MOV<.f><.cc> b, u6 ->
613 MOV<.f><.cc> b, limm. */
614 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM
),
615 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
617 /* ADD<.f><.cc> b, b, u6 ->
618 ADD<.f><.cc> b, b, limm. */
619 RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM
),
620 RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE
),
623 /* Order of this table's entries matters! */
624 const struct arc_relaxable_ins arc_relaxable_insns
[] =
626 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
627 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
628 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
629 2, ARC_RLX_ADD_RRU6
},
630 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
632 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
634 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
635 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
636 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
637 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
638 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
639 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
640 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
641 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
643 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
645 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
649 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
651 /* Flags to set in the elf header. */
652 static const flagword arc_initial_eflag
= 0x00;
654 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
655 symbolS
* GOT_symbol
= 0;
657 /* Set to TRUE when we assemble instructions. */
658 static bfd_boolean assembling_insn
= FALSE
;
660 /* Functions implementation. */
662 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
663 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
664 are no matching entries in ARC_OPCODE_HASH. */
666 static const struct arc_opcode_hash_entry
*
667 arc_find_opcode (const char *name
)
669 const struct arc_opcode_hash_entry
*entry
;
671 entry
= hash_find (arc_opcode_hash
, name
);
675 /* Initialise the iterator ITER. */
678 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator
*iter
)
684 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
685 calls to this function. Return NULL when all ARC_OPCODE entries have
688 static const struct arc_opcode
*
689 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry
*entry
,
690 struct arc_opcode_hash_entry_iterator
*iter
)
692 if (iter
->opcode
== NULL
&& iter
->index
== 0)
694 gas_assert (entry
->count
> 0);
695 iter
->opcode
= entry
->opcode
[iter
->index
];
697 else if (iter
->opcode
!= NULL
)
699 const char *old_name
= iter
->opcode
->name
;
702 if (iter
->opcode
->name
== NULL
703 || strcmp (old_name
, iter
->opcode
->name
) != 0)
706 if (iter
->index
== entry
->count
)
709 iter
->opcode
= entry
->opcode
[iter
->index
];
716 /* Insert an opcode into opcode hash structure. */
719 arc_insert_opcode (const struct arc_opcode
*opcode
)
721 const char *name
, *retval
;
722 struct arc_opcode_hash_entry
*entry
;
725 entry
= hash_find (arc_opcode_hash
, name
);
728 entry
= XNEW (struct arc_opcode_hash_entry
);
730 entry
->opcode
= NULL
;
732 retval
= hash_insert (arc_opcode_hash
, name
, (void *) entry
);
734 as_fatal (_("internal error: can't hash opcode '%s': %s"),
738 entry
->opcode
= XRESIZEVEC (const struct arc_opcode
*, entry
->opcode
,
741 if (entry
->opcode
== NULL
)
742 as_fatal (_("Virtual memory exhausted"));
744 entry
->opcode
[entry
->count
] = opcode
;
749 /* Like md_number_to_chars but for middle-endian values. The 4-byte limm
750 value, is encoded as 'middle-endian' for a little-endian target. This
751 function is used for regular 4, 6, and 8 byte instructions as well. */
754 md_number_to_chars_midend (char *buf
, unsigned long long val
, int n
)
759 md_number_to_chars (buf
, val
, n
);
762 md_number_to_chars (buf
, (val
& 0xffff00000000) >> 32, 2);
763 md_number_to_chars_midend (buf
+ 2, (val
& 0xffffffff), 4);
766 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
767 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
770 md_number_to_chars_midend (buf
, (val
& 0xffffffff00000000) >> 32, 4);
771 md_number_to_chars_midend (buf
+ 4, (val
& 0xffffffff), 4);
778 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
779 the relevant static global variables. Parameter SEL describes where
780 this selection originated from. */
783 arc_select_cpu (const char *arg
, enum mach_selection_type sel
)
788 /* We should only set a default if we've not made a selection from some
790 gas_assert (sel
!= MACH_SELECTION_FROM_DEFAULT
791 || mach_selection_mode
== MACH_SELECTION_NONE
);
793 /* Look for a matching entry in CPU_TYPES array. */
794 for (i
= 0; cpu_types
[i
].name
; ++i
)
796 if (!strcasecmp (cpu_types
[i
].name
, arg
))
798 /* If a previous selection was made on the command line, then we
799 allow later selections on the command line to override earlier
800 ones. However, a selection from a '.cpu NAME' directive must
801 match the command line selection, or we give a warning. */
802 if (mach_selection_mode
== MACH_SELECTION_FROM_COMMAND_LINE
)
804 gas_assert (sel
== MACH_SELECTION_FROM_COMMAND_LINE
805 || sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
);
806 if (sel
== MACH_SELECTION_FROM_CPU_DIRECTIVE
807 && selected_cpu
.mach
!= cpu_types
[i
].mach
)
809 as_warn (_("Command-line value overrides \".cpu\" directive"));
814 /* Initialise static global data about selected machine type. */
815 selected_cpu
.flags
= cpu_types
[i
].flags
;
816 selected_cpu
.name
= cpu_types
[i
].name
;
817 selected_cpu
.features
= cpu_types
[i
].features
;
818 selected_cpu
.mach
= cpu_types
[i
].mach
;
819 cpu_flags
= cpu_types
[i
].eflags
;
824 if (!cpu_types
[i
].name
)
825 as_fatal (_("unknown architecture: %s\n"), arg
);
826 gas_assert (cpu_flags
!= 0);
827 selected_cpu
.eflags
= (arc_initial_eflag
& ~EF_ARC_MACH_MSK
) | cpu_flags
;
828 mach_selection_mode
= sel
;
831 /* Here ends all the ARCompact extension instruction assembling
835 arc_extra_reloc (int r_type
)
838 symbolS
*sym
, *lab
= NULL
;
840 if (*input_line_pointer
== '@')
841 input_line_pointer
++;
842 c
= get_symbol_name (&sym_name
);
843 sym
= symbol_find_or_make (sym_name
);
844 restore_line_pointer (c
);
845 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
847 ++input_line_pointer
;
849 c
= get_symbol_name (&lab_name
);
850 lab
= symbol_find_or_make (lab_name
);
851 restore_line_pointer (c
);
854 /* These relocations exist as a mechanism for the compiler to tell the
855 linker how to patch the code if the tls model is optimised. However,
856 the relocation itself does not require any space within the assembler
857 fragment, and so we pass a size of 0.
859 The lines that generate these relocations look like this:
861 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
863 The '.tls_gd_ld @.tdata' is processed first and generates the
864 additional relocation, while the 'bl __tls_get_addr@plt' is processed
865 second and generates the additional branch.
867 It is possible that the additional relocation generated by the
868 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
869 while the 'bl __tls_get_addr@plt' will be generated as the first thing
870 in the next fragment. This will be fine; both relocations will still
871 appear to be at the same address in the generated object file.
872 However, this only works as the additional relocation is generated
873 with size of 0 bytes. */
875 = fix_new (frag_now
, /* Which frag? */
876 frag_now_fix (), /* Where in that frag? */
877 0, /* size: 1, 2, or 4 usually. */
878 sym
, /* X_add_symbol. */
879 0, /* X_add_number. */
880 FALSE
, /* TRUE if PC-relative relocation. */
881 r_type
/* Relocation type. */);
882 fixP
->fx_subsy
= lab
;
886 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
887 symbolS
*symbolP
, addressT size
)
892 if (*input_line_pointer
== ',')
894 align
= parse_align (1);
896 if (align
== (addressT
) -1)
911 bss_alloc (symbolP
, size
, align
);
912 S_CLEAR_EXTERNAL (symbolP
);
918 arc_lcomm (int ignore
)
920 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
923 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
926 /* Select the cpu we're assembling for. */
929 arc_option (int ignore ATTRIBUTE_UNUSED
)
933 const char *cpu_name
;
935 c
= get_symbol_name (&cpu
);
937 if ((!strcmp ("ARC600", cpu
))
938 || (!strcmp ("ARC601", cpu
))
939 || (!strcmp ("A6", cpu
)))
941 else if ((!strcmp ("ARC700", cpu
))
942 || (!strcmp ("A7", cpu
)))
944 else if (!strcmp ("EM", cpu
))
946 else if (!strcmp ("HS", cpu
))
948 else if (!strcmp ("NPS400", cpu
))
953 if (cpu_name
!= NULL
)
954 arc_select_cpu (cpu_name
, MACH_SELECTION_FROM_CPU_DIRECTIVE
);
956 as_fatal (_("invalid architecture `%s' in .cpu directive"), cpu
);
958 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
959 as_fatal (_("could not set architecture and machine"));
961 /* Set elf header flags. */
962 bfd_set_private_flags (stdoutput
, selected_cpu
.eflags
);
964 restore_line_pointer (c
);
965 demand_empty_rest_of_line ();
968 /* Smartly print an expression. */
971 debug_exp (expressionS
*t
)
973 const char *name ATTRIBUTE_UNUSED
;
974 const char *namemd ATTRIBUTE_UNUSED
;
976 pr_debug ("debug_exp: ");
980 default: name
= "unknown"; break;
981 case O_illegal
: name
= "O_illegal"; break;
982 case O_absent
: name
= "O_absent"; break;
983 case O_constant
: name
= "O_constant"; break;
984 case O_symbol
: name
= "O_symbol"; break;
985 case O_symbol_rva
: name
= "O_symbol_rva"; break;
986 case O_register
: name
= "O_register"; break;
987 case O_big
: name
= "O_big"; break;
988 case O_uminus
: name
= "O_uminus"; break;
989 case O_bit_not
: name
= "O_bit_not"; break;
990 case O_logical_not
: name
= "O_logical_not"; break;
991 case O_multiply
: name
= "O_multiply"; break;
992 case O_divide
: name
= "O_divide"; break;
993 case O_modulus
: name
= "O_modulus"; break;
994 case O_left_shift
: name
= "O_left_shift"; break;
995 case O_right_shift
: name
= "O_right_shift"; break;
996 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
997 case O_bit_or_not
: name
= "O_bit_or_not"; break;
998 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
999 case O_bit_and
: name
= "O_bit_and"; break;
1000 case O_add
: name
= "O_add"; break;
1001 case O_subtract
: name
= "O_subtract"; break;
1002 case O_eq
: name
= "O_eq"; break;
1003 case O_ne
: name
= "O_ne"; break;
1004 case O_lt
: name
= "O_lt"; break;
1005 case O_le
: name
= "O_le"; break;
1006 case O_ge
: name
= "O_ge"; break;
1007 case O_gt
: name
= "O_gt"; break;
1008 case O_logical_and
: name
= "O_logical_and"; break;
1009 case O_logical_or
: name
= "O_logical_or"; break;
1010 case O_index
: name
= "O_index"; break;
1011 case O_bracket
: name
= "O_bracket"; break;
1012 case O_colon
: name
= "O_colon"; break;
1013 case O_addrtype
: name
= "O_addrtype"; break;
1018 default: namemd
= "unknown"; break;
1019 case O_gotoff
: namemd
= "O_gotoff"; break;
1020 case O_gotpc
: namemd
= "O_gotpc"; break;
1021 case O_plt
: namemd
= "O_plt"; break;
1022 case O_sda
: namemd
= "O_sda"; break;
1023 case O_pcl
: namemd
= "O_pcl"; break;
1024 case O_tlsgd
: namemd
= "O_tlsgd"; break;
1025 case O_tlsie
: namemd
= "O_tlsie"; break;
1026 case O_tpoff9
: namemd
= "O_tpoff9"; break;
1027 case O_tpoff
: namemd
= "O_tpoff"; break;
1028 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
1029 case O_dtpoff
: namemd
= "O_dtpoff"; break;
1032 pr_debug ("%s (%s, %s, %d, %s)", name
,
1033 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1034 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1035 (int) t
->X_add_number
,
1036 (t
->X_md
) ? namemd
: "--");
1041 /* Parse the arguments to an opcode. */
1044 tokenize_arguments (char *str
,
1048 char *old_input_line_pointer
;
1049 bfd_boolean saw_comma
= FALSE
;
1050 bfd_boolean saw_arg
= FALSE
;
1055 const struct arc_reloc_op_tag
*r
;
1057 char *reloc_name
, c
;
1059 memset (tok
, 0, sizeof (*tok
) * ntok
);
1061 /* Save and restore input_line_pointer around this function. */
1062 old_input_line_pointer
= input_line_pointer
;
1063 input_line_pointer
= str
;
1065 while (*input_line_pointer
)
1068 switch (*input_line_pointer
)
1074 input_line_pointer
++;
1075 if (saw_comma
|| !saw_arg
)
1082 ++input_line_pointer
;
1084 if (!saw_arg
|| num_args
== ntok
)
1086 tok
->X_op
= O_bracket
;
1093 input_line_pointer
++;
1094 if (brk_lvl
|| num_args
== ntok
)
1097 tok
->X_op
= O_bracket
;
1103 input_line_pointer
++;
1104 if (!saw_arg
|| num_args
== ntok
)
1106 tok
->X_op
= O_colon
;
1113 /* We have labels, function names and relocations, all
1114 starting with @ symbol. Sort them out. */
1115 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1119 tok
->X_op
= O_symbol
;
1120 tok
->X_md
= O_absent
;
1122 if (*input_line_pointer
!= '@')
1123 goto normalsymbol
; /* This is not a relocation. */
1127 /* A relocation opernad has the following form
1128 @identifier@relocation_type. The identifier is already
1130 if (tok
->X_op
!= O_symbol
)
1132 as_bad (_("No valid label relocation operand"));
1136 /* Parse @relocation_type. */
1137 input_line_pointer
++;
1138 c
= get_symbol_name (&reloc_name
);
1139 len
= input_line_pointer
- reloc_name
;
1142 as_bad (_("No relocation operand"));
1146 /* Go through known relocation and try to find a match. */
1147 r
= &arc_reloc_op
[0];
1148 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1149 if (len
== r
->length
1150 && memcmp (reloc_name
, r
->name
, len
) == 0)
1154 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
1158 *input_line_pointer
= c
;
1159 SKIP_WHITESPACE_AFTER_NAME ();
1160 /* Extra check for TLS: base. */
1161 if (*input_line_pointer
== '@')
1164 if (tok
->X_op_symbol
!= NULL
1165 || tok
->X_op
!= O_symbol
)
1167 as_bad (_("Unable to parse TLS base: %s"),
1168 input_line_pointer
);
1171 input_line_pointer
++;
1173 c
= get_symbol_name (&sym_name
);
1174 base
= symbol_find_or_make (sym_name
);
1175 tok
->X_op
= O_subtract
;
1176 tok
->X_op_symbol
= base
;
1177 restore_line_pointer (c
);
1178 tmpE
.X_add_number
= 0;
1180 if ((*input_line_pointer
!= '+')
1181 && (*input_line_pointer
!= '-'))
1183 tmpE
.X_add_number
= 0;
1187 /* Parse the constant of a complex relocation expression
1188 like @identifier@reloc +/- const. */
1189 if (! r
->complex_expr
)
1191 as_bad (_("@%s is not a complex relocation."), r
->name
);
1195 if (tmpE
.X_op
!= O_constant
)
1197 as_bad (_("Bad expression: @%s + %s."),
1198 r
->name
, input_line_pointer
);
1204 tok
->X_add_number
= tmpE
.X_add_number
;
1215 /* Can be a register. */
1216 ++input_line_pointer
;
1220 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1223 tok
->X_op
= O_absent
;
1224 tok
->X_md
= O_absent
;
1227 /* Legacy: There are cases when we have
1228 identifier@relocation_type, if it is the case parse the
1229 relocation type as well. */
1230 if (*input_line_pointer
== '@')
1236 if (tok
->X_op
== O_illegal
1237 || tok
->X_op
== O_absent
1238 || num_args
== ntok
)
1250 if (saw_comma
|| brk_lvl
)
1252 input_line_pointer
= old_input_line_pointer
;
1258 as_bad (_("Brackets in operand field incorrect"));
1260 as_bad (_("extra comma"));
1262 as_bad (_("missing argument"));
1264 as_bad (_("missing comma or colon"));
1265 input_line_pointer
= old_input_line_pointer
;
1269 /* Parse the flags to a structure. */
1272 tokenize_flags (const char *str
,
1273 struct arc_flags flags
[],
1276 char *old_input_line_pointer
;
1277 bfd_boolean saw_flg
= FALSE
;
1278 bfd_boolean saw_dot
= FALSE
;
1282 memset (flags
, 0, sizeof (*flags
) * nflg
);
1284 /* Save and restore input_line_pointer around this function. */
1285 old_input_line_pointer
= input_line_pointer
;
1286 input_line_pointer
= (char *) str
;
1288 while (*input_line_pointer
)
1290 switch (*input_line_pointer
)
1297 input_line_pointer
++;
1305 if (saw_flg
&& !saw_dot
)
1308 if (num_flags
>= nflg
)
1311 flgnamelen
= strspn (input_line_pointer
,
1312 "abcdefghijklmnopqrstuvwxyz0123456789");
1313 if (flgnamelen
> MAX_FLAG_NAME_LENGTH
)
1316 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1318 input_line_pointer
+= flgnamelen
;
1328 input_line_pointer
= old_input_line_pointer
;
1333 as_bad (_("extra dot"));
1335 as_bad (_("unrecognized flag"));
1337 as_bad (_("failed to parse flags"));
1338 input_line_pointer
= old_input_line_pointer
;
1342 /* Apply the fixups in order. */
1345 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1349 for (i
= 0; i
< insn
->nfixups
; i
++)
1351 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1352 int size
, pcrel
, offset
= 0;
1354 /* FIXME! the reloc size is wrong in the BFD file.
1355 When it is fixed please delete me. */
1356 size
= ((insn
->len
== 2) && !fixup
->islong
) ? 2 : 4;
1361 /* Some fixups are only used internally, thus no howto. */
1362 if ((int) fixup
->reloc
== 0)
1363 as_fatal (_("Unhandled reloc type"));
1365 if ((int) fixup
->reloc
< 0)
1367 /* FIXME! the reloc size is wrong in the BFD file.
1368 When it is fixed please enable me.
1369 size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
1370 pcrel
= fixup
->pcrel
;
1374 reloc_howto_type
*reloc_howto
=
1375 bfd_reloc_type_lookup (stdoutput
,
1376 (bfd_reloc_code_real_type
) fixup
->reloc
);
1377 gas_assert (reloc_howto
);
1379 /* FIXME! the reloc size is wrong in the BFD file.
1380 When it is fixed please enable me.
1381 size = bfd_get_reloc_size (reloc_howto); */
1382 pcrel
= reloc_howto
->pc_relative
;
1385 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1387 fragP
->fr_file
, fragP
->fr_line
,
1388 (fixup
->reloc
< 0) ? "Internal" :
1389 bfd_get_reloc_code_name (fixup
->reloc
),
1392 fix_new_exp (fragP
, fix
+ offset
,
1393 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1395 /* Check for ZOLs, and update symbol info if any. */
1396 if (LP_INSN (insn
->insn
))
1398 gas_assert (fixup
->exp
.X_add_symbol
);
1399 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1404 /* Actually output an instruction with its fixup. */
1407 emit_insn0 (struct arc_insn
*insn
, char *where
, bfd_boolean relax
)
1412 pr_debug ("Emit insn : 0x%llx\n", insn
->insn
);
1413 pr_debug ("\tLength : 0x%d\n", insn
->len
);
1414 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1416 /* Write out the instruction. */
1417 total_len
= insn
->len
+ (insn
->has_limm
? 4 : 0);
1419 f
= frag_more (total_len
);
1421 md_number_to_chars_midend(f
, insn
->insn
, insn
->len
);
1424 md_number_to_chars_midend (f
+ insn
->len
, insn
->limm
, 4);
1425 dwarf2_emit_insn (total_len
);
1428 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1432 emit_insn1 (struct arc_insn
*insn
)
1434 /* How frag_var's args are currently configured:
1435 - rs_machine_dependent, to dictate it's a relaxation frag.
1436 - FRAG_MAX_GROWTH, maximum size of instruction
1437 - 0, variable size that might grow...unused by generic relaxation.
1438 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1439 - s, opand expression.
1440 - 0, offset but it's unused.
1441 - 0, opcode but it's unused. */
1442 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1443 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1445 if (frag_room () < FRAG_MAX_GROWTH
)
1447 /* Handle differently when frag literal memory is exhausted.
1448 This is used because when there's not enough memory left in
1449 the current frag, a new frag is created and the information
1450 we put into frag_now->tc_frag_data is disregarded. */
1452 struct arc_relax_type relax_info_copy
;
1453 relax_substateT subtype
= frag_now
->fr_subtype
;
1455 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1456 sizeof (struct arc_relax_type
));
1458 frag_wane (frag_now
);
1459 frag_grow (FRAG_MAX_GROWTH
);
1461 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1462 sizeof (struct arc_relax_type
));
1464 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1468 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1469 frag_now
->fr_subtype
, s
, 0, 0);
1473 emit_insn (struct arc_insn
*insn
)
1478 emit_insn0 (insn
, NULL
, FALSE
);
1481 /* Check whether a symbol involves a register. */
1484 contains_register (symbolS
*sym
)
1488 expressionS
*ex
= symbol_get_value_expression (sym
);
1490 return ((O_register
== ex
->X_op
)
1491 && !contains_register (ex
->X_add_symbol
)
1492 && !contains_register (ex
->X_op_symbol
));
1498 /* Returns the register number within a symbol. */
1501 get_register (symbolS
*sym
)
1503 if (!contains_register (sym
))
1506 expressionS
*ex
= symbol_get_value_expression (sym
);
1507 return regno (ex
->X_add_number
);
1510 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1511 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1514 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1521 case BFD_RELOC_ARC_SDA_LDST
:
1522 case BFD_RELOC_ARC_SDA_LDST1
:
1523 case BFD_RELOC_ARC_SDA_LDST2
:
1524 case BFD_RELOC_ARC_SDA16_LD
:
1525 case BFD_RELOC_ARC_SDA16_LD1
:
1526 case BFD_RELOC_ARC_SDA16_LD2
:
1527 case BFD_RELOC_ARC_SDA16_ST2
:
1528 case BFD_RELOC_ARC_SDA32_ME
:
1535 /* Allocates a tok entry. */
1538 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1540 if (ntok
> MAX_INSN_ARGS
- 2)
1541 return 0; /* No space left. */
1544 return 0; /* Incorect args. */
1546 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1549 return 1; /* Success. */
1550 return allocate_tok (tok
, ntok
- 1, cidx
);
1553 /* Check if an particular ARC feature is enabled. */
1556 check_cpu_feature (insn_subclass_t sc
)
1558 if (is_code_density_p (sc
) && !(selected_cpu
.features
& ARC_CD
))
1561 if (is_spfp_p (sc
) && !(selected_cpu
.features
& ARC_SPFP
))
1564 if (is_dpfp_p (sc
) && !(selected_cpu
.features
& ARC_DPFP
))
1567 if (is_fpuda_p (sc
) && !(selected_cpu
.features
& ARC_FPUDA
))
1570 if (is_nps400_p (sc
) && !(selected_cpu
.features
& ARC_NPS400
))
1576 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1577 operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG
1578 array and returns TRUE if the flag operands all match, otherwise,
1579 returns FALSE, in which case the FIRST_PFLAG array may have been
1583 parse_opcode_flags (const struct arc_opcode
*opcode
,
1585 struct arc_flags
*first_pflag
)
1588 const unsigned char *flgidx
;
1591 for (i
= 0; i
< nflgs
; i
++)
1592 first_pflag
[i
].flgp
= NULL
;
1594 /* Check the flags. Iterate over the valid flag classes. */
1595 for (flgidx
= opcode
->flags
; *flgidx
; ++flgidx
)
1597 /* Get a valid flag class. */
1598 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1599 const unsigned *flgopridx
;
1601 struct arc_flags
*pflag
= NULL
;
1603 /* Check for extension conditional codes. */
1604 if (ext_condcode
.arc_ext_condcode
1605 && cl_flags
->flag_class
& F_CLASS_EXTEND
)
1607 struct arc_flag_operand
*pf
= ext_condcode
.arc_ext_condcode
;
1610 pflag
= first_pflag
;
1611 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1613 if (!strcmp (pf
->name
, pflag
->name
))
1615 if (pflag
->flgp
!= NULL
)
1628 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1630 const struct arc_flag_operand
*flg_operand
;
1632 pflag
= first_pflag
;
1633 flg_operand
= &arc_flag_operands
[*flgopridx
];
1634 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1636 /* Match against the parsed flags. */
1637 if (!strcmp (flg_operand
->name
, pflag
->name
))
1639 if (pflag
->flgp
!= NULL
)
1642 pflag
->flgp
= flg_operand
;
1644 break; /* goto next flag class and parsed flag. */
1649 if ((cl_flags
->flag_class
& F_CLASS_REQUIRED
) && cl_matches
== 0)
1651 if ((cl_flags
->flag_class
& F_CLASS_OPTIONAL
) && cl_matches
> 1)
1655 /* Did I check all the parsed flags? */
1656 return lnflg
? FALSE
: TRUE
;
1660 /* Search forward through all variants of an opcode looking for a
1663 static const struct arc_opcode
*
1664 find_opcode_match (const struct arc_opcode_hash_entry
*entry
,
1667 struct arc_flags
*first_pflag
,
1671 const struct arc_opcode
*opcode
;
1672 struct arc_opcode_hash_entry_iterator iter
;
1674 int got_cpu_match
= 0;
1675 expressionS bktok
[MAX_INSN_ARGS
];
1679 arc_opcode_hash_entry_iterator_init (&iter
);
1680 memset (&emptyE
, 0, sizeof (emptyE
));
1681 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1684 for (opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
);
1686 opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
))
1688 const unsigned char *opidx
;
1690 const expressionS
*t
= &emptyE
;
1692 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
1693 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1695 /* Don't match opcodes that don't exist on this
1697 if (!(opcode
->cpu
& selected_cpu
.flags
))
1700 if (!check_cpu_feature (opcode
->subclass
))
1706 /* Check the operands. */
1707 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1709 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1711 /* Only take input from real operands. */
1712 if (ARC_OPERAND_IS_FAKE (operand
))
1715 /* When we expect input, make sure we have it. */
1719 /* Match operand type with expression type. */
1720 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1722 case ARC_OPERAND_ADDRTYPE
:
1724 const char *errmsg
= NULL
;
1726 /* Check to be an address type. */
1727 if (tok
[tokidx
].X_op
!= O_addrtype
)
1730 /* All address type operands need to have an insert
1731 method in order to check that we have the correct
1733 gas_assert (operand
->insert
!= NULL
);
1734 (*operand
->insert
) (0, tok
[tokidx
].X_add_number
,
1741 case ARC_OPERAND_IR
:
1742 /* Check to be a register. */
1743 if ((tok
[tokidx
].X_op
!= O_register
1744 || !is_ir_num (tok
[tokidx
].X_add_number
))
1745 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1748 /* If expect duplicate, make sure it is duplicate. */
1749 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1751 /* Check for duplicate. */
1752 if (t
->X_op
!= O_register
1753 || !is_ir_num (t
->X_add_number
)
1754 || (regno (t
->X_add_number
) !=
1755 regno (tok
[tokidx
].X_add_number
)))
1759 /* Special handling? */
1760 if (operand
->insert
)
1762 const char *errmsg
= NULL
;
1763 (*operand
->insert
)(0,
1764 regno (tok
[tokidx
].X_add_number
),
1768 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1770 /* Missing argument, create one. */
1771 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1774 tok
[tokidx
].X_op
= O_absent
;
1785 case ARC_OPERAND_BRAKET
:
1786 /* Check if bracket is also in opcode table as
1788 if (tok
[tokidx
].X_op
!= O_bracket
)
1792 case ARC_OPERAND_COLON
:
1793 /* Check if colon is also in opcode table as operand. */
1794 if (tok
[tokidx
].X_op
!= O_colon
)
1798 case ARC_OPERAND_LIMM
:
1799 case ARC_OPERAND_SIGNED
:
1800 case ARC_OPERAND_UNSIGNED
:
1801 switch (tok
[tokidx
].X_op
)
1809 /* Got an (too) early bracket, check if it is an
1810 ignored operand. N.B. This procedure works only
1811 when bracket is the last operand! */
1812 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1814 /* Insert the missing operand. */
1815 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1818 tok
[tokidx
].X_op
= O_absent
;
1825 const struct arc_aux_reg
*auxr
;
1827 if (opcode
->insn_class
!= AUXREG
)
1829 p
= S_GET_NAME (tok
[tokidx
].X_add_symbol
);
1831 auxr
= hash_find (arc_aux_hash
, p
);
1834 /* We modify the token array here, safe in the
1835 knowledge, that if this was the wrong
1836 choice then the original contents will be
1837 restored from BKTOK. */
1838 tok
[tokidx
].X_op
= O_constant
;
1839 tok
[tokidx
].X_add_number
= auxr
->address
;
1840 ARC_SET_FLAG (tok
[tokidx
].X_add_symbol
, ARC_FLAG_AUX
);
1843 if (tok
[tokidx
].X_op
!= O_constant
)
1848 /* Check the range. */
1849 if (operand
->bits
!= 32
1850 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1852 offsetT min
, max
, val
;
1853 val
= tok
[tokidx
].X_add_number
;
1855 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1857 max
= (1 << (operand
->bits
- 1)) - 1;
1858 min
= -(1 << (operand
->bits
- 1));
1862 max
= (1 << operand
->bits
) - 1;
1866 if (val
< min
|| val
> max
)
1869 /* Check alignmets. */
1870 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1874 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1878 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1880 if (operand
->insert
)
1882 const char *errmsg
= NULL
;
1883 (*operand
->insert
)(0,
1884 tok
[tokidx
].X_add_number
,
1889 else if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1895 /* Check if it is register range. */
1896 if ((tok
[tokidx
].X_add_number
== 0)
1897 && contains_register (tok
[tokidx
].X_add_symbol
)
1898 && contains_register (tok
[tokidx
].X_op_symbol
))
1902 regs
= get_register (tok
[tokidx
].X_add_symbol
);
1904 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
1905 if (operand
->insert
)
1907 const char *errmsg
= NULL
;
1908 (*operand
->insert
)(0,
1921 if (operand
->default_reloc
== 0)
1922 goto match_failed
; /* The operand needs relocation. */
1924 /* Relocs requiring long immediate. FIXME! make it
1925 generic and move it to a function. */
1926 switch (tok
[tokidx
].X_md
)
1935 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
1939 if (!generic_reloc_p (operand
->default_reloc
))
1947 /* If expect duplicate, make sure it is duplicate. */
1948 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1950 if (t
->X_op
== O_illegal
1951 || t
->X_op
== O_absent
1952 || t
->X_op
== O_register
1953 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
1960 /* Everything else should have been fake. */
1968 /* Setup ready for flag parsing. */
1969 if (!parse_opcode_flags (opcode
, nflgs
, first_pflag
))
1973 /* Possible match -- did we use all of our input? */
1983 /* Restore the original parameters. */
1984 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
1989 *pcpumatch
= got_cpu_match
;
1994 /* Swap operand tokens. */
1997 swap_operand (expressionS
*operand_array
,
1999 unsigned destination
)
2001 expressionS cpy_operand
;
2002 expressionS
*src_operand
;
2003 expressionS
*dst_operand
;
2006 if (source
== destination
)
2009 src_operand
= &operand_array
[source
];
2010 dst_operand
= &operand_array
[destination
];
2011 size
= sizeof (expressionS
);
2013 /* Make copy of operand to swap with and swap. */
2014 memcpy (&cpy_operand
, dst_operand
, size
);
2015 memcpy (dst_operand
, src_operand
, size
);
2016 memcpy (src_operand
, &cpy_operand
, size
);
2019 /* Check if *op matches *tok type.
2020 Returns FALSE if they don't match, TRUE if they match. */
2023 pseudo_operand_match (const expressionS
*tok
,
2024 const struct arc_operand_operation
*op
)
2026 offsetT min
, max
, val
;
2028 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
2034 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
2036 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
2038 val
= tok
->X_add_number
+ op
->count
;
2039 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
2041 max
= (1 << (operand_real
->bits
- 1)) - 1;
2042 min
= -(1 << (operand_real
->bits
- 1));
2046 max
= (1 << operand_real
->bits
) - 1;
2049 if (min
<= val
&& val
<= max
)
2055 /* Handle all symbols as long immediates or signed 9. */
2056 if (operand_real
->flags
& ARC_OPERAND_LIMM
2057 || ((operand_real
->flags
& ARC_OPERAND_SIGNED
)
2058 && operand_real
->bits
== 9))
2063 if (operand_real
->flags
& ARC_OPERAND_IR
)
2068 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2079 /* Find pseudo instruction in array. */
2081 static const struct arc_pseudo_insn
*
2082 find_pseudo_insn (const char *opname
,
2084 const expressionS
*tok
)
2086 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2087 const struct arc_operand_operation
*op
;
2091 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
2093 pseudo_insn
= &arc_pseudo_insns
[i
];
2094 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
2096 op
= pseudo_insn
->operand
;
2097 for (j
= 0; j
< ntok
; ++j
)
2098 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
2101 /* Found the right instruction. */
2109 /* Assumes the expressionS *tok is of sufficient size. */
2111 static const struct arc_opcode_hash_entry
*
2112 find_special_case_pseudo (const char *opname
,
2116 struct arc_flags
*pflags
)
2118 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2119 const struct arc_operand_operation
*operand_pseudo
;
2120 const struct arc_operand
*operand_real
;
2122 char construct_operand
[MAX_CONSTR_STR
];
2124 /* Find whether opname is in pseudo instruction array. */
2125 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
2127 if (pseudo_insn
== NULL
)
2130 /* Handle flag, Limited to one flag at the moment. */
2131 if (pseudo_insn
->flag_r
!= NULL
)
2132 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
2133 MAX_INSN_FLGS
- *nflgs
);
2135 /* Handle operand operations. */
2136 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2138 operand_pseudo
= &pseudo_insn
->operand
[i
];
2139 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
2141 if (operand_real
->flags
& ARC_OPERAND_BRAKET
2142 && !operand_pseudo
->needs_insert
)
2145 /* Has to be inserted (i.e. this token does not exist yet). */
2146 if (operand_pseudo
->needs_insert
)
2148 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2150 tok
[i
].X_op
= O_bracket
;
2155 /* Check if operand is a register or constant and handle it
2157 if (operand_real
->flags
& ARC_OPERAND_IR
)
2158 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
2159 operand_pseudo
->count
);
2161 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
2162 operand_pseudo
->count
);
2164 tokenize_arguments (construct_operand
, &tok
[i
], 1);
2168 else if (operand_pseudo
->count
)
2170 /* Operand number has to be adjusted accordingly (by operand
2172 switch (tok
[i
].X_op
)
2175 tok
[i
].X_add_number
+= operand_pseudo
->count
;
2188 /* Swap operands if necessary. Only supports one swap at the
2190 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2192 operand_pseudo
= &pseudo_insn
->operand
[i
];
2194 if (operand_pseudo
->swap_operand_idx
== i
)
2197 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
2199 /* Prevent a swap back later by breaking out. */
2203 return arc_find_opcode (pseudo_insn
->mnemonic_r
);
2206 static const struct arc_opcode_hash_entry
*
2207 find_special_case_flag (const char *opname
,
2209 struct arc_flags
*pflags
)
2213 unsigned flag_idx
, flag_arr_idx
;
2214 size_t flaglen
, oplen
;
2215 const struct arc_flag_special
*arc_flag_special_opcode
;
2216 const struct arc_opcode_hash_entry
*entry
;
2218 /* Search for special case instruction. */
2219 for (i
= 0; i
< arc_num_flag_special
; i
++)
2221 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
2222 oplen
= strlen (arc_flag_special_opcode
->name
);
2224 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
2227 /* Found a potential special case instruction, now test for
2229 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
2231 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
2233 break; /* End of array, nothing found. */
2235 flagnm
= arc_flag_operands
[flag_idx
].name
;
2236 flaglen
= strlen (flagnm
);
2237 if (strcmp (opname
+ oplen
, flagnm
) == 0)
2239 entry
= arc_find_opcode (arc_flag_special_opcode
->name
);
2241 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
2243 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
2244 pflags
[*nflgs
].name
[flaglen
] = '\0';
2253 /* Used to find special case opcode. */
2255 static const struct arc_opcode_hash_entry
*
2256 find_special_case (const char *opname
,
2258 struct arc_flags
*pflags
,
2262 const struct arc_opcode_hash_entry
*entry
;
2264 entry
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
2267 entry
= find_special_case_flag (opname
, nflgs
, pflags
);
2272 /* Given an opcode name, pre-tockenized set of argumenst and the
2273 opcode flags, take it all the way through emission. */
2276 assemble_tokens (const char *opname
,
2279 struct arc_flags
*pflags
,
2282 bfd_boolean found_something
= FALSE
;
2283 const struct arc_opcode_hash_entry
*entry
;
2286 /* Search opcodes. */
2287 entry
= arc_find_opcode (opname
);
2289 /* Couldn't find opcode conventional way, try special cases. */
2291 entry
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
2295 const struct arc_opcode
*opcode
;
2297 pr_debug ("%s:%d: assemble_tokens: %s\n",
2298 frag_now
->fr_file
, frag_now
->fr_line
, opname
);
2299 found_something
= TRUE
;
2300 opcode
= find_opcode_match (entry
, tok
, &ntok
, pflags
,
2304 struct arc_insn insn
;
2306 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
2312 if (found_something
)
2315 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
2317 as_bad (_("opcode '%s' not supported for target %s"), opname
,
2321 as_bad (_("unknown opcode '%s'"), opname
);
2324 /* The public interface to the instruction assembler. */
2327 md_assemble (char *str
)
2330 expressionS tok
[MAX_INSN_ARGS
];
2333 struct arc_flags flags
[MAX_INSN_FLGS
];
2335 /* Split off the opcode. */
2336 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
2337 opname
= xmemdup0 (str
, opnamelen
);
2339 /* Signalize we are assmbling the instructions. */
2340 assembling_insn
= TRUE
;
2342 /* Tokenize the flags. */
2343 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2345 as_bad (_("syntax error"));
2349 /* Scan up to the end of the mnemonic which must end in space or end
2352 for (; *str
!= '\0'; str
++)
2356 /* Tokenize the rest of the line. */
2357 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2359 as_bad (_("syntax error"));
2363 /* Finish it off. */
2364 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2365 assembling_insn
= FALSE
;
2368 /* Callback to insert a register into the hash table. */
2371 declare_register (const char *name
, int number
)
2374 symbolS
*regS
= symbol_create (name
, reg_section
,
2375 number
, &zero_address_frag
);
2377 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
2379 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2383 /* Construct symbols for each of the general registers. */
2386 declare_register_set (void)
2389 for (i
= 0; i
< 64; ++i
)
2393 sprintf (name
, "r%d", i
);
2394 declare_register (name
, i
);
2395 if ((i
& 0x01) == 0)
2397 sprintf (name
, "r%dr%d", i
, i
+1);
2398 declare_register (name
, i
);
2403 /* Construct a symbol for an address type. */
2406 declare_addrtype (const char *name
, int number
)
2409 symbolS
*addrtypeS
= symbol_create (name
, undefined_section
,
2410 number
, &zero_address_frag
);
2412 err
= hash_insert (arc_addrtype_hash
, S_GET_NAME (addrtypeS
),
2413 (void *) addrtypeS
);
2415 as_fatal (_("Inserting \"%s\" into address type table failed: %s"),
2419 /* Port-specific assembler initialization. This function is called
2420 once, at assembler startup time. */
2425 const struct arc_opcode
*opcode
= arc_opcodes
;
2427 if (mach_selection_mode
== MACH_SELECTION_NONE
)
2428 arc_select_cpu (TARGET_WITH_CPU
, MACH_SELECTION_FROM_DEFAULT
);
2430 /* The endianness can be chosen "at the factory". */
2431 target_big_endian
= byte_order
== BIG_ENDIAN
;
2433 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, selected_cpu
.mach
))
2434 as_warn (_("could not set architecture and machine"));
2436 /* Set elf header flags. */
2437 bfd_set_private_flags (stdoutput
, selected_cpu
.eflags
);
2439 /* Set up a hash table for the instructions. */
2440 arc_opcode_hash
= hash_new ();
2441 if (arc_opcode_hash
== NULL
)
2442 as_fatal (_("Virtual memory exhausted"));
2444 /* Initialize the hash table with the insns. */
2447 const char *name
= opcode
->name
;
2449 arc_insert_opcode (opcode
);
2451 while (++opcode
&& opcode
->name
2452 && (opcode
->name
== name
2453 || !strcmp (opcode
->name
, name
)))
2455 }while (opcode
->name
);
2457 /* Register declaration. */
2458 arc_reg_hash
= hash_new ();
2459 if (arc_reg_hash
== NULL
)
2460 as_fatal (_("Virtual memory exhausted"));
2462 declare_register_set ();
2463 declare_register ("gp", 26);
2464 declare_register ("fp", 27);
2465 declare_register ("sp", 28);
2466 declare_register ("ilink", 29);
2467 declare_register ("ilink1", 29);
2468 declare_register ("ilink2", 30);
2469 declare_register ("blink", 31);
2471 /* XY memory registers. */
2472 declare_register ("x0_u0", 32);
2473 declare_register ("x0_u1", 33);
2474 declare_register ("x1_u0", 34);
2475 declare_register ("x1_u1", 35);
2476 declare_register ("x2_u0", 36);
2477 declare_register ("x2_u1", 37);
2478 declare_register ("x3_u0", 38);
2479 declare_register ("x3_u1", 39);
2480 declare_register ("y0_u0", 40);
2481 declare_register ("y0_u1", 41);
2482 declare_register ("y1_u0", 42);
2483 declare_register ("y1_u1", 43);
2484 declare_register ("y2_u0", 44);
2485 declare_register ("y2_u1", 45);
2486 declare_register ("y3_u0", 46);
2487 declare_register ("y3_u1", 47);
2488 declare_register ("x0_nu", 48);
2489 declare_register ("x1_nu", 49);
2490 declare_register ("x2_nu", 50);
2491 declare_register ("x3_nu", 51);
2492 declare_register ("y0_nu", 52);
2493 declare_register ("y1_nu", 53);
2494 declare_register ("y2_nu", 54);
2495 declare_register ("y3_nu", 55);
2497 declare_register ("mlo", 57);
2498 declare_register ("mmid", 58);
2499 declare_register ("mhi", 59);
2501 declare_register ("acc1", 56);
2502 declare_register ("acc2", 57);
2504 declare_register ("lp_count", 60);
2505 declare_register ("pcl", 63);
2507 /* Initialize the last instructions. */
2508 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2510 /* Aux register declaration. */
2511 arc_aux_hash
= hash_new ();
2512 if (arc_aux_hash
== NULL
)
2513 as_fatal (_("Virtual memory exhausted"));
2515 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
2517 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
2521 if (!(auxr
->cpu
& selected_cpu
.flags
))
2524 if ((auxr
->subclass
!= NONE
)
2525 && !check_cpu_feature (auxr
->subclass
))
2528 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
2530 as_fatal (_("internal error: can't hash aux register '%s': %s"),
2531 auxr
->name
, retval
);
2534 /* Address type declaration. */
2535 arc_addrtype_hash
= hash_new ();
2536 if (arc_addrtype_hash
== NULL
)
2537 as_fatal (_("Virtual memory exhausted"));
2539 declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD
);
2540 declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID
);
2541 declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD
);
2542 declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD
);
2543 declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD
);
2544 declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM
);
2545 declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA
);
2546 declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD
);
2547 declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD
);
2548 declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD
);
2549 declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID
);
2550 declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD
);
2551 declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM
);
2552 declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD
);
2553 declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA
);
2554 declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD
);
2557 /* Write a value out to the object file, using the appropriate
2561 md_number_to_chars (char *buf
,
2565 if (target_big_endian
)
2566 number_to_chars_bigendian (buf
, val
, n
);
2568 number_to_chars_littleendian (buf
, val
, n
);
2571 /* Round up a section size to the appropriate boundary. */
2574 md_section_align (segT segment
,
2577 int align
= bfd_get_section_alignment (stdoutput
, segment
);
2579 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2582 /* The location from which a PC relative jump should be calculated,
2583 given a PC relative reloc. */
2586 md_pcrel_from_section (fixS
*fixP
,
2589 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2591 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2593 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2594 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2595 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2597 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2599 /* The symbol is undefined (or is defined but not in this section).
2600 Let the linker figure it out. */
2604 if ((int) fixP
->fx_r_type
< 0)
2606 /* These are the "internal" relocations. Align them to
2607 32 bit boundary (PCL), for the moment. */
2612 switch (fixP
->fx_r_type
)
2614 case BFD_RELOC_ARC_PC32
:
2615 /* The hardware calculates relative to the start of the
2616 insn, but this relocation is relative to location of the
2617 LIMM, compensate. The base always needs to be
2618 substracted by 4 as we do not support this type of PCrel
2619 relocation for short instructions. */
2622 case BFD_RELOC_ARC_PLT32
:
2623 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2624 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2625 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2626 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2628 case BFD_RELOC_ARC_S21H_PCREL
:
2629 case BFD_RELOC_ARC_S25H_PCREL
:
2630 case BFD_RELOC_ARC_S13_PCREL
:
2631 case BFD_RELOC_ARC_S21W_PCREL
:
2632 case BFD_RELOC_ARC_S25W_PCREL
:
2636 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2637 _("unhandled reloc %s in md_pcrel_from_section"),
2638 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2643 pr_debug ("pcrel from %"BFD_VMA_FMT
"x + %lx = %"BFD_VMA_FMT
"x, "
2644 "symbol: %s (%"BFD_VMA_FMT
"x)\n",
2645 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
2646 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2647 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
2652 /* Given a BFD relocation find the coresponding operand. */
2654 static const struct arc_operand
*
2655 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2659 for (i
= 0; i
< arc_num_operands
; i
++)
2660 if (arc_operands
[i
].default_reloc
== reloc
)
2661 return &arc_operands
[i
];
2665 /* Insert an operand value into an instruction. */
2667 static unsigned long long
2668 insert_operand (unsigned long long insn
,
2669 const struct arc_operand
*operand
,
2674 offsetT min
= 0, max
= 0;
2676 if (operand
->bits
!= 32
2677 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2678 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2680 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2682 max
= (1 << (operand
->bits
- 1)) - 1;
2683 min
= -(1 << (operand
->bits
- 1));
2687 max
= (1 << operand
->bits
) - 1;
2691 if (val
< min
|| val
> max
)
2692 as_bad_value_out_of_range (_("operand"),
2693 val
, min
, max
, file
, line
);
2696 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08llx\n",
2697 min
, val
, max
, insn
);
2699 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2701 as_bad_where (file
, line
,
2702 _("Unaligned operand. Needs to be 32bit aligned"));
2704 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2706 as_bad_where (file
, line
,
2707 _("Unaligned operand. Needs to be 16bit aligned"));
2709 if (operand
->insert
)
2711 const char *errmsg
= NULL
;
2713 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2715 as_warn_where (file
, line
, "%s", errmsg
);
2719 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2721 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2723 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2726 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2731 /* Apply a fixup to the object code. At this point all symbol values
2732 should be fully resolved, and we attempt to completely resolve the
2733 reloc. If we can not do that, we determine the correct reloc code
2734 and put it back in the fixup. To indicate that a fixup has been
2735 eliminated, set fixP->fx_done. */
2738 md_apply_fix (fixS
*fixP
,
2742 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2743 valueT value
= *valP
;
2745 symbolS
*fx_addsy
, *fx_subsy
;
2747 segT add_symbol_segment
= absolute_section
;
2748 segT sub_symbol_segment
= absolute_section
;
2749 const struct arc_operand
*operand
= NULL
;
2750 extended_bfd_reloc_code_real_type reloc
;
2752 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2753 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2754 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2755 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2758 fx_addsy
= fixP
->fx_addsy
;
2759 fx_subsy
= fixP
->fx_subsy
;
2764 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2768 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2769 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2770 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2772 resolve_symbol_value (fx_subsy
);
2773 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2775 if (sub_symbol_segment
== absolute_section
)
2777 /* The symbol is really a constant. */
2778 fx_offset
-= S_GET_VALUE (fx_subsy
);
2783 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2784 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2785 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
2786 segment_name (add_symbol_segment
),
2787 S_GET_NAME (fx_subsy
),
2788 segment_name (sub_symbol_segment
));
2794 && !S_IS_WEAK (fx_addsy
))
2796 if (add_symbol_segment
== seg
2799 value
+= S_GET_VALUE (fx_addsy
);
2800 value
-= md_pcrel_from_section (fixP
, seg
);
2802 fixP
->fx_pcrel
= FALSE
;
2804 else if (add_symbol_segment
== absolute_section
)
2806 value
= fixP
->fx_offset
;
2807 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2809 fixP
->fx_pcrel
= FALSE
;
2814 fixP
->fx_done
= TRUE
;
2819 && ((S_IS_DEFINED (fx_addsy
)
2820 && S_GET_SEGMENT (fx_addsy
) != seg
)
2821 || S_IS_WEAK (fx_addsy
)))
2822 value
+= md_pcrel_from_section (fixP
, seg
);
2824 switch (fixP
->fx_r_type
)
2826 case BFD_RELOC_ARC_32_ME
:
2827 /* This is a pc-relative value in a LIMM. Adjust it to the
2828 address of the instruction not to the address of the
2829 LIMM. Note: it is not anylonger valid this afirmation as
2830 the linker consider ARC_PC32 a fixup to entire 64 bit
2832 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
2835 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
2837 case BFD_RELOC_ARC_PC32
:
2838 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2841 if ((int) fixP
->fx_r_type
< 0)
2842 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2848 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2849 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2850 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2851 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2855 /* Now check for TLS relocations. */
2856 reloc
= fixP
->fx_r_type
;
2859 case BFD_RELOC_ARC_TLS_DTPOFF
:
2860 case BFD_RELOC_ARC_TLS_LE_32
:
2864 case BFD_RELOC_ARC_TLS_GD_GOT
:
2865 case BFD_RELOC_ARC_TLS_IE_GOT
:
2866 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2869 case BFD_RELOC_ARC_TLS_GD_LD
:
2870 gas_assert (!fixP
->fx_offset
);
2873 = (S_GET_VALUE (fixP
->fx_subsy
)
2874 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
2875 fixP
->fx_subsy
= NULL
;
2877 case BFD_RELOC_ARC_TLS_GD_CALL
:
2878 /* These two relocs are there just to allow ld to change the tls
2879 model for this symbol, by patching the code. The offset -
2880 and scale, if any - will be installed by the linker. */
2881 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2884 case BFD_RELOC_ARC_TLS_LE_S9
:
2885 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
2886 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2898 /* Addjust the value if we have a constant. */
2901 /* For hosts with longs bigger than 32-bits make sure that the top
2902 bits of a 32-bit negative value read in by the parser are set,
2903 so that the correct comparisons are made. */
2904 if (value
& 0x80000000)
2905 value
|= (-1UL << 31);
2907 reloc
= fixP
->fx_r_type
;
2915 case BFD_RELOC_ARC_32_PCREL
:
2916 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
2919 case BFD_RELOC_ARC_GOTPC32
:
2920 /* I cannot fix an GOTPC relocation because I need to relax it
2921 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2922 as_bad (_("Unsupported operation on reloc"));
2925 case BFD_RELOC_ARC_TLS_DTPOFF
:
2926 case BFD_RELOC_ARC_TLS_LE_32
:
2927 gas_assert (!fixP
->fx_addsy
);
2928 gas_assert (!fixP
->fx_subsy
);
2931 case BFD_RELOC_ARC_GOTOFF
:
2932 case BFD_RELOC_ARC_32_ME
:
2933 case BFD_RELOC_ARC_PC32
:
2934 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2937 case BFD_RELOC_ARC_PLT32
:
2938 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2941 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2942 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2945 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2946 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
2949 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2950 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2953 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2954 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
2957 case BFD_RELOC_ARC_S25W_PCREL
:
2958 case BFD_RELOC_ARC_S21W_PCREL
:
2959 case BFD_RELOC_ARC_S21H_PCREL
:
2960 case BFD_RELOC_ARC_S25H_PCREL
:
2961 case BFD_RELOC_ARC_S13_PCREL
:
2963 operand
= find_operand_for_reloc (reloc
);
2964 gas_assert (operand
);
2969 if ((int) fixP
->fx_r_type
>= 0)
2970 as_fatal (_("unhandled relocation type %s"),
2971 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2973 /* The rest of these fixups needs to be completely resolved as
2975 if (fixP
->fx_addsy
!= 0
2976 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
2977 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2978 _("non-absolute expression in constant field"));
2980 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
2981 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
2986 if (target_big_endian
)
2988 switch (fixP
->fx_size
)
2991 insn
= bfd_getb32 (fixpos
);
2994 insn
= bfd_getb16 (fixpos
);
2997 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2998 _("unknown fixup size"));
3004 switch (fixP
->fx_size
)
3007 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
3010 insn
= bfd_getl16 (fixpos
);
3013 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3014 _("unknown fixup size"));
3018 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
3019 fixP
->fx_file
, fixP
->fx_line
);
3021 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
3024 /* Prepare machine-dependent frags for relaxation.
3026 Called just before relaxation starts. Any symbol that is now undefined
3027 will not become defined.
3029 Return the correct fr_subtype in the frag.
3031 Return the initial "guess for fr_var" to caller. The guess for fr_var
3032 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3033 or fr_var contributes to our returned value.
3035 Although it may not be explicit in the frag, pretend
3036 fr_var starts with a value. */
3039 md_estimate_size_before_relax (fragS
*fragP
,
3044 /* If the symbol is not located within the same section AND it's not
3045 an absolute section, use the maximum. OR if the symbol is a
3046 constant AND the insn is by nature not pc-rel, use the maximum.
3047 OR if the symbol is being equated against another symbol, use the
3048 maximum. OR if the symbol is weak use the maximum. */
3049 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
3050 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
3051 || (symbol_constant_p (fragP
->fr_symbol
)
3052 && !fragP
->tc_frag_data
.pcrel
)
3053 || symbol_equated_p (fragP
->fr_symbol
)
3054 || S_IS_WEAK (fragP
->fr_symbol
))
3056 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
3057 ++fragP
->fr_subtype
;
3060 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3061 fragP
->fr_var
= growth
;
3063 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3064 fragP
->fr_file
, fragP
->fr_line
, growth
);
3069 /* Translate internal representation of relocation info to BFD target
3073 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
3077 bfd_reloc_code_real_type code
;
3079 reloc
= XNEW (arelent
);
3080 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3081 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3082 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3084 /* Make sure none of our internal relocations make it this far.
3085 They'd better have been fully resolved by this point. */
3086 gas_assert ((int) fixP
->fx_r_type
> 0);
3088 code
= fixP
->fx_r_type
;
3090 /* if we have something like add gp, pcl,
3091 _GLOBAL_OFFSET_TABLE_@gotpc. */
3092 if (code
== BFD_RELOC_ARC_GOTPC32
3094 && fixP
->fx_addsy
== GOT_symbol
)
3095 code
= BFD_RELOC_ARC_GOTPC
;
3097 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
3098 if (reloc
->howto
== NULL
)
3100 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3101 _("cannot represent `%s' relocation in object file"),
3102 bfd_get_reloc_code_name (code
));
3106 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
3107 as_fatal (_("internal error? cannot generate `%s' relocation"),
3108 bfd_get_reloc_code_name (code
));
3110 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
3112 reloc
->addend
= fixP
->fx_offset
;
3117 /* Perform post-processing of machine-dependent frags after relaxation.
3118 Called after relaxation is finished.
3119 In: Address of frag.
3120 fr_type == rs_machine_dependent.
3121 fr_subtype is what the address relaxed to.
3123 Out: Any fixS:s and constants are set up. */
3126 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
3127 segT segment ATTRIBUTE_UNUSED
,
3130 const relax_typeS
*table_entry
;
3132 const struct arc_opcode
*opcode
;
3133 struct arc_insn insn
;
3135 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
3137 fix
= (fragP
->fr_fix
< 0 ? 0 : fragP
->fr_fix
);
3138 dest
= fragP
->fr_literal
+ fix
;
3139 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
3141 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3142 "var: %"BFD_VMA_FMT
"d\n",
3143 fragP
->fr_file
, fragP
->fr_line
,
3144 fragP
->fr_subtype
, fix
, fragP
->fr_var
);
3146 if (fragP
->fr_subtype
<= 0
3147 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
3148 as_fatal (_("no relaxation found for this instruction."));
3150 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
3152 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
3153 relax_arg
->nflg
, &insn
);
3155 apply_fixups (&insn
, fragP
, fix
);
3157 size
= insn
.len
+ (insn
.has_limm
? 4 : 0);
3158 gas_assert (table_entry
->rlx_length
== size
);
3159 emit_insn0 (&insn
, dest
, TRUE
);
3161 fragP
->fr_fix
+= table_entry
->rlx_length
;
3165 /* We have no need to default values of symbols. We could catch
3166 register names here, but that is handled by inserting them all in
3167 the symbol table to begin with. */
3170 md_undefined_symbol (char *name
)
3172 /* The arc abi demands that a GOT[0] should be referencible as
3173 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3174 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3176 && (*(name
+1) == 'G')
3177 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0))
3179 && (*(name
+1) == 'D')
3180 && (strcmp (name
, DYNAMIC_STRUCT_NAME
) == 0)))
3184 if (symbol_find (name
))
3185 as_bad ("GOT already in symbol table");
3187 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
3188 (valueT
) 0, &zero_address_frag
);
3195 /* Turn a string in input_line_pointer into a floating point constant
3196 of type type, and store the appropriate bytes in *litP. The number
3197 of LITTLENUMS emitted is stored in *sizeP. An error message is
3198 returned, or NULL on OK. */
3201 md_atof (int type
, char *litP
, int *sizeP
)
3203 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
3206 /* Called for any expression that can not be recognized. When the
3207 function is called, `input_line_pointer' will point to the start of
3211 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
3213 char *p
= input_line_pointer
;
3216 input_line_pointer
++;
3217 expressionP
->X_op
= O_symbol
;
3218 expression (expressionP
);
3222 /* This function is called from the function 'expression', it attempts
3223 to parse special names (in our case register names). It fills in
3224 the expression with the identified register. It returns TRUE if
3225 it is a register and FALSE otherwise. */
3228 arc_parse_name (const char *name
,
3229 struct expressionS
*e
)
3233 if (!assembling_insn
)
3236 if (e
->X_op
== O_symbol
)
3239 sym
= hash_find (arc_reg_hash
, name
);
3242 e
->X_op
= O_register
;
3243 e
->X_add_number
= S_GET_VALUE (sym
);
3247 sym
= hash_find (arc_addrtype_hash
, name
);
3250 e
->X_op
= O_addrtype
;
3251 e
->X_add_number
= S_GET_VALUE (sym
);
3259 Invocation line includes a switch not recognized by the base assembler.
3260 See if it's a processor-specific option.
3262 New options (supported) are:
3264 -mcpu=<cpu name> Assemble for selected processor
3265 -EB/-mbig-endian Big-endian
3266 -EL/-mlittle-endian Little-endian
3267 -mrelax Enable relaxation
3269 The following CPU names are recognized:
3270 arc600, arc700, arcem, archs, nps400. */
3273 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
3279 return md_parse_option (OPTION_MCPU
, "arc600");
3282 return md_parse_option (OPTION_MCPU
, "arc700");
3285 return md_parse_option (OPTION_MCPU
, "arcem");
3288 return md_parse_option (OPTION_MCPU
, "archs");
3292 arc_select_cpu (arg
, MACH_SELECTION_FROM_COMMAND_LINE
);
3297 arc_target_format
= "elf32-bigarc";
3298 byte_order
= BIG_ENDIAN
;
3302 arc_target_format
= "elf32-littlearc";
3303 byte_order
= LITTLE_ENDIAN
;
3307 /* This option has an effect only on ARC EM. */
3308 if (selected_cpu
.flags
& ARC_OPCODE_ARCv2EM
)
3309 selected_cpu
.features
|= ARC_CD
;
3311 as_warn (_("Code density option invalid for selected CPU"));
3315 relaxation_state
= 1;
3319 selected_cpu
.features
|= ARC_NPS400
;
3323 selected_cpu
.features
|= ARC_SPFP
;
3327 selected_cpu
.features
|= ARC_DPFP
;
3331 /* This option has an effect only on ARC EM. */
3332 if (selected_cpu
.flags
& ARC_OPCODE_ARCv2EM
)
3333 selected_cpu
.features
|= ARC_FPUDA
;
3335 as_warn (_("FPUDA invalid for selected CPU"));
3338 /* Dummy options are accepted but have no effect. */
3339 case OPTION_USER_MODE
:
3340 case OPTION_LD_EXT_MASK
:
3343 case OPTION_BARREL_SHIFT
:
3344 case OPTION_MIN_MAX
:
3349 case OPTION_XMAC_D16
:
3350 case OPTION_XMAC_24
:
3351 case OPTION_DSP_PACKA
:
3354 case OPTION_TELEPHONY
:
3355 case OPTION_XYMEMORY
:
3369 md_show_usage (FILE *stream
)
3371 fprintf (stream
, _("ARC-specific assembler options:\n"));
3373 fprintf (stream
, " -mcpu=<cpu name>\t assemble for CPU <cpu name> "
3374 "(default: %s)\n", TARGET_WITH_CPU
);
3375 fprintf (stream
, " -mcpu=nps400\t\t same as -mcpu=arc700 -mnps400\n");
3376 fprintf (stream
, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3377 fprintf (stream
, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3378 fprintf (stream
, " -mEM\t\t\t same as -mcpu=arcem\n");
3379 fprintf (stream
, " -mHS\t\t\t same as -mcpu=archs\n");
3381 fprintf (stream
, " -mnps400\t\t enable NPS-400 extended instructions\n");
3382 fprintf (stream
, " -mspfp\t\t enable single-precision floating point instructions\n");
3383 fprintf (stream
, " -mdpfp\t\t enable double-precision floating point instructions\n");
3384 fprintf (stream
, " -mfpuda\t\t enable double-precision assist floating "
3385 "point\n\t\t\t instructions for ARC EM\n");
3388 " -mcode-density\t enable code density option for ARC EM\n");
3390 fprintf (stream
, _("\
3391 -EB assemble code for a big-endian cpu\n"));
3392 fprintf (stream
, _("\
3393 -EL assemble code for a little-endian cpu\n"));
3394 fprintf (stream
, _("\
3395 -mrelax enable relaxation\n"));
3397 fprintf (stream
, _("The following ARC-specific assembler options are "
3398 "deprecated and are accepted\nfor compatibility only:\n"));
3400 fprintf (stream
, _(" -mEA\n"
3401 " -mbarrel-shifter\n"
3402 " -mbarrel_shifter\n"
3407 " -mld-extension-reg-mask\n"
3423 " -muser-mode-only\n"
3427 /* Find the proper relocation for the given opcode. */
3429 static extended_bfd_reloc_code_real_type
3430 find_reloc (const char *name
,
3431 const char *opcodename
,
3432 const struct arc_flags
*pflags
,
3434 extended_bfd_reloc_code_real_type reloc
)
3438 bfd_boolean found_flag
, tmp
;
3439 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
3441 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
3443 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3445 /* Find the entry. */
3446 if (strcmp (name
, r
->name
))
3448 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3455 unsigned * psflg
= (unsigned *)r
->flags
;
3459 for (j
= 0; j
< nflg
; j
++)
3460 if (!strcmp (pflags
[j
].name
,
3461 arc_flag_operands
[*psflg
].name
))
3482 if (reloc
!= r
->oldreloc
)
3489 if (ret
== BFD_RELOC_UNUSED
)
3490 as_bad (_("Unable to find %s relocation for instruction %s"),
3495 /* All the symbol types that are allowed to be used for
3499 may_relax_expr (expressionS tok
)
3501 /* Check if we have unrelaxable relocs. */
3526 /* Checks if flags are in line with relaxable insn. */
3529 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3530 const struct arc_flags
*pflags
,
3533 unsigned flag_class
,
3538 const struct arc_flag_operand
*flag_opand
;
3539 int i
, counttrue
= 0;
3541 /* Iterate through flags classes. */
3542 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3544 /* Iterate through flags in flag class. */
3545 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3548 flag_opand
= &arc_flag_operands
[flag
];
3549 /* Iterate through flags in ins to compare. */
3550 for (i
= 0; i
< nflgs
; ++i
)
3552 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3563 /* If counttrue == nflgs, then all flags have been found. */
3564 return (counttrue
== nflgs
? TRUE
: FALSE
);
3567 /* Checks if operands are in line with relaxable insn. */
3570 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3571 const expressionS
*tok
,
3574 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3577 while (*operand
!= EMPTY
)
3579 const expressionS
*epr
= &tok
[i
];
3581 if (i
!= 0 && i
>= ntok
)
3587 if (!(epr
->X_op
== O_multiply
3588 || epr
->X_op
== O_divide
3589 || epr
->X_op
== O_modulus
3590 || epr
->X_op
== O_add
3591 || epr
->X_op
== O_subtract
3592 || epr
->X_op
== O_symbol
))
3598 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3602 if (epr
->X_op
!= O_register
)
3607 if (epr
->X_op
!= O_register
)
3610 switch (epr
->X_add_number
)
3612 case 0: case 1: case 2: case 3:
3613 case 12: case 13: case 14: case 15:
3620 case REGISTER_NO_GP
:
3621 if ((epr
->X_op
!= O_register
)
3622 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3627 if (epr
->X_op
!= O_bracket
)
3632 /* Don't understand, bail out. */
3638 operand
= &ins
->operands
[i
];
3641 return (i
== ntok
? TRUE
: FALSE
);
3644 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3647 relax_insn_p (const struct arc_opcode
*opcode
,
3648 const expressionS
*tok
,
3650 const struct arc_flags
*pflags
,
3654 bfd_boolean rv
= FALSE
;
3656 /* Check the relaxation table. */
3657 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3659 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3661 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3662 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3663 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3664 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3667 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3668 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3669 sizeof (expressionS
) * ntok
);
3670 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3671 sizeof (struct arc_flags
) * nflg
);
3672 frag_now
->tc_frag_data
.nflg
= nflg
;
3673 frag_now
->tc_frag_data
.ntok
= ntok
;
3681 /* Turn an opcode description and a set of arguments into
3682 an instruction and a fixup. */
3685 assemble_insn (const struct arc_opcode
*opcode
,
3686 const expressionS
*tok
,
3688 const struct arc_flags
*pflags
,
3690 struct arc_insn
*insn
)
3692 const expressionS
*reloc_exp
= NULL
;
3693 unsigned long long image
;
3694 const unsigned char *argidx
;
3697 unsigned char pcrel
= 0;
3698 bfd_boolean needGOTSymbol
;
3699 bfd_boolean has_delay_slot
= FALSE
;
3700 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3702 memset (insn
, 0, sizeof (*insn
));
3703 image
= opcode
->opcode
;
3705 pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
3706 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3709 /* Handle operands. */
3710 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3712 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3713 const expressionS
*t
= (const expressionS
*) 0;
3715 if (ARC_OPERAND_IS_FAKE (operand
))
3718 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3720 /* Duplicate operand, already inserted. */
3732 /* Regardless if we have a reloc or not mark the instruction
3733 limm if it is the case. */
3734 if (operand
->flags
& ARC_OPERAND_LIMM
)
3735 insn
->has_limm
= TRUE
;
3740 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3745 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3747 if (operand
->flags
& ARC_OPERAND_LIMM
)
3748 insn
->limm
= t
->X_add_number
;
3754 /* Ignore brackets, colons, and address types. */
3758 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3762 /* Maybe register range. */
3763 if ((t
->X_add_number
== 0)
3764 && contains_register (t
->X_add_symbol
)
3765 && contains_register (t
->X_op_symbol
))
3769 regs
= get_register (t
->X_add_symbol
);
3771 regs
|= get_register (t
->X_op_symbol
);
3772 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3778 /* This operand needs a relocation. */
3779 needGOTSymbol
= FALSE
;
3784 if (opcode
->insn_class
== JUMP
)
3785 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3786 _("Unable to use @plt relocatio for insn %s"),
3788 needGOTSymbol
= TRUE
;
3789 reloc
= find_reloc ("plt", opcode
->name
,
3791 operand
->default_reloc
);
3796 needGOTSymbol
= TRUE
;
3797 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3800 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3801 if (arc_opcode_len (opcode
) == 2
3802 || opcode
->insn_class
== JUMP
)
3803 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3804 _("Unable to use @pcl relocation for insn %s"),
3808 reloc
= find_reloc ("sda", opcode
->name
,
3810 operand
->default_reloc
);
3814 needGOTSymbol
= TRUE
;
3819 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3822 case O_tpoff9
: /*FIXME! Check for the conditionality of
3824 case O_dtpoff9
: /*FIXME! Check for the conditionality of
3826 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3830 /* Just consider the default relocation. */
3831 reloc
= operand
->default_reloc
;
3835 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
3836 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
3843 /* sanity checks. */
3844 reloc_howto_type
*reloc_howto
3845 = bfd_reloc_type_lookup (stdoutput
,
3846 (bfd_reloc_code_real_type
) reloc
);
3847 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
3848 if (reloc_howto
->rightshift
)
3849 reloc_bitsize
-= reloc_howto
->rightshift
;
3850 if (reloc_bitsize
!= operand
->bits
)
3852 as_bad (_("invalid relocation %s for field"),
3853 bfd_get_reloc_code_name (reloc
));
3858 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3859 as_fatal (_("too many fixups"));
3861 struct arc_fixup
*fixup
;
3862 fixup
= &insn
->fixups
[insn
->nfixups
++];
3864 fixup
->reloc
= reloc
;
3865 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
3866 fixup
->pcrel
= pcrel
;
3867 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
3874 for (i
= 0; i
< nflg
; i
++)
3876 const struct arc_flag_operand
*flg_operand
= pflags
[i
].flgp
;
3878 /* Check if the instruction has a delay slot. */
3879 if (!strcmp (flg_operand
->name
, "d"))
3880 has_delay_slot
= TRUE
;
3882 /* There is an exceptional case when we cannot insert a flag
3883 just as it is. The .T flag must be handled in relation with
3884 the relative address. */
3885 if (!strcmp (flg_operand
->name
, "t")
3886 || !strcmp (flg_operand
->name
, "nt"))
3888 unsigned bitYoperand
= 0;
3889 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3890 if (!strcmp (flg_operand
->name
, "t"))
3891 if (!strcmp (opcode
->name
, "bbit0")
3892 || !strcmp (opcode
->name
, "bbit1"))
3893 bitYoperand
= arc_NToperand
;
3895 bitYoperand
= arc_Toperand
;
3897 if (!strcmp (opcode
->name
, "bbit0")
3898 || !strcmp (opcode
->name
, "bbit1"))
3899 bitYoperand
= arc_Toperand
;
3901 bitYoperand
= arc_NToperand
;
3903 gas_assert (reloc_exp
!= NULL
);
3904 if (reloc_exp
->X_op
== O_constant
)
3906 /* Check if we have a constant and solved it
3908 offsetT val
= reloc_exp
->X_add_number
;
3909 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
3914 struct arc_fixup
*fixup
;
3916 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3917 as_fatal (_("too many fixups"));
3919 fixup
= &insn
->fixups
[insn
->nfixups
++];
3920 fixup
->exp
= *reloc_exp
;
3921 fixup
->reloc
= -bitYoperand
;
3922 fixup
->pcrel
= pcrel
;
3923 fixup
->islong
= FALSE
;
3927 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
3928 << flg_operand
->shift
;
3931 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
3933 /* Instruction length. */
3934 insn
->len
= arc_opcode_len (opcode
);
3938 /* Update last insn status. */
3939 arc_last_insns
[1] = arc_last_insns
[0];
3940 arc_last_insns
[0].opcode
= opcode
;
3941 arc_last_insns
[0].has_limm
= insn
->has_limm
;
3942 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
3944 /* Check if the current instruction is legally used. */
3945 if (arc_last_insns
[1].has_delay_slot
3946 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3947 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3948 _("A jump/branch instruction in delay slot."));
3952 arc_handle_align (fragS
* fragP
)
3954 if ((fragP
)->fr_type
== rs_align_code
)
3956 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
3957 valueT count
= ((fragP
)->fr_next
->fr_address
3958 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
3960 (fragP
)->fr_var
= 2;
3962 if (count
& 1)/* Padding in the gap till the next 2-byte
3963 boundary with 0s. */
3968 /* Writing nop_s. */
3969 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
3973 /* Here we decide which fixups can be adjusted to make them relative
3974 to the beginning of the section instead of the symbol. Basically
3975 we need to make sure that the dynamic relocations are done
3976 correctly, so in some cases we force the original symbol to be
3980 tc_arc_fix_adjustable (fixS
*fixP
)
3983 /* Prevent all adjustments to global symbols. */
3984 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
3986 if (S_IS_WEAK (fixP
->fx_addsy
))
3989 /* Adjust_reloc_syms doesn't know about the GOT. */
3990 switch (fixP
->fx_r_type
)
3992 case BFD_RELOC_ARC_GOTPC32
:
3993 case BFD_RELOC_ARC_PLT32
:
3994 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
3995 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
3996 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
3997 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
4007 /* Compute the reloc type of an expression EXP. */
4010 arc_check_reloc (expressionS
*exp
,
4011 bfd_reloc_code_real_type
*r_type_p
)
4013 if (*r_type_p
== BFD_RELOC_32
4014 && exp
->X_op
== O_subtract
4015 && exp
->X_op_symbol
!= NULL
4016 && exp
->X_op_symbol
->bsym
->section
== now_seg
)
4017 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
4021 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4024 arc_cons_fix_new (fragS
*frag
,
4028 bfd_reloc_code_real_type r_type
)
4030 r_type
= BFD_RELOC_UNUSED
;
4035 r_type
= BFD_RELOC_8
;
4039 r_type
= BFD_RELOC_16
;
4043 r_type
= BFD_RELOC_24
;
4047 r_type
= BFD_RELOC_32
;
4048 arc_check_reloc (exp
, &r_type
);
4052 r_type
= BFD_RELOC_64
;
4056 as_bad (_("unsupported BFD relocation size %u"), size
);
4057 r_type
= BFD_RELOC_UNUSED
;
4060 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
4063 /* The actual routine that checks the ZOL conditions. */
4066 check_zol (symbolS
*s
)
4068 switch (selected_cpu
.mach
)
4070 case bfd_mach_arc_arcv2
:
4071 if (selected_cpu
.flags
& ARC_OPCODE_ARCv2EM
)
4074 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
4075 || arc_last_insns
[1].has_delay_slot
)
4076 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4080 case bfd_mach_arc_arc600
:
4082 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
4083 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4086 if (arc_last_insns
[0].has_limm
4087 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4088 as_bad (_("A jump instruction with long immediate detected at the \
4089 end of the ZOL label @%s"), S_GET_NAME (s
));
4092 case bfd_mach_arc_arc700
:
4093 if (arc_last_insns
[0].has_delay_slot
)
4094 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4103 /* If ZOL end check the last two instruction for illegals. */
4105 arc_frob_label (symbolS
* sym
)
4107 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
4110 dwarf2_emit_label (sym
);
4113 /* Used because generic relaxation assumes a pc-rel value whilst we
4114 also relax instructions that use an absolute value resolved out of
4115 relative values (if that makes any sense). An example: 'add r1,
4116 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4117 but if they're in the same section we can subtract the section
4118 offset relocation which ends up in a resolved value. So if @.L2 is
4119 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4120 .text + 0x40 = 0x10. */
4122 arc_pcrel_adjust (fragS
*fragP
)
4124 if (!fragP
->tc_frag_data
.pcrel
)
4125 return fragP
->fr_address
+ fragP
->fr_fix
;
4130 /* Initialize the DWARF-2 unwind information for this procedure. */
4133 tc_arc_frame_initial_instructions (void)
4135 /* Stack pointer is register 28. */
4136 cfi_add_CFA_def_cfa (28, 0);
4140 tc_arc_regname_to_dw2regnum (char *regname
)
4144 sym
= hash_find (arc_reg_hash
, regname
);
4146 return S_GET_VALUE (sym
);
4151 /* Adjust the symbol table. Delete found AUX register symbols. */
4154 arc_adjust_symtab (void)
4158 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
4160 /* I've created a symbol during parsing process. Now, remove
4161 the symbol as it is found to be an AUX register. */
4162 if (ARC_GET_FLAG (sym
) & ARC_FLAG_AUX
)
4163 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
4166 /* Now do generic ELF adjustments. */
4167 elf_adjust_symtab ();
4171 tokenize_extinsn (extInstruction_t
*einsn
)
4175 unsigned char major_opcode
;
4176 unsigned char sub_opcode
;
4177 unsigned char syntax_class
= 0;
4178 unsigned char syntax_class_modifiers
= 0;
4179 unsigned char suffix_class
= 0;
4184 /* 1st: get instruction name. */
4185 p
= input_line_pointer
;
4186 c
= get_symbol_name (&p
);
4188 insn_name
= xstrdup (p
);
4189 restore_line_pointer (c
);
4191 /* 2nd: get major opcode. */
4192 if (*input_line_pointer
!= ',')
4194 as_bad (_("expected comma after instruction name"));
4195 ignore_rest_of_line ();
4198 input_line_pointer
++;
4199 major_opcode
= get_absolute_expression ();
4201 /* 3rd: get sub-opcode. */
4204 if (*input_line_pointer
!= ',')
4206 as_bad (_("expected comma after major opcode"));
4207 ignore_rest_of_line ();
4210 input_line_pointer
++;
4211 sub_opcode
= get_absolute_expression ();
4213 /* 4th: get suffix class. */
4216 if (*input_line_pointer
!= ',')
4218 as_bad ("expected comma after sub opcode");
4219 ignore_rest_of_line ();
4222 input_line_pointer
++;
4228 for (i
= 0; i
< ARRAY_SIZE (suffixclass
); i
++)
4230 if (!strncmp (suffixclass
[i
].name
, input_line_pointer
,
4231 suffixclass
[i
].len
))
4233 suffix_class
|= suffixclass
[i
].attr_class
;
4234 input_line_pointer
+= suffixclass
[i
].len
;
4239 if (i
== ARRAY_SIZE (suffixclass
))
4241 as_bad ("invalid suffix class");
4242 ignore_rest_of_line ();
4248 if (*input_line_pointer
== '|')
4249 input_line_pointer
++;
4254 /* 5th: get syntax class and syntax class modifiers. */
4255 if (*input_line_pointer
!= ',')
4257 as_bad ("expected comma after suffix class");
4258 ignore_rest_of_line ();
4261 input_line_pointer
++;
4267 for (i
= 0; i
< ARRAY_SIZE (syntaxclassmod
); i
++)
4269 if (!strncmp (syntaxclassmod
[i
].name
,
4271 syntaxclassmod
[i
].len
))
4273 syntax_class_modifiers
|= syntaxclassmod
[i
].attr_class
;
4274 input_line_pointer
+= syntaxclassmod
[i
].len
;
4279 if (i
== ARRAY_SIZE (syntaxclassmod
))
4281 for (i
= 0; i
< ARRAY_SIZE (syntaxclass
); i
++)
4283 if (!strncmp (syntaxclass
[i
].name
,
4285 syntaxclass
[i
].len
))
4287 syntax_class
|= syntaxclass
[i
].attr_class
;
4288 input_line_pointer
+= syntaxclass
[i
].len
;
4293 if (i
== ARRAY_SIZE (syntaxclass
))
4295 as_bad ("missing syntax class");
4296 ignore_rest_of_line ();
4303 if (*input_line_pointer
== '|')
4304 input_line_pointer
++;
4309 demand_empty_rest_of_line ();
4311 einsn
->name
= insn_name
;
4312 einsn
->major
= major_opcode
;
4313 einsn
->minor
= sub_opcode
;
4314 einsn
->syntax
= syntax_class
;
4315 einsn
->modsyn
= syntax_class_modifiers
;
4316 einsn
->suffix
= suffix_class
;
4317 einsn
->flags
= syntax_class
4318 | (syntax_class_modifiers
& ARC_OP1_IMM_IMPLIED
? 0x10 : 0);
4321 /* Generate an extension section. */
4324 arc_set_ext_seg (void)
4326 if (!arcext_section
)
4328 arcext_section
= subseg_new (".arcextmap", 0);
4329 bfd_set_section_flags (stdoutput
, arcext_section
,
4330 SEC_READONLY
| SEC_HAS_CONTENTS
);
4333 subseg_set (arcext_section
, 0);
4337 /* Create an extension instruction description in the arc extension
4338 section of the output file.
4339 The structure for an instruction is like this:
4340 [0]: Length of the record.
4341 [1]: Type of the record.
4345 [4]: Syntax (flags).
4346 [5]+ Name instruction.
4348 The sequence is terminated by an empty entry. */
4351 create_extinst_section (extInstruction_t
*einsn
)
4354 segT old_sec
= now_seg
;
4355 int old_subsec
= now_subseg
;
4357 int name_len
= strlen (einsn
->name
);
4362 *p
= 5 + name_len
+ 1;
4364 *p
= EXT_INSTRUCTION
;
4371 p
= frag_more (name_len
+ 1);
4372 strcpy (p
, einsn
->name
);
4374 subseg_set (old_sec
, old_subsec
);
4377 /* Handler .extinstruction pseudo-op. */
4380 arc_extinsn (int ignore ATTRIBUTE_UNUSED
)
4382 extInstruction_t einsn
;
4383 struct arc_opcode
*arc_ext_opcodes
;
4384 const char *errmsg
= NULL
;
4385 unsigned char moplow
, mophigh
;
4387 memset (&einsn
, 0, sizeof (einsn
));
4388 tokenize_extinsn (&einsn
);
4390 /* Check if the name is already used. */
4391 if (arc_find_opcode (einsn
.name
))
4392 as_warn (_("Pseudocode already used %s"), einsn
.name
);
4394 /* Check the opcode ranges. */
4396 mophigh
= (selected_cpu
.flags
& (ARC_OPCODE_ARCv2EM
4397 | ARC_OPCODE_ARCv2HS
)) ? 0x07 : 0x0a;
4399 if ((einsn
.major
> mophigh
) || (einsn
.major
< moplow
))
4400 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow
, mophigh
);
4402 if ((einsn
.minor
> 0x3f) && (einsn
.major
!= 0x0a)
4403 && (einsn
.major
!= 5) && (einsn
.major
!= 9))
4404 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4406 switch (einsn
.syntax
& ARC_SYNTAX_MASK
)
4408 case ARC_SYNTAX_3OP
:
4409 if (einsn
.modsyn
& ARC_OP1_IMM_IMPLIED
)
4410 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4412 case ARC_SYNTAX_2OP
:
4413 case ARC_SYNTAX_1OP
:
4414 case ARC_SYNTAX_NOP
:
4415 if (einsn
.modsyn
& ARC_OP1_MUST_BE_IMM
)
4416 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4422 arc_ext_opcodes
= arcExtMap_genOpcode (&einsn
, selected_cpu
.flags
, &errmsg
);
4423 if (arc_ext_opcodes
== NULL
)
4426 as_fatal ("%s", errmsg
);
4428 as_fatal (_("Couldn't generate extension instruction opcodes"));
4431 as_warn ("%s", errmsg
);
4433 /* Insert the extension instruction. */
4434 arc_insert_opcode ((const struct arc_opcode
*) arc_ext_opcodes
);
4436 create_extinst_section (&einsn
);
4440 tokenize_extregister (extRegister_t
*ereg
, int opertype
)
4446 int number
, imode
= 0;
4447 bfd_boolean isCore_p
= (opertype
== EXT_CORE_REGISTER
) ? TRUE
: FALSE
;
4448 bfd_boolean isReg_p
= (opertype
== EXT_CORE_REGISTER
4449 || opertype
== EXT_AUX_REGISTER
) ? TRUE
: FALSE
;
4451 /* 1st: get register name. */
4453 p
= input_line_pointer
;
4454 c
= get_symbol_name (&p
);
4457 restore_line_pointer (c
);
4459 /* 2nd: get register number. */
4462 if (*input_line_pointer
!= ',')
4464 as_bad (_("expected comma after register name"));
4465 ignore_rest_of_line ();
4469 input_line_pointer
++;
4470 number
= get_absolute_expression ();
4474 as_bad (_("negative operand number %d"), number
);
4475 ignore_rest_of_line ();
4482 /* 3rd: get register mode. */
4485 if (*input_line_pointer
!= ',')
4487 as_bad (_("expected comma after register number"));
4488 ignore_rest_of_line ();
4493 input_line_pointer
++;
4494 mode
= input_line_pointer
;
4496 if (!strncmp (mode
, "r|w", 3))
4499 input_line_pointer
+= 3;
4501 else if (!strncmp (mode
, "r", 1))
4503 imode
= ARC_REGISTER_READONLY
;
4504 input_line_pointer
+= 1;
4506 else if (strncmp (mode
, "w", 1))
4508 as_bad (_("invalid mode"));
4509 ignore_rest_of_line ();
4515 imode
= ARC_REGISTER_WRITEONLY
;
4516 input_line_pointer
+= 1;
4522 /* 4th: get core register shortcut. */
4524 if (*input_line_pointer
!= ',')
4526 as_bad (_("expected comma after register mode"));
4527 ignore_rest_of_line ();
4532 input_line_pointer
++;
4534 if (!strncmp (input_line_pointer
, "cannot_shortcut", 15))
4536 imode
|= ARC_REGISTER_NOSHORT_CUT
;
4537 input_line_pointer
+= 15;
4539 else if (strncmp (input_line_pointer
, "can_shortcut", 12))
4541 as_bad (_("shortcut designator invalid"));
4542 ignore_rest_of_line ();
4548 input_line_pointer
+= 12;
4551 demand_empty_rest_of_line ();
4554 ereg
->number
= number
;
4555 ereg
->imode
= imode
;
4558 /* Create an extension register/condition description in the arc
4559 extension section of the output file.
4561 The structure for an instruction is like this:
4562 [0]: Length of the record.
4563 [1]: Type of the record.
4565 For core regs and condition codes:
4569 For auxilirary registers:
4573 The sequence is terminated by an empty entry. */
4576 create_extcore_section (extRegister_t
*ereg
, int opertype
)
4578 segT old_sec
= now_seg
;
4579 int old_subsec
= now_subseg
;
4581 int name_len
= strlen (ereg
->name
);
4588 case EXT_CORE_REGISTER
:
4590 *p
= 3 + name_len
+ 1;
4596 case EXT_AUX_REGISTER
:
4598 *p
= 6 + name_len
+ 1;
4600 *p
= EXT_AUX_REGISTER
;
4602 *p
= (ereg
->number
>> 24) & 0xff;
4604 *p
= (ereg
->number
>> 16) & 0xff;
4606 *p
= (ereg
->number
>> 8) & 0xff;
4608 *p
= (ereg
->number
) & 0xff;
4614 p
= frag_more (name_len
+ 1);
4615 strcpy (p
, ereg
->name
);
4617 subseg_set (old_sec
, old_subsec
);
4620 /* Handler .extCoreRegister pseudo-op. */
4623 arc_extcorereg (int opertype
)
4626 struct arc_aux_reg
*auxr
;
4628 struct arc_flag_operand
*ccode
;
4630 memset (&ereg
, 0, sizeof (ereg
));
4631 tokenize_extregister (&ereg
, opertype
);
4635 case EXT_CORE_REGISTER
:
4636 /* Core register. */
4637 if (ereg
.number
> 60)
4638 as_bad (_("core register %s value (%d) too large"), ereg
.name
,
4640 declare_register (ereg
.name
, ereg
.number
);
4642 case EXT_AUX_REGISTER
:
4643 /* Auxiliary register. */
4644 auxr
= XNEW (struct arc_aux_reg
);
4645 auxr
->name
= ereg
.name
;
4646 auxr
->cpu
= selected_cpu
.flags
;
4647 auxr
->subclass
= NONE
;
4648 auxr
->address
= ereg
.number
;
4649 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
4651 as_fatal (_("internal error: can't hash aux register '%s': %s"),
4652 auxr
->name
, retval
);
4655 /* Condition code. */
4656 if (ereg
.number
> 31)
4657 as_bad (_("condition code %s value (%d) too large"), ereg
.name
,
4659 ext_condcode
.size
++;
4660 ext_condcode
.arc_ext_condcode
=
4661 XRESIZEVEC (struct arc_flag_operand
, ext_condcode
.arc_ext_condcode
,
4662 ext_condcode
.size
+ 1);
4663 if (ext_condcode
.arc_ext_condcode
== NULL
)
4664 as_fatal (_("Virtual memory exhausted"));
4666 ccode
= ext_condcode
.arc_ext_condcode
+ ext_condcode
.size
- 1;
4667 ccode
->name
= ereg
.name
;
4668 ccode
->code
= ereg
.number
;
4671 ccode
->favail
= 0; /* not used. */
4673 memset (ccode
, 0, sizeof (struct arc_flag_operand
));
4676 as_bad (_("Unknown extension"));
4679 create_extcore_section (&ereg
, opertype
);
4683 eval: (c-set-style "gnu")