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 || (op)->insn_class == JUMP))
106 #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL))
107 #define is_nps400_p(op) (((sc) == NPS400))
109 /* Generic assembler global variables which must be defined by all
112 /* Characters which always start a comment. */
113 const char comment_chars
[] = "#;";
115 /* Characters which start a comment at the beginning of a line. */
116 const char line_comment_chars
[] = "#";
118 /* Characters which may be used to separate multiple commands on a
120 const char line_separator_chars
[] = "`";
122 /* Characters which are used to indicate an exponent in a floating
124 const char EXP_CHARS
[] = "eE";
126 /* Chars that mean this number is a floating point constant
127 As in 0f12.456 or 0d1.2345e12. */
128 const char FLT_CHARS
[] = "rRsSfFdD";
131 extern int target_big_endian
;
132 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
133 static int byte_order
= DEFAULT_BYTE_ORDER
;
135 /* Arc extension section. */
136 static segT arcext_section
;
138 /* By default relaxation is disabled. */
139 static int relaxation_state
= 0;
141 extern int arc_get_mach (char *);
143 /* Forward declarations. */
144 static void arc_lcomm (int);
145 static void arc_option (int);
146 static void arc_extra_reloc (int);
147 static void arc_extinsn (int);
148 static void arc_extcorereg (int);
150 const pseudo_typeS md_pseudo_table
[] =
152 /* Make sure that .word is 32 bits. */
155 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
156 { "lcomm", arc_lcomm
, 0 },
157 { "lcommon", arc_lcomm
, 0 },
158 { "cpu", arc_option
, 0 },
160 { "extinstruction", arc_extinsn
, 0 },
161 { "extcoreregister", arc_extcorereg
, EXT_CORE_REGISTER
},
162 { "extauxregister", arc_extcorereg
, EXT_AUX_REGISTER
},
163 { "extcondcode", arc_extcorereg
, EXT_COND_CODE
},
165 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
166 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
171 const char *md_shortopts
= "";
175 OPTION_EB
= OPTION_MD_BASE
,
193 /* The following options are deprecated and provided here only for
194 compatibility reasons. */
217 struct option md_longopts
[] =
219 { "EB", no_argument
, NULL
, OPTION_EB
},
220 { "EL", no_argument
, NULL
, OPTION_EL
},
221 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
222 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
223 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
224 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
225 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
226 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
227 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
228 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
229 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
230 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
231 { "mnps400", no_argument
, NULL
, OPTION_NPS400
},
233 /* Floating point options */
234 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
235 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
236 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
237 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
238 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
239 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
240 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
241 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
242 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
243 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
244 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
246 /* The following options are deprecated and provided here only for
247 compatibility reasons. */
248 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
249 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
250 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
251 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
252 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
253 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
254 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
255 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
256 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
257 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
258 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
259 { "mea", no_argument
, NULL
, OPTION_EA
},
260 { "mEA", no_argument
, NULL
, OPTION_EA
},
261 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
262 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
263 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
264 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
265 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
266 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
267 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
268 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
269 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
270 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
271 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
272 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
273 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
274 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
275 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
277 { NULL
, no_argument
, NULL
, 0 }
280 size_t md_longopts_size
= sizeof (md_longopts
);
282 /* Local data and data types. */
284 /* Used since new relocation types are introduced in this
285 file (DUMMY_RELOC_LITUSE_*). */
286 typedef int extended_bfd_reloc_code_real_type
;
292 extended_bfd_reloc_code_real_type reloc
;
294 /* index into arc_operands. */
295 unsigned int opindex
;
297 /* PC-relative, used by internals fixups. */
300 /* TRUE if this fixup is for LIMM operand. */
308 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
310 bfd_boolean short_insn
; /* Boolean value: TRUE if current insn is
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 cpu for which we are generating code. */
404 static unsigned arc_target
;
405 static const char *arc_target_name
;
406 static unsigned arc_features
;
408 /* The default architecture. */
409 static int arc_mach_type
;
411 /* TRUE if the cpu type has been explicitly specified. */
412 static bfd_boolean mach_type_specified_p
= FALSE
;
414 /* The hash table of instruction opcodes. */
415 static struct hash_control
*arc_opcode_hash
;
417 /* The hash table of register symbols. */
418 static struct hash_control
*arc_reg_hash
;
420 /* The hash table of aux register symbols. */
421 static struct hash_control
*arc_aux_hash
;
423 /* A table of CPU names and opcode sets. */
424 static const struct cpu_type
434 { "arc600", ARC_OPCODE_ARC600
, bfd_mach_arc_arc600
,
435 E_ARC_MACH_ARC600
, 0x00},
436 { "arc700", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
437 E_ARC_MACH_ARC700
, 0x00},
438 { "nps400", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
439 E_ARC_MACH_ARC700
, ARC_NPS400
},
440 { "arcem", ARC_OPCODE_ARCv2EM
, bfd_mach_arc_arcv2
,
441 EF_ARC_CPU_ARCV2EM
, 0x00},
442 { "archs", ARC_OPCODE_ARCv2HS
, bfd_mach_arc_arcv2
,
443 EF_ARC_CPU_ARCV2HS
, ARC_CD
},
447 /* Used by the arc_reloc_op table. Order is important. */
448 #define O_gotoff O_md1 /* @gotoff relocation. */
449 #define O_gotpc O_md2 /* @gotpc relocation. */
450 #define O_plt O_md3 /* @plt relocation. */
451 #define O_sda O_md4 /* @sda relocation. */
452 #define O_pcl O_md5 /* @pcl relocation. */
453 #define O_tlsgd O_md6 /* @tlsgd relocation. */
454 #define O_tlsie O_md7 /* @tlsie relocation. */
455 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
456 #define O_tpoff O_md9 /* @tpoff relocation. */
457 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
458 #define O_dtpoff O_md11 /* @dtpoff relocation. */
459 #define O_last O_dtpoff
461 /* Used to define a bracket as operand in tokens. */
462 #define O_bracket O_md32
464 /* Dummy relocation, to be sorted out. */
465 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
467 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
469 /* A table to map the spelling of a relocation operand into an appropriate
470 bfd_reloc_code_real_type type. The table is assumed to be ordered such
471 that op-O_literal indexes into it. */
472 #define ARC_RELOC_TABLE(op) \
473 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
475 : (int) (op) - (int) O_gotoff) ])
477 #define DEF(NAME, RELOC, REQ) \
478 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
480 static const struct arc_reloc_op_tag
482 /* String to lookup. */
484 /* Size of the string. */
486 /* Which operator to use. */
488 extended_bfd_reloc_code_real_type reloc
;
489 /* Allows complex relocation expression like identifier@reloc +
491 unsigned int complex_expr
: 1;
495 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
496 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
497 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
498 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
499 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
500 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
501 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
502 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
503 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
504 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
505 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 1),
508 static const int arc_num_reloc_op
509 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
511 /* Structure for relaxable instruction that have to be swapped with a
512 smaller alternative instruction. */
513 struct arc_relaxable_ins
515 /* Mnemonic that should be checked. */
516 const char *mnemonic_r
;
518 /* Operands that should be checked.
519 Indexes of operands from operand array. */
520 enum rlx_operand_type operands
[6];
522 /* Flags that should be checked. */
523 unsigned flag_classes
[5];
525 /* Mnemonic (smaller) alternative to be used later for relaxation. */
526 const char *mnemonic_alt
;
528 /* Index of operand that generic relaxation has to check. */
531 /* Base subtype index used. */
532 enum arc_rlx_types subtype
;
535 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
536 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
537 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
541 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
542 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
543 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
548 /* ARC relaxation table. */
549 const relax_typeS md_relax_table
[] =
556 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL
),
557 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
561 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B
),
562 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
567 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6
),
568 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM
),
569 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
571 /* LD_S a, [b, u7] ->
572 LD<zz><.x><.aa><.di> a, [b, s9] ->
573 LD<zz><.x><.aa><.di> a, [b, limm] */
574 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9
),
575 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM
),
576 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE
),
581 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12
),
582 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM
),
583 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
587 SUB<.f> a, b, limm. */
588 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6
),
589 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM
),
590 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
592 /* MPY<.f> a, b, u6 ->
593 MPY<.f> a, b, limm. */
594 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM
),
595 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
597 /* MOV<.f><.cc> b, u6 ->
598 MOV<.f><.cc> b, limm. */
599 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM
),
600 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
602 /* ADD<.f><.cc> b, b, u6 ->
603 ADD<.f><.cc> b, b, limm. */
604 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM
),
605 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
608 /* Order of this table's entries matters! */
609 const struct arc_relaxable_ins arc_relaxable_insns
[] =
611 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
612 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
613 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
614 2, ARC_RLX_ADD_RRU6
},
615 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
617 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
619 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
620 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
621 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
622 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
623 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
624 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
625 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
626 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
628 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
630 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
634 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
636 /* Flags to set in the elf header. */
637 static flagword arc_eflag
= 0x00;
639 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
640 symbolS
* GOT_symbol
= 0;
642 /* Set to TRUE when we assemble instructions. */
643 static bfd_boolean assembling_insn
= FALSE
;
645 /* Functions implementation. */
647 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
648 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
649 are no matching entries in ARC_OPCODE_HASH. */
651 static const struct arc_opcode_hash_entry
*
652 arc_find_opcode (const char *name
)
654 const struct arc_opcode_hash_entry
*entry
;
656 entry
= hash_find (arc_opcode_hash
, name
);
660 /* Initialise the iterator ITER. */
663 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator
*iter
)
669 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
670 calls to this function. Return NULL when all ARC_OPCODE entries have
673 static const struct arc_opcode
*
674 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry
*entry
,
675 struct arc_opcode_hash_entry_iterator
*iter
)
677 if (iter
->opcode
== NULL
&& iter
->index
== 0)
679 gas_assert (entry
->count
> 0);
680 iter
->opcode
= entry
->opcode
[iter
->index
];
682 else if (iter
->opcode
!= NULL
)
684 const char *old_name
= iter
->opcode
->name
;
687 if (iter
->opcode
->name
== NULL
688 || strcmp (old_name
, iter
->opcode
->name
) != 0)
691 if (iter
->index
== entry
->count
)
694 iter
->opcode
= entry
->opcode
[iter
->index
];
701 /* Insert an opcode into opcode hash structure. */
704 arc_insert_opcode (const struct arc_opcode
*opcode
)
706 const char *name
, *retval
;
707 struct arc_opcode_hash_entry
*entry
;
710 entry
= hash_find (arc_opcode_hash
, name
);
713 entry
= XNEW (struct arc_opcode_hash_entry
);
715 entry
->opcode
= NULL
;
717 retval
= hash_insert (arc_opcode_hash
, name
, (void *) entry
);
719 as_fatal (_("internal error: can't hash opcode '%s': %s"),
723 entry
->opcode
= XRESIZEVEC (const struct arc_opcode
*, entry
->opcode
,
726 if (entry
->opcode
== NULL
)
727 as_fatal (_("Virtual memory exhausted"));
729 entry
->opcode
[entry
->count
] = opcode
;
734 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
735 is encoded as 'middle-endian' for a little-endian target. FIXME!
736 this function is used for regular 4 byte instructions as well. */
739 md_number_to_chars_midend (char *buf
, valueT val
, int n
)
743 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
744 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
748 md_number_to_chars (buf
, val
, n
);
752 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
753 the relevant static global variables. */
756 arc_select_cpu (const char *arg
)
761 for (i
= 0; cpu_types
[i
].name
; ++i
)
763 if (!strcasecmp (cpu_types
[i
].name
, arg
))
765 arc_target
= cpu_types
[i
].flags
;
766 arc_target_name
= cpu_types
[i
].name
;
767 arc_features
= cpu_types
[i
].features
;
768 arc_mach_type
= cpu_types
[i
].mach
;
769 cpu_flags
= cpu_types
[i
].eflags
;
774 if (!cpu_types
[i
].name
)
775 as_fatal (_("unknown architecture: %s\n"), arg
);
776 gas_assert (cpu_flags
!= 0);
777 arc_eflag
= (arc_eflag
& ~EF_ARC_MACH_MSK
) | cpu_flags
;
780 /* Here ends all the ARCompact extension instruction assembling
784 arc_extra_reloc (int r_type
)
787 symbolS
*sym
, *lab
= NULL
;
789 if (*input_line_pointer
== '@')
790 input_line_pointer
++;
791 c
= get_symbol_name (&sym_name
);
792 sym
= symbol_find_or_make (sym_name
);
793 restore_line_pointer (c
);
794 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
796 ++input_line_pointer
;
798 c
= get_symbol_name (&lab_name
);
799 lab
= symbol_find_or_make (lab_name
);
800 restore_line_pointer (c
);
803 /* These relocations exist as a mechanism for the compiler to tell the
804 linker how to patch the code if the tls model is optimised. However,
805 the relocation itself does not require any space within the assembler
806 fragment, and so we pass a size of 0.
808 The lines that generate these relocations look like this:
810 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
812 The '.tls_gd_ld @.tdata' is processed first and generates the
813 additional relocation, while the 'bl __tls_get_addr@plt' is processed
814 second and generates the additional branch.
816 It is possible that the additional relocation generated by the
817 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
818 while the 'bl __tls_get_addr@plt' will be generated as the first thing
819 in the next fragment. This will be fine; both relocations will still
820 appear to be at the same address in the generated object file.
821 However, this only works as the additional relocation is generated
822 with size of 0 bytes. */
824 = fix_new (frag_now
, /* Which frag? */
825 frag_now_fix (), /* Where in that frag? */
826 0, /* size: 1, 2, or 4 usually. */
827 sym
, /* X_add_symbol. */
828 0, /* X_add_number. */
829 FALSE
, /* TRUE if PC-relative relocation. */
830 r_type
/* Relocation type. */);
831 fixP
->fx_subsy
= lab
;
835 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
836 symbolS
*symbolP
, addressT size
)
841 if (*input_line_pointer
== ',')
843 align
= parse_align (1);
845 if (align
== (addressT
) -1)
860 bss_alloc (symbolP
, size
, align
);
861 S_CLEAR_EXTERNAL (symbolP
);
867 arc_lcomm (int ignore
)
869 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
872 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
875 /* Select the cpu we're assembling for. */
878 arc_option (int ignore ATTRIBUTE_UNUSED
)
884 c
= get_symbol_name (&cpu
);
885 mach
= arc_get_mach (cpu
);
890 if (!mach_type_specified_p
)
892 if ((!strcmp ("ARC600", cpu
))
893 || (!strcmp ("ARC601", cpu
))
894 || (!strcmp ("A6", cpu
)))
896 md_parse_option (OPTION_MCPU
, "arc600");
898 else if ((!strcmp ("ARC700", cpu
))
899 || (!strcmp ("A7", cpu
)))
901 md_parse_option (OPTION_MCPU
, "arc700");
903 else if (!strcmp ("EM", cpu
))
905 md_parse_option (OPTION_MCPU
, "arcem");
907 else if (!strcmp ("HS", cpu
))
909 md_parse_option (OPTION_MCPU
, "archs");
911 else if (!strcmp ("NPS400", cpu
))
913 md_parse_option (OPTION_MCPU
, "nps400");
916 as_fatal (_("could not find the architecture"));
918 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, mach
))
919 as_fatal (_("could not set architecture and machine"));
921 /* Set elf header flags. */
922 bfd_set_private_flags (stdoutput
, arc_eflag
);
925 if (arc_mach_type
!= mach
)
926 as_warn (_("Command-line value overrides \".cpu\" directive"));
928 restore_line_pointer (c
);
929 demand_empty_rest_of_line ();
933 restore_line_pointer (c
);
934 as_bad (_("invalid identifier for \".cpu\""));
935 ignore_rest_of_line ();
938 /* Smartly print an expression. */
941 debug_exp (expressionS
*t
)
943 const char *name ATTRIBUTE_UNUSED
;
944 const char *namemd ATTRIBUTE_UNUSED
;
946 pr_debug ("debug_exp: ");
950 default: name
= "unknown"; break;
951 case O_illegal
: name
= "O_illegal"; break;
952 case O_absent
: name
= "O_absent"; break;
953 case O_constant
: name
= "O_constant"; break;
954 case O_symbol
: name
= "O_symbol"; break;
955 case O_symbol_rva
: name
= "O_symbol_rva"; break;
956 case O_register
: name
= "O_register"; break;
957 case O_big
: name
= "O_big"; break;
958 case O_uminus
: name
= "O_uminus"; break;
959 case O_bit_not
: name
= "O_bit_not"; break;
960 case O_logical_not
: name
= "O_logical_not"; break;
961 case O_multiply
: name
= "O_multiply"; break;
962 case O_divide
: name
= "O_divide"; break;
963 case O_modulus
: name
= "O_modulus"; break;
964 case O_left_shift
: name
= "O_left_shift"; break;
965 case O_right_shift
: name
= "O_right_shift"; break;
966 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
967 case O_bit_or_not
: name
= "O_bit_or_not"; break;
968 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
969 case O_bit_and
: name
= "O_bit_and"; break;
970 case O_add
: name
= "O_add"; break;
971 case O_subtract
: name
= "O_subtract"; break;
972 case O_eq
: name
= "O_eq"; break;
973 case O_ne
: name
= "O_ne"; break;
974 case O_lt
: name
= "O_lt"; break;
975 case O_le
: name
= "O_le"; break;
976 case O_ge
: name
= "O_ge"; break;
977 case O_gt
: name
= "O_gt"; break;
978 case O_logical_and
: name
= "O_logical_and"; break;
979 case O_logical_or
: name
= "O_logical_or"; break;
980 case O_index
: name
= "O_index"; break;
981 case O_bracket
: name
= "O_bracket"; break;
986 default: namemd
= "unknown"; break;
987 case O_gotoff
: namemd
= "O_gotoff"; break;
988 case O_gotpc
: namemd
= "O_gotpc"; break;
989 case O_plt
: namemd
= "O_plt"; break;
990 case O_sda
: namemd
= "O_sda"; break;
991 case O_pcl
: namemd
= "O_pcl"; break;
992 case O_tlsgd
: namemd
= "O_tlsgd"; break;
993 case O_tlsie
: namemd
= "O_tlsie"; break;
994 case O_tpoff9
: namemd
= "O_tpoff9"; break;
995 case O_tpoff
: namemd
= "O_tpoff"; break;
996 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
997 case O_dtpoff
: namemd
= "O_dtpoff"; break;
1000 pr_debug ("%s (%s, %s, %d, %s)", name
,
1001 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1002 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1003 (int) t
->X_add_number
,
1004 (t
->X_md
) ? namemd
: "--");
1009 /* Parse the arguments to an opcode. */
1012 tokenize_arguments (char *str
,
1016 char *old_input_line_pointer
;
1017 bfd_boolean saw_comma
= FALSE
;
1018 bfd_boolean saw_arg
= FALSE
;
1023 const struct arc_reloc_op_tag
*r
;
1025 char *reloc_name
, c
;
1027 memset (tok
, 0, sizeof (*tok
) * ntok
);
1029 /* Save and restore input_line_pointer around this function. */
1030 old_input_line_pointer
= input_line_pointer
;
1031 input_line_pointer
= str
;
1033 while (*input_line_pointer
)
1036 switch (*input_line_pointer
)
1042 input_line_pointer
++;
1043 if (saw_comma
|| !saw_arg
)
1050 ++input_line_pointer
;
1052 if (!saw_arg
|| num_args
== ntok
)
1054 tok
->X_op
= O_bracket
;
1061 input_line_pointer
++;
1062 if (brk_lvl
|| num_args
== ntok
)
1065 tok
->X_op
= O_bracket
;
1071 /* We have labels, function names and relocations, all
1072 starting with @ symbol. Sort them out. */
1073 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1077 tok
->X_op
= O_symbol
;
1078 tok
->X_md
= O_absent
;
1080 if (*input_line_pointer
!= '@')
1081 goto normalsymbol
; /* This is not a relocation. */
1085 /* A relocation opernad has the following form
1086 @identifier@relocation_type. The identifier is already
1088 if (tok
->X_op
!= O_symbol
)
1090 as_bad (_("No valid label relocation operand"));
1094 /* Parse @relocation_type. */
1095 input_line_pointer
++;
1096 c
= get_symbol_name (&reloc_name
);
1097 len
= input_line_pointer
- reloc_name
;
1100 as_bad (_("No relocation operand"));
1104 /* Go through known relocation and try to find a match. */
1105 r
= &arc_reloc_op
[0];
1106 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1107 if (len
== r
->length
1108 && memcmp (reloc_name
, r
->name
, len
) == 0)
1112 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
1116 *input_line_pointer
= c
;
1117 SKIP_WHITESPACE_AFTER_NAME ();
1118 /* Extra check for TLS: base. */
1119 if (*input_line_pointer
== '@')
1122 if (tok
->X_op_symbol
!= NULL
1123 || tok
->X_op
!= O_symbol
)
1125 as_bad (_("Unable to parse TLS base: %s"),
1126 input_line_pointer
);
1129 input_line_pointer
++;
1131 c
= get_symbol_name (&sym_name
);
1132 base
= symbol_find_or_make (sym_name
);
1133 tok
->X_op
= O_subtract
;
1134 tok
->X_op_symbol
= base
;
1135 restore_line_pointer (c
);
1136 tmpE
.X_add_number
= 0;
1138 else if ((*input_line_pointer
!= '+')
1139 && (*input_line_pointer
!= '-'))
1141 tmpE
.X_add_number
= 0;
1145 /* Parse the constant of a complex relocation expression
1146 like @identifier@reloc +/- const. */
1147 if (! r
->complex_expr
)
1149 as_bad (_("@%s is not a complex relocation."), r
->name
);
1153 if (tmpE
.X_op
!= O_constant
)
1155 as_bad (_("Bad expression: @%s + %s."),
1156 r
->name
, input_line_pointer
);
1162 tok
->X_add_number
= tmpE
.X_add_number
;
1173 /* Can be a register. */
1174 ++input_line_pointer
;
1178 if ((saw_arg
&& !saw_comma
) || num_args
== ntok
)
1181 tok
->X_op
= O_absent
;
1182 tok
->X_md
= O_absent
;
1185 /* Legacy: There are cases when we have
1186 identifier@relocation_type, if it is the case parse the
1187 relocation type as well. */
1188 if (*input_line_pointer
== '@')
1194 if (tok
->X_op
== O_illegal
1195 || tok
->X_op
== O_absent
1196 || num_args
== ntok
)
1208 if (saw_comma
|| brk_lvl
)
1210 input_line_pointer
= old_input_line_pointer
;
1216 as_bad (_("Brackets in operand field incorrect"));
1218 as_bad (_("extra comma"));
1220 as_bad (_("missing argument"));
1222 as_bad (_("missing comma or colon"));
1223 input_line_pointer
= old_input_line_pointer
;
1227 /* Parse the flags to a structure. */
1230 tokenize_flags (const char *str
,
1231 struct arc_flags flags
[],
1234 char *old_input_line_pointer
;
1235 bfd_boolean saw_flg
= FALSE
;
1236 bfd_boolean saw_dot
= FALSE
;
1240 memset (flags
, 0, sizeof (*flags
) * nflg
);
1242 /* Save and restore input_line_pointer around this function. */
1243 old_input_line_pointer
= input_line_pointer
;
1244 input_line_pointer
= (char *) str
;
1246 while (*input_line_pointer
)
1248 switch (*input_line_pointer
)
1255 input_line_pointer
++;
1263 if (saw_flg
&& !saw_dot
)
1266 if (num_flags
>= nflg
)
1269 flgnamelen
= strspn (input_line_pointer
,
1270 "abcdefghijklmnopqrstuvwxyz0123456789");
1271 if (flgnamelen
> MAX_FLAG_NAME_LENGTH
)
1274 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1276 input_line_pointer
+= flgnamelen
;
1286 input_line_pointer
= old_input_line_pointer
;
1291 as_bad (_("extra dot"));
1293 as_bad (_("unrecognized flag"));
1295 as_bad (_("failed to parse flags"));
1296 input_line_pointer
= old_input_line_pointer
;
1300 /* Apply the fixups in order. */
1303 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1307 for (i
= 0; i
< insn
->nfixups
; i
++)
1309 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1310 int size
, pcrel
, offset
= 0;
1312 /* FIXME! the reloc size is wrong in the BFD file.
1313 When it is fixed please delete me. */
1314 size
= (insn
->short_insn
&& !fixup
->islong
) ? 2 : 4;
1317 offset
= (insn
->short_insn
) ? 2 : 4;
1319 /* Some fixups are only used internally, thus no howto. */
1320 if ((int) fixup
->reloc
== 0)
1321 as_fatal (_("Unhandled reloc type"));
1323 if ((int) fixup
->reloc
< 0)
1325 /* FIXME! the reloc size is wrong in the BFD file.
1326 When it is fixed please enable me.
1327 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1328 pcrel
= fixup
->pcrel
;
1332 reloc_howto_type
*reloc_howto
=
1333 bfd_reloc_type_lookup (stdoutput
,
1334 (bfd_reloc_code_real_type
) fixup
->reloc
);
1335 gas_assert (reloc_howto
);
1337 /* FIXME! the reloc size is wrong in the BFD file.
1338 When it is fixed please enable me.
1339 size = bfd_get_reloc_size (reloc_howto); */
1340 pcrel
= reloc_howto
->pc_relative
;
1343 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1345 fragP
->fr_file
, fragP
->fr_line
,
1346 (fixup
->reloc
< 0) ? "Internal" :
1347 bfd_get_reloc_code_name (fixup
->reloc
),
1350 fix_new_exp (fragP
, fix
+ offset
,
1351 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1353 /* Check for ZOLs, and update symbol info if any. */
1354 if (LP_INSN (insn
->insn
))
1356 gas_assert (fixup
->exp
.X_add_symbol
);
1357 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1362 /* Actually output an instruction with its fixup. */
1365 emit_insn0 (struct arc_insn
*insn
, char *where
, bfd_boolean relax
)
1369 pr_debug ("Emit insn : 0x%x\n", insn
->insn
);
1370 pr_debug ("\tShort : 0x%d\n", insn
->short_insn
);
1371 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1373 /* Write out the instruction. */
1374 if (insn
->short_insn
)
1380 md_number_to_chars (f
, insn
->insn
, 2);
1381 md_number_to_chars_midend (f
+ 2, insn
->limm
, 4);
1382 dwarf2_emit_insn (6);
1388 md_number_to_chars (f
, insn
->insn
, 2);
1389 dwarf2_emit_insn (2);
1398 md_number_to_chars_midend (f
, insn
->insn
, 4);
1399 md_number_to_chars_midend (f
+ 4, insn
->limm
, 4);
1400 dwarf2_emit_insn (8);
1406 md_number_to_chars_midend (f
, insn
->insn
, 4);
1407 dwarf2_emit_insn (4);
1412 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1416 emit_insn1 (struct arc_insn
*insn
)
1418 /* How frag_var's args are currently configured:
1419 - rs_machine_dependent, to dictate it's a relaxation frag.
1420 - FRAG_MAX_GROWTH, maximum size of instruction
1421 - 0, variable size that might grow...unused by generic relaxation.
1422 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1423 - s, opand expression.
1424 - 0, offset but it's unused.
1425 - 0, opcode but it's unused. */
1426 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1427 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1429 if (frag_room () < FRAG_MAX_GROWTH
)
1431 /* Handle differently when frag literal memory is exhausted.
1432 This is used because when there's not enough memory left in
1433 the current frag, a new frag is created and the information
1434 we put into frag_now->tc_frag_data is disregarded. */
1436 struct arc_relax_type relax_info_copy
;
1437 relax_substateT subtype
= frag_now
->fr_subtype
;
1439 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1440 sizeof (struct arc_relax_type
));
1442 frag_wane (frag_now
);
1443 frag_grow (FRAG_MAX_GROWTH
);
1445 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1446 sizeof (struct arc_relax_type
));
1448 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1452 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1453 frag_now
->fr_subtype
, s
, 0, 0);
1457 emit_insn (struct arc_insn
*insn
)
1462 emit_insn0 (insn
, NULL
, FALSE
);
1465 /* Check whether a symbol involves a register. */
1468 contains_register (symbolS
*sym
)
1472 expressionS
*ex
= symbol_get_value_expression (sym
);
1474 return ((O_register
== ex
->X_op
)
1475 && !contains_register (ex
->X_add_symbol
)
1476 && !contains_register (ex
->X_op_symbol
));
1482 /* Returns the register number within a symbol. */
1485 get_register (symbolS
*sym
)
1487 if (!contains_register (sym
))
1490 expressionS
*ex
= symbol_get_value_expression (sym
);
1491 return regno (ex
->X_add_number
);
1494 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1495 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1498 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1505 case BFD_RELOC_ARC_SDA_LDST
:
1506 case BFD_RELOC_ARC_SDA_LDST1
:
1507 case BFD_RELOC_ARC_SDA_LDST2
:
1508 case BFD_RELOC_ARC_SDA16_LD
:
1509 case BFD_RELOC_ARC_SDA16_LD1
:
1510 case BFD_RELOC_ARC_SDA16_LD2
:
1511 case BFD_RELOC_ARC_SDA16_ST2
:
1512 case BFD_RELOC_ARC_SDA32_ME
:
1519 /* Allocates a tok entry. */
1522 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1524 if (ntok
> MAX_INSN_ARGS
- 2)
1525 return 0; /* No space left. */
1528 return 0; /* Incorect args. */
1530 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1533 return 1; /* Success. */
1534 return allocate_tok (tok
, ntok
- 1, cidx
);
1537 /* Check if an particular ARC feature is enabled. */
1540 check_cpu_feature (insn_subclass_t sc
)
1542 if (is_code_density_p (sc
) && !(arc_features
& ARC_CD
))
1545 if (is_spfp_p (sc
) && !(arc_features
& ARC_SPFP
))
1548 if (is_dpfp_p (sc
) && !(arc_features
& ARC_DPFP
))
1551 if (is_fpuda_p (sc
) && !(arc_features
& ARC_FPUDA
))
1554 if (is_nps400_p (sc
) && !(arc_features
& ARC_NPS400
))
1560 /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1561 operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG
1562 array and returns TRUE if the flag operands all match, otherwise,
1563 returns FALSE, in which case the FIRST_PFLAG array may have been
1567 parse_opcode_flags (const struct arc_opcode
*opcode
,
1569 struct arc_flags
*first_pflag
)
1572 const unsigned char *flgidx
;
1575 for (i
= 0; i
< nflgs
; i
++)
1576 first_pflag
[i
].flgp
= NULL
;
1578 /* Check the flags. Iterate over the valid flag classes. */
1579 for (flgidx
= opcode
->flags
; *flgidx
; ++flgidx
)
1581 /* Get a valid flag class. */
1582 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1583 const unsigned *flgopridx
;
1585 struct arc_flags
*pflag
= NULL
;
1587 /* Check for extension conditional codes. */
1588 if (ext_condcode
.arc_ext_condcode
1589 && cl_flags
->flag_class
& F_CLASS_EXTEND
)
1591 struct arc_flag_operand
*pf
= ext_condcode
.arc_ext_condcode
;
1594 pflag
= first_pflag
;
1595 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1597 if (!strcmp (pf
->name
, pflag
->name
))
1599 if (pflag
->flgp
!= NULL
)
1612 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1614 const struct arc_flag_operand
*flg_operand
;
1616 pflag
= first_pflag
;
1617 flg_operand
= &arc_flag_operands
[*flgopridx
];
1618 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1620 /* Match against the parsed flags. */
1621 if (!strcmp (flg_operand
->name
, pflag
->name
))
1623 if (pflag
->flgp
!= NULL
)
1626 pflag
->flgp
= flg_operand
;
1628 break; /* goto next flag class and parsed flag. */
1633 if ((cl_flags
->flag_class
& F_CLASS_REQUIRED
) && cl_matches
== 0)
1635 if ((cl_flags
->flag_class
& F_CLASS_OPTIONAL
) && cl_matches
> 1)
1639 /* Did I check all the parsed flags? */
1640 return lnflg
? FALSE
: TRUE
;
1644 /* Search forward through all variants of an opcode looking for a
1647 static const struct arc_opcode
*
1648 find_opcode_match (const struct arc_opcode_hash_entry
*entry
,
1651 struct arc_flags
*first_pflag
,
1655 const struct arc_opcode
*opcode
;
1656 struct arc_opcode_hash_entry_iterator iter
;
1658 int got_cpu_match
= 0;
1659 expressionS bktok
[MAX_INSN_ARGS
];
1663 arc_opcode_hash_entry_iterator_init (&iter
);
1664 memset (&emptyE
, 0, sizeof (emptyE
));
1665 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1668 for (opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
);
1670 opcode
= arc_opcode_hash_entry_iterator_next (entry
, &iter
))
1672 const unsigned char *opidx
;
1674 const expressionS
*t
= &emptyE
;
1676 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1677 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1679 /* Don't match opcodes that don't exist on this
1681 if (!(opcode
->cpu
& arc_target
))
1684 if (!check_cpu_feature (opcode
->subclass
))
1690 /* Check the operands. */
1691 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1693 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1695 /* Only take input from real operands. */
1696 if ((operand
->flags
& ARC_OPERAND_FAKE
)
1697 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
1700 /* When we expect input, make sure we have it. */
1704 /* Match operand type with expression type. */
1705 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1707 case ARC_OPERAND_IR
:
1708 /* Check to be a register. */
1709 if ((tok
[tokidx
].X_op
!= O_register
1710 || !is_ir_num (tok
[tokidx
].X_add_number
))
1711 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1714 /* If expect duplicate, make sure it is duplicate. */
1715 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1717 /* Check for duplicate. */
1718 if (t
->X_op
!= O_register
1719 || !is_ir_num (t
->X_add_number
)
1720 || (regno (t
->X_add_number
) !=
1721 regno (tok
[tokidx
].X_add_number
)))
1725 /* Special handling? */
1726 if (operand
->insert
)
1728 const char *errmsg
= NULL
;
1729 (*operand
->insert
)(0,
1730 regno (tok
[tokidx
].X_add_number
),
1734 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1736 /* Missing argument, create one. */
1737 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1740 tok
[tokidx
].X_op
= O_absent
;
1751 case ARC_OPERAND_BRAKET
:
1752 /* Check if bracket is also in opcode table as
1754 if (tok
[tokidx
].X_op
!= O_bracket
)
1758 case ARC_OPERAND_LIMM
:
1759 case ARC_OPERAND_SIGNED
:
1760 case ARC_OPERAND_UNSIGNED
:
1761 switch (tok
[tokidx
].X_op
)
1769 /* Got an (too) early bracket, check if it is an
1770 ignored operand. N.B. This procedure works only
1771 when bracket is the last operand! */
1772 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1774 /* Insert the missing operand. */
1775 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1778 tok
[tokidx
].X_op
= O_absent
;
1785 const struct arc_aux_reg
*auxr
;
1787 if (opcode
->insn_class
!= AUXREG
)
1789 p
= S_GET_NAME (tok
[tokidx
].X_add_symbol
);
1791 auxr
= hash_find (arc_aux_hash
, p
);
1794 /* We modify the token array here, safe in the
1795 knowledge, that if this was the wrong
1796 choice then the original contents will be
1797 restored from BKTOK. */
1798 tok
[tokidx
].X_op
= O_constant
;
1799 tok
[tokidx
].X_add_number
= auxr
->address
;
1800 ARC_SET_FLAG (tok
[tokidx
].X_add_symbol
, ARC_FLAG_AUX
);
1803 if (tok
[tokidx
].X_op
!= O_constant
)
1808 /* Check the range. */
1809 if (operand
->bits
!= 32
1810 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1812 offsetT min
, max
, val
;
1813 val
= tok
[tokidx
].X_add_number
;
1815 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1817 max
= (1 << (operand
->bits
- 1)) - 1;
1818 min
= -(1 << (operand
->bits
- 1));
1822 max
= (1 << operand
->bits
) - 1;
1826 if (val
< min
|| val
> max
)
1829 /* Check alignmets. */
1830 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1834 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1838 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1840 if (operand
->insert
)
1842 const char *errmsg
= NULL
;
1843 (*operand
->insert
)(0,
1844 tok
[tokidx
].X_add_number
,
1849 else if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1855 /* Check if it is register range. */
1856 if ((tok
[tokidx
].X_add_number
== 0)
1857 && contains_register (tok
[tokidx
].X_add_symbol
)
1858 && contains_register (tok
[tokidx
].X_op_symbol
))
1862 regs
= get_register (tok
[tokidx
].X_add_symbol
);
1864 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
1865 if (operand
->insert
)
1867 const char *errmsg
= NULL
;
1868 (*operand
->insert
)(0,
1880 if (operand
->default_reloc
== 0)
1881 goto match_failed
; /* The operand needs relocation. */
1883 /* Relocs requiring long immediate. FIXME! make it
1884 generic and move it to a function. */
1885 switch (tok
[tokidx
].X_md
)
1894 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
1897 if (!generic_reloc_p (operand
->default_reloc
))
1904 /* If expect duplicate, make sure it is duplicate. */
1905 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1907 if (t
->X_op
== O_illegal
1908 || t
->X_op
== O_absent
1909 || t
->X_op
== O_register
1910 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
1917 /* Everything else should have been fake. */
1925 /* Setup ready for flag parsing. */
1926 if (!parse_opcode_flags (opcode
, nflgs
, first_pflag
))
1930 /* Possible match -- did we use all of our input? */
1940 /* Restore the original parameters. */
1941 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
1946 *pcpumatch
= got_cpu_match
;
1951 /* Swap operand tokens. */
1954 swap_operand (expressionS
*operand_array
,
1956 unsigned destination
)
1958 expressionS cpy_operand
;
1959 expressionS
*src_operand
;
1960 expressionS
*dst_operand
;
1963 if (source
== destination
)
1966 src_operand
= &operand_array
[source
];
1967 dst_operand
= &operand_array
[destination
];
1968 size
= sizeof (expressionS
);
1970 /* Make copy of operand to swap with and swap. */
1971 memcpy (&cpy_operand
, dst_operand
, size
);
1972 memcpy (dst_operand
, src_operand
, size
);
1973 memcpy (src_operand
, &cpy_operand
, size
);
1976 /* Check if *op matches *tok type.
1977 Returns FALSE if they don't match, TRUE if they match. */
1980 pseudo_operand_match (const expressionS
*tok
,
1981 const struct arc_operand_operation
*op
)
1983 offsetT min
, max
, val
;
1985 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
1991 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
1993 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
1995 val
= tok
->X_add_number
+ op
->count
;
1996 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
1998 max
= (1 << (operand_real
->bits
- 1)) - 1;
1999 min
= -(1 << (operand_real
->bits
- 1));
2003 max
= (1 << operand_real
->bits
) - 1;
2006 if (min
<= val
&& val
<= max
)
2012 /* Handle all symbols as long immediates or signed 9. */
2013 if (operand_real
->flags
& ARC_OPERAND_LIMM
||
2014 ((operand_real
->flags
& ARC_OPERAND_SIGNED
) && operand_real
->bits
== 9))
2019 if (operand_real
->flags
& ARC_OPERAND_IR
)
2024 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2035 /* Find pseudo instruction in array. */
2037 static const struct arc_pseudo_insn
*
2038 find_pseudo_insn (const char *opname
,
2040 const expressionS
*tok
)
2042 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2043 const struct arc_operand_operation
*op
;
2047 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
2049 pseudo_insn
= &arc_pseudo_insns
[i
];
2050 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
2052 op
= pseudo_insn
->operand
;
2053 for (j
= 0; j
< ntok
; ++j
)
2054 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
2057 /* Found the right instruction. */
2065 /* Assumes the expressionS *tok is of sufficient size. */
2067 static const struct arc_opcode_hash_entry
*
2068 find_special_case_pseudo (const char *opname
,
2072 struct arc_flags
*pflags
)
2074 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2075 const struct arc_operand_operation
*operand_pseudo
;
2076 const struct arc_operand
*operand_real
;
2078 char construct_operand
[MAX_CONSTR_STR
];
2080 /* Find whether opname is in pseudo instruction array. */
2081 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
2083 if (pseudo_insn
== NULL
)
2086 /* Handle flag, Limited to one flag at the moment. */
2087 if (pseudo_insn
->flag_r
!= NULL
)
2088 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
2089 MAX_INSN_FLGS
- *nflgs
);
2091 /* Handle operand operations. */
2092 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2094 operand_pseudo
= &pseudo_insn
->operand
[i
];
2095 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
2097 if (operand_real
->flags
& ARC_OPERAND_BRAKET
&&
2098 !operand_pseudo
->needs_insert
)
2101 /* Has to be inserted (i.e. this token does not exist yet). */
2102 if (operand_pseudo
->needs_insert
)
2104 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2106 tok
[i
].X_op
= O_bracket
;
2111 /* Check if operand is a register or constant and handle it
2113 if (operand_real
->flags
& ARC_OPERAND_IR
)
2114 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
2115 operand_pseudo
->count
);
2117 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
2118 operand_pseudo
->count
);
2120 tokenize_arguments (construct_operand
, &tok
[i
], 1);
2124 else if (operand_pseudo
->count
)
2126 /* Operand number has to be adjusted accordingly (by operand
2128 switch (tok
[i
].X_op
)
2131 tok
[i
].X_add_number
+= operand_pseudo
->count
;
2144 /* Swap operands if necessary. Only supports one swap at the
2146 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2148 operand_pseudo
= &pseudo_insn
->operand
[i
];
2150 if (operand_pseudo
->swap_operand_idx
== i
)
2153 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
2155 /* Prevent a swap back later by breaking out. */
2159 return arc_find_opcode (pseudo_insn
->mnemonic_r
);
2162 static const struct arc_opcode_hash_entry
*
2163 find_special_case_flag (const char *opname
,
2165 struct arc_flags
*pflags
)
2169 unsigned flag_idx
, flag_arr_idx
;
2170 size_t flaglen
, oplen
;
2171 const struct arc_flag_special
*arc_flag_special_opcode
;
2172 const struct arc_opcode_hash_entry
*entry
;
2174 /* Search for special case instruction. */
2175 for (i
= 0; i
< arc_num_flag_special
; i
++)
2177 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
2178 oplen
= strlen (arc_flag_special_opcode
->name
);
2180 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
2183 /* Found a potential special case instruction, now test for
2185 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
2187 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
2189 break; /* End of array, nothing found. */
2191 flagnm
= arc_flag_operands
[flag_idx
].name
;
2192 flaglen
= strlen (flagnm
);
2193 if (strcmp (opname
+ oplen
, flagnm
) == 0)
2195 entry
= arc_find_opcode (arc_flag_special_opcode
->name
);
2197 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
2199 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
2200 pflags
[*nflgs
].name
[flaglen
] = '\0';
2209 /* The long instructions are not stored in a hash (there's not many of
2210 them) and so there's no arc_opcode_hash_entry structure to return. This
2211 helper function for find_special_case_long_opcode takes an arc_opcode
2212 result and places it into a fake arc_opcode_hash_entry that points to
2213 the single arc_opcode OPCODE, which is then returned. */
2215 static const struct arc_opcode_hash_entry
*
2216 build_fake_opcode_hash_entry (const struct arc_opcode
*opcode
)
2218 static struct arc_opcode_hash_entry entry
;
2219 static struct arc_opcode tmp
[2];
2220 static const struct arc_opcode
*ptr
[2];
2222 memcpy (&tmp
[0], opcode
, sizeof (struct arc_opcode
));
2223 memset (&tmp
[1], 0, sizeof (struct arc_opcode
));
2232 /* Used by the assembler to match the list of tokens against a long (48 or
2233 64 bits) instruction. If a matching long instruction is found, then
2234 some of the tokens are consumed in this function and converted into a
2235 single LIMM value, which is then added to the end of the token list,
2236 where it will be consumed by a LIMM operand that exists in the base
2237 opcode of the long instruction. */
2239 static const struct arc_opcode_hash_entry
*
2240 find_special_case_long_opcode (const char *opname
,
2241 int *ntok ATTRIBUTE_UNUSED
,
2242 expressionS
*tok ATTRIBUTE_UNUSED
,
2244 struct arc_flags
*pflags
)
2248 if (*ntok
== MAX_INSN_ARGS
)
2251 for (i
= 0; i
< arc_num_long_opcodes
; ++i
)
2253 struct arc_opcode fake_opcode
;
2254 const struct arc_opcode
*opcode
;
2255 struct arc_insn insn
;
2256 expressionS
*limm_token
;
2258 opcode
= &arc_long_opcodes
[i
].base_opcode
;
2260 if (!(opcode
->cpu
& arc_target
))
2263 if (!check_cpu_feature (opcode
->subclass
))
2266 if (strcmp (opname
, opcode
->name
) != 0)
2269 /* Check that the flags are a match. */
2270 if (!parse_opcode_flags (opcode
, *nflgs
, pflags
))
2273 /* Parse the LIMM operands into the LIMM template. */
2274 memset (&fake_opcode
, 0, sizeof (fake_opcode
));
2275 fake_opcode
.name
= "fake limm";
2276 fake_opcode
.opcode
= arc_long_opcodes
[i
].limm_template
;
2277 fake_opcode
.mask
= arc_long_opcodes
[i
].limm_mask
;
2278 fake_opcode
.cpu
= opcode
->cpu
;
2279 fake_opcode
.insn_class
= opcode
->insn_class
;
2280 fake_opcode
.subclass
= opcode
->subclass
;
2281 memcpy (&fake_opcode
.operands
[0],
2282 &arc_long_opcodes
[i
].operands
,
2284 /* Leave fake_opcode.flags as zero. */
2286 pr_debug ("Calling assemble_insn to build fake limm value\n");
2287 assemble_insn (&fake_opcode
, tok
, *ntok
,
2289 pr_debug (" got limm value: 0x%x\n", insn
.insn
);
2291 /* Now create a new token at the end of the token array (We know this
2292 is safe as the token array is always created with enough space for
2293 MAX_INSN_ARGS, and we check at the start at the start of this
2294 function that we're not there yet). This new token will
2295 correspond to a LIMM operand that will be contained in the
2296 base_opcode of the arc_long_opcode. */
2297 limm_token
= &tok
[(*ntok
)];
2300 /* Modify the LIMM token to hold the constant. */
2301 limm_token
->X_op
= O_constant
;
2302 limm_token
->X_add_number
= insn
.insn
;
2304 /* Return the base opcode. */
2305 return build_fake_opcode_hash_entry (opcode
);
2311 /* Used to find special case opcode. */
2313 static const struct arc_opcode_hash_entry
*
2314 find_special_case (const char *opname
,
2316 struct arc_flags
*pflags
,
2320 const struct arc_opcode_hash_entry
*entry
;
2322 entry
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
2325 entry
= find_special_case_flag (opname
, nflgs
, pflags
);
2328 entry
= find_special_case_long_opcode (opname
, ntok
, tok
, nflgs
, pflags
);
2333 /* Given an opcode name, pre-tockenized set of argumenst and the
2334 opcode flags, take it all the way through emission. */
2337 assemble_tokens (const char *opname
,
2340 struct arc_flags
*pflags
,
2343 bfd_boolean found_something
= FALSE
;
2344 const struct arc_opcode_hash_entry
*entry
;
2347 /* Search opcodes. */
2348 entry
= arc_find_opcode (opname
);
2350 /* Couldn't find opcode conventional way, try special cases. */
2352 entry
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
2356 const struct arc_opcode
*opcode
;
2358 pr_debug ("%s:%d: assemble_tokens: %s\n",
2359 frag_now
->fr_file
, frag_now
->fr_line
, opname
);
2360 found_something
= TRUE
;
2361 opcode
= find_opcode_match (entry
, tok
, &ntok
, pflags
,
2365 struct arc_insn insn
;
2367 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
2373 if (found_something
)
2376 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
2378 as_bad (_("opcode '%s' not supported for target %s"), opname
,
2382 as_bad (_("unknown opcode '%s'"), opname
);
2385 /* The public interface to the instruction assembler. */
2388 md_assemble (char *str
)
2391 expressionS tok
[MAX_INSN_ARGS
];
2394 struct arc_flags flags
[MAX_INSN_FLGS
];
2396 /* Split off the opcode. */
2397 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
2398 opname
= xmemdup0 (str
, opnamelen
);
2400 /* Signalize we are assmbling the instructions. */
2401 assembling_insn
= TRUE
;
2403 /* Tokenize the flags. */
2404 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2406 as_bad (_("syntax error"));
2410 /* Scan up to the end of the mnemonic which must end in space or end
2413 for (; *str
!= '\0'; str
++)
2417 /* Tokenize the rest of the line. */
2418 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2420 as_bad (_("syntax error"));
2424 /* Finish it off. */
2425 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2426 assembling_insn
= FALSE
;
2429 /* Callback to insert a register into the hash table. */
2432 declare_register (const char *name
, int number
)
2435 symbolS
*regS
= symbol_create (name
, reg_section
,
2436 number
, &zero_address_frag
);
2438 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
2440 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2444 /* Construct symbols for each of the general registers. */
2447 declare_register_set (void)
2450 for (i
= 0; i
< 64; ++i
)
2454 sprintf (name
, "r%d", i
);
2455 declare_register (name
, i
);
2456 if ((i
& 0x01) == 0)
2458 sprintf (name
, "r%dr%d", i
, i
+1);
2459 declare_register (name
, i
);
2464 /* Port-specific assembler initialization. This function is called
2465 once, at assembler startup time. */
2470 const struct arc_opcode
*opcode
= arc_opcodes
;
2472 if (!mach_type_specified_p
)
2473 arc_select_cpu (TARGET_WITH_CPU
);
2475 /* The endianness can be chosen "at the factory". */
2476 target_big_endian
= byte_order
== BIG_ENDIAN
;
2478 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, arc_mach_type
))
2479 as_warn (_("could not set architecture and machine"));
2481 /* Set elf header flags. */
2482 bfd_set_private_flags (stdoutput
, arc_eflag
);
2484 /* Set up a hash table for the instructions. */
2485 arc_opcode_hash
= hash_new ();
2486 if (arc_opcode_hash
== NULL
)
2487 as_fatal (_("Virtual memory exhausted"));
2489 /* Initialize the hash table with the insns. */
2492 const char *name
= opcode
->name
;
2494 arc_insert_opcode (opcode
);
2496 while (++opcode
&& opcode
->name
2497 && (opcode
->name
== name
2498 || !strcmp (opcode
->name
, name
)))
2500 }while (opcode
->name
);
2502 /* Register declaration. */
2503 arc_reg_hash
= hash_new ();
2504 if (arc_reg_hash
== NULL
)
2505 as_fatal (_("Virtual memory exhausted"));
2507 declare_register_set ();
2508 declare_register ("gp", 26);
2509 declare_register ("fp", 27);
2510 declare_register ("sp", 28);
2511 declare_register ("ilink", 29);
2512 declare_register ("ilink1", 29);
2513 declare_register ("ilink2", 30);
2514 declare_register ("blink", 31);
2516 /* XY memory registers. */
2517 declare_register ("x0_u0", 32);
2518 declare_register ("x0_u1", 33);
2519 declare_register ("x1_u0", 34);
2520 declare_register ("x1_u1", 35);
2521 declare_register ("x2_u0", 36);
2522 declare_register ("x2_u1", 37);
2523 declare_register ("x3_u0", 38);
2524 declare_register ("x3_u1", 39);
2525 declare_register ("y0_u0", 40);
2526 declare_register ("y0_u1", 41);
2527 declare_register ("y1_u0", 42);
2528 declare_register ("y1_u1", 43);
2529 declare_register ("y2_u0", 44);
2530 declare_register ("y2_u1", 45);
2531 declare_register ("y3_u0", 46);
2532 declare_register ("y3_u1", 47);
2533 declare_register ("x0_nu", 48);
2534 declare_register ("x1_nu", 49);
2535 declare_register ("x2_nu", 50);
2536 declare_register ("x3_nu", 51);
2537 declare_register ("y0_nu", 52);
2538 declare_register ("y1_nu", 53);
2539 declare_register ("y2_nu", 54);
2540 declare_register ("y3_nu", 55);
2542 declare_register ("mlo", 57);
2543 declare_register ("mmid", 58);
2544 declare_register ("mhi", 59);
2546 declare_register ("acc1", 56);
2547 declare_register ("acc2", 57);
2549 declare_register ("lp_count", 60);
2550 declare_register ("pcl", 63);
2552 /* Initialize the last instructions. */
2553 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2555 /* Aux register declaration. */
2556 arc_aux_hash
= hash_new ();
2557 if (arc_aux_hash
== NULL
)
2558 as_fatal (_("Virtual memory exhausted"));
2560 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
2562 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
2566 if (!(auxr
->cpu
& arc_target
))
2569 if ((auxr
->subclass
!= NONE
)
2570 && !check_cpu_feature (auxr
->subclass
))
2573 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
2575 as_fatal (_("internal error: can't hash aux register '%s': %s"),
2576 auxr
->name
, retval
);
2580 /* Write a value out to the object file, using the appropriate
2584 md_number_to_chars (char *buf
,
2588 if (target_big_endian
)
2589 number_to_chars_bigendian (buf
, val
, n
);
2591 number_to_chars_littleendian (buf
, val
, n
);
2594 /* Round up a section size to the appropriate boundary. */
2597 md_section_align (segT segment
,
2600 int align
= bfd_get_section_alignment (stdoutput
, segment
);
2602 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2605 /* The location from which a PC relative jump should be calculated,
2606 given a PC relative reloc. */
2609 md_pcrel_from_section (fixS
*fixP
,
2612 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2614 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2616 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2617 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2618 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2620 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2622 /* The symbol is undefined (or is defined but not in this section).
2623 Let the linker figure it out. */
2627 if ((int) fixP
->fx_r_type
< 0)
2629 /* These are the "internal" relocations. Align them to
2630 32 bit boundary (PCL), for the moment. */
2635 switch (fixP
->fx_r_type
)
2637 case BFD_RELOC_ARC_PC32
:
2638 /* The hardware calculates relative to the start of the
2639 insn, but this relocation is relative to location of the
2640 LIMM, compensate. The base always needs to be
2641 substracted by 4 as we do not support this type of PCrel
2642 relocation for short instructions. */
2645 case BFD_RELOC_ARC_PLT32
:
2646 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2647 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2648 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2649 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2651 case BFD_RELOC_ARC_S21H_PCREL
:
2652 case BFD_RELOC_ARC_S25H_PCREL
:
2653 case BFD_RELOC_ARC_S13_PCREL
:
2654 case BFD_RELOC_ARC_S21W_PCREL
:
2655 case BFD_RELOC_ARC_S25W_PCREL
:
2659 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2660 _("unhandled reloc %s in md_pcrel_from_section"),
2661 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2666 pr_debug ("pcrel from %"BFD_VMA_FMT
"x + %lx = %"BFD_VMA_FMT
"x, "
2667 "symbol: %s (%"BFD_VMA_FMT
"x)\n",
2668 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
2669 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2670 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
2675 /* Given a BFD relocation find the coresponding operand. */
2677 static const struct arc_operand
*
2678 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2682 for (i
= 0; i
< arc_num_operands
; i
++)
2683 if (arc_operands
[i
].default_reloc
== reloc
)
2684 return &arc_operands
[i
];
2688 /* Insert an operand value into an instruction. */
2691 insert_operand (unsigned insn
,
2692 const struct arc_operand
*operand
,
2697 offsetT min
= 0, max
= 0;
2699 if (operand
->bits
!= 32
2700 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2701 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2703 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2705 max
= (1 << (operand
->bits
- 1)) - 1;
2706 min
= -(1 << (operand
->bits
- 1));
2710 max
= (1 << operand
->bits
) - 1;
2714 if (val
< min
|| val
> max
)
2715 as_bad_value_out_of_range (_("operand"),
2716 val
, min
, max
, file
, line
);
2719 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2720 min
, val
, max
, insn
);
2722 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2724 as_bad_where (file
, line
,
2725 _("Unaligned operand. Needs to be 32bit aligned"));
2727 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2729 as_bad_where (file
, line
,
2730 _("Unaligned operand. Needs to be 16bit aligned"));
2732 if (operand
->insert
)
2734 const char *errmsg
= NULL
;
2736 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2738 as_warn_where (file
, line
, "%s", errmsg
);
2742 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2744 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2746 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2749 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2754 /* Apply a fixup to the object code. At this point all symbol values
2755 should be fully resolved, and we attempt to completely resolve the
2756 reloc. If we can not do that, we determine the correct reloc code
2757 and put it back in the fixup. To indicate that a fixup has been
2758 eliminated, set fixP->fx_done. */
2761 md_apply_fix (fixS
*fixP
,
2765 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2766 valueT value
= *valP
;
2768 symbolS
*fx_addsy
, *fx_subsy
;
2770 segT add_symbol_segment
= absolute_section
;
2771 segT sub_symbol_segment
= absolute_section
;
2772 const struct arc_operand
*operand
= NULL
;
2773 extended_bfd_reloc_code_real_type reloc
;
2775 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2776 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2777 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2778 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2781 fx_addsy
= fixP
->fx_addsy
;
2782 fx_subsy
= fixP
->fx_subsy
;
2787 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2791 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2792 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2793 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2795 resolve_symbol_value (fx_subsy
);
2796 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2798 if (sub_symbol_segment
== absolute_section
)
2800 /* The symbol is really a constant. */
2801 fx_offset
-= S_GET_VALUE (fx_subsy
);
2806 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2807 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2808 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
2809 segment_name (add_symbol_segment
),
2810 S_GET_NAME (fx_subsy
),
2811 segment_name (sub_symbol_segment
));
2817 && !S_IS_WEAK (fx_addsy
))
2819 if (add_symbol_segment
== seg
2822 value
+= S_GET_VALUE (fx_addsy
);
2823 value
-= md_pcrel_from_section (fixP
, seg
);
2825 fixP
->fx_pcrel
= FALSE
;
2827 else if (add_symbol_segment
== absolute_section
)
2829 value
= fixP
->fx_offset
;
2830 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2832 fixP
->fx_pcrel
= FALSE
;
2837 fixP
->fx_done
= TRUE
;
2842 && ((S_IS_DEFINED (fx_addsy
)
2843 && S_GET_SEGMENT (fx_addsy
) != seg
)
2844 || S_IS_WEAK (fx_addsy
)))
2845 value
+= md_pcrel_from_section (fixP
, seg
);
2847 switch (fixP
->fx_r_type
)
2849 case BFD_RELOC_ARC_32_ME
:
2850 /* This is a pc-relative value in a LIMM. Adjust it to the
2851 address of the instruction not to the address of the
2852 LIMM. Note: it is not anylonger valid this afirmation as
2853 the linker consider ARC_PC32 a fixup to entire 64 bit
2855 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
2858 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
2860 case BFD_RELOC_ARC_PC32
:
2861 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2864 if ((int) fixP
->fx_r_type
< 0)
2865 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2871 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2872 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2873 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2874 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2878 /* Now check for TLS relocations. */
2879 reloc
= fixP
->fx_r_type
;
2882 case BFD_RELOC_ARC_TLS_DTPOFF
:
2883 case BFD_RELOC_ARC_TLS_LE_32
:
2887 case BFD_RELOC_ARC_TLS_GD_GOT
:
2888 case BFD_RELOC_ARC_TLS_IE_GOT
:
2889 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2892 case BFD_RELOC_ARC_TLS_GD_LD
:
2893 gas_assert (!fixP
->fx_offset
);
2896 = (S_GET_VALUE (fixP
->fx_subsy
)
2897 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
2898 fixP
->fx_subsy
= NULL
;
2900 case BFD_RELOC_ARC_TLS_GD_CALL
:
2901 /* These two relocs are there just to allow ld to change the tls
2902 model for this symbol, by patching the code. The offset -
2903 and scale, if any - will be installed by the linker. */
2904 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2907 case BFD_RELOC_ARC_TLS_LE_S9
:
2908 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
2909 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2921 /* Addjust the value if we have a constant. */
2924 /* For hosts with longs bigger than 32-bits make sure that the top
2925 bits of a 32-bit negative value read in by the parser are set,
2926 so that the correct comparisons are made. */
2927 if (value
& 0x80000000)
2928 value
|= (-1UL << 31);
2930 reloc
= fixP
->fx_r_type
;
2938 case BFD_RELOC_ARC_32_PCREL
:
2939 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
2942 case BFD_RELOC_ARC_GOTPC32
:
2943 /* I cannot fix an GOTPC relocation because I need to relax it
2944 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2945 as_bad (_("Unsupported operation on reloc"));
2948 case BFD_RELOC_ARC_TLS_DTPOFF
:
2949 case BFD_RELOC_ARC_TLS_LE_32
:
2950 gas_assert (!fixP
->fx_addsy
);
2951 gas_assert (!fixP
->fx_subsy
);
2953 case BFD_RELOC_ARC_GOTOFF
:
2954 case BFD_RELOC_ARC_32_ME
:
2955 case BFD_RELOC_ARC_PC32
:
2956 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2959 case BFD_RELOC_ARC_PLT32
:
2960 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2963 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2964 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2967 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2968 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
2971 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2972 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2975 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2976 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
2978 case BFD_RELOC_ARC_S25W_PCREL
:
2979 case BFD_RELOC_ARC_S21W_PCREL
:
2980 case BFD_RELOC_ARC_S21H_PCREL
:
2981 case BFD_RELOC_ARC_S25H_PCREL
:
2982 case BFD_RELOC_ARC_S13_PCREL
:
2984 operand
= find_operand_for_reloc (reloc
);
2985 gas_assert (operand
);
2990 if ((int) fixP
->fx_r_type
>= 0)
2991 as_fatal (_("unhandled relocation type %s"),
2992 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2994 /* The rest of these fixups needs to be completely resolved as
2996 if (fixP
->fx_addsy
!= 0
2997 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
2998 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2999 _("non-absolute expression in constant field"));
3001 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
3002 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
3007 if (target_big_endian
)
3009 switch (fixP
->fx_size
)
3012 insn
= bfd_getb32 (fixpos
);
3015 insn
= bfd_getb16 (fixpos
);
3018 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3019 _("unknown fixup size"));
3025 switch (fixP
->fx_size
)
3028 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
3031 insn
= bfd_getl16 (fixpos
);
3034 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3035 _("unknown fixup size"));
3039 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
3040 fixP
->fx_file
, fixP
->fx_line
);
3042 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
3045 /* Prepare machine-dependent frags for relaxation.
3047 Called just before relaxation starts. Any symbol that is now undefined
3048 will not become defined.
3050 Return the correct fr_subtype in the frag.
3052 Return the initial "guess for fr_var" to caller. The guess for fr_var
3053 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3054 or fr_var contributes to our returned value.
3056 Although it may not be explicit in the frag, pretend
3057 fr_var starts with a value. */
3060 md_estimate_size_before_relax (fragS
*fragP
,
3065 /* If the symbol is not located within the same section AND it's not
3066 an absolute section, use the maximum. OR if the symbol is a
3067 constant AND the insn is by nature not pc-rel, use the maximum.
3068 OR if the symbol is being equated against another symbol, use the
3069 maximum. OR if the symbol is weak use the maximum. */
3070 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
3071 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
3072 || (symbol_constant_p (fragP
->fr_symbol
)
3073 && !fragP
->tc_frag_data
.pcrel
)
3074 || symbol_equated_p (fragP
->fr_symbol
)
3075 || S_IS_WEAK (fragP
->fr_symbol
))
3077 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
3078 ++fragP
->fr_subtype
;
3081 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3082 fragP
->fr_var
= growth
;
3084 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3085 fragP
->fr_file
, fragP
->fr_line
, growth
);
3090 /* Translate internal representation of relocation info to BFD target
3094 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
3098 bfd_reloc_code_real_type code
;
3100 reloc
= XNEW (arelent
);
3101 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3102 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3103 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3105 /* Make sure none of our internal relocations make it this far.
3106 They'd better have been fully resolved by this point. */
3107 gas_assert ((int) fixP
->fx_r_type
> 0);
3109 code
= fixP
->fx_r_type
;
3111 /* if we have something like add gp, pcl,
3112 _GLOBAL_OFFSET_TABLE_@gotpc. */
3113 if (code
== BFD_RELOC_ARC_GOTPC32
3115 && fixP
->fx_addsy
== GOT_symbol
)
3116 code
= BFD_RELOC_ARC_GOTPC
;
3118 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
3119 if (reloc
->howto
== NULL
)
3121 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3122 _("cannot represent `%s' relocation in object file"),
3123 bfd_get_reloc_code_name (code
));
3127 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
3128 as_fatal (_("internal error? cannot generate `%s' relocation"),
3129 bfd_get_reloc_code_name (code
));
3131 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
3133 reloc
->addend
= fixP
->fx_offset
;
3138 /* Perform post-processing of machine-dependent frags after relaxation.
3139 Called after relaxation is finished.
3140 In: Address of frag.
3141 fr_type == rs_machine_dependent.
3142 fr_subtype is what the address relaxed to.
3144 Out: Any fixS:s and constants are set up. */
3147 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
3148 segT segment ATTRIBUTE_UNUSED
,
3151 const relax_typeS
*table_entry
;
3153 const struct arc_opcode
*opcode
;
3154 struct arc_insn insn
;
3156 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
3158 fix
= (fragP
->fr_fix
< 0 ? 0 : fragP
->fr_fix
);
3159 dest
= fragP
->fr_literal
+ fix
;
3160 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
3162 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3163 "var: %"BFD_VMA_FMT
"d\n",
3164 fragP
->fr_file
, fragP
->fr_line
,
3165 fragP
->fr_subtype
, fix
, fragP
->fr_var
);
3167 if (fragP
->fr_subtype
<= 0
3168 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
3169 as_fatal (_("no relaxation found for this instruction."));
3171 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
3173 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
3174 relax_arg
->nflg
, &insn
);
3176 apply_fixups (&insn
, fragP
, fix
);
3178 size
= insn
.short_insn
? (insn
.has_limm
? 6 : 2) : (insn
.has_limm
? 8 : 4);
3179 gas_assert (table_entry
->rlx_length
== size
);
3180 emit_insn0 (&insn
, dest
, TRUE
);
3182 fragP
->fr_fix
+= table_entry
->rlx_length
;
3186 /* We have no need to default values of symbols. We could catch
3187 register names here, but that is handled by inserting them all in
3188 the symbol table to begin with. */
3191 md_undefined_symbol (char *name
)
3193 /* The arc abi demands that a GOT[0] should be referencible as
3194 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3195 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3197 && (*(name
+1) == 'G')
3198 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0))
3200 && (*(name
+1) == 'D')
3201 && (strcmp (name
, DYNAMIC_STRUCT_NAME
) == 0)))
3205 if (symbol_find (name
))
3206 as_bad ("GOT already in symbol table");
3208 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
3209 (valueT
) 0, &zero_address_frag
);
3216 /* Turn a string in input_line_pointer into a floating point constant
3217 of type type, and store the appropriate bytes in *litP. The number
3218 of LITTLENUMS emitted is stored in *sizeP. An error message is
3219 returned, or NULL on OK. */
3222 md_atof (int type
, char *litP
, int *sizeP
)
3224 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
3227 /* Called for any expression that can not be recognized. When the
3228 function is called, `input_line_pointer' will point to the start of
3232 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
3234 char *p
= input_line_pointer
;
3237 input_line_pointer
++;
3238 expressionP
->X_op
= O_symbol
;
3239 expression (expressionP
);
3243 /* This function is called from the function 'expression', it attempts
3244 to parse special names (in our case register names). It fills in
3245 the expression with the identified register. It returns TRUE if
3246 it is a register and FALSE otherwise. */
3249 arc_parse_name (const char *name
,
3250 struct expressionS
*e
)
3254 if (!assembling_insn
)
3257 /* Handle only registers. */
3258 if (e
->X_op
!= O_absent
)
3261 sym
= hash_find (arc_reg_hash
, name
);
3264 e
->X_op
= O_register
;
3265 e
->X_add_number
= S_GET_VALUE (sym
);
3272 Invocation line includes a switch not recognized by the base assembler.
3273 See if it's a processor-specific option.
3275 New options (supported) are:
3277 -mcpu=<cpu name> Assemble for selected processor
3278 -EB/-mbig-endian Big-endian
3279 -EL/-mlittle-endian Little-endian
3280 -mrelax Enable relaxation
3282 The following CPU names are recognized:
3283 arc600, arc700, arcem, archs, nps400. */
3286 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
3292 return md_parse_option (OPTION_MCPU
, "arc600");
3295 return md_parse_option (OPTION_MCPU
, "arc700");
3298 return md_parse_option (OPTION_MCPU
, "arcem");
3301 return md_parse_option (OPTION_MCPU
, "archs");
3305 arc_select_cpu (arg
);
3306 mach_type_specified_p
= TRUE
;
3311 arc_target_format
= "elf32-bigarc";
3312 byte_order
= BIG_ENDIAN
;
3316 arc_target_format
= "elf32-littlearc";
3317 byte_order
= LITTLE_ENDIAN
;
3321 /* This option has an effect only on ARC EM. */
3322 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3323 arc_features
|= ARC_CD
;
3325 as_warn (_("Code density option invalid for selected CPU"));
3329 relaxation_state
= 1;
3333 arc_features
|= ARC_NPS400
;
3337 arc_features
|= ARC_SPFP
;
3341 arc_features
|= ARC_DPFP
;
3345 /* This option has an effect only on ARC EM. */
3346 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3347 arc_features
|= ARC_FPUDA
;
3349 as_warn (_("FPUDA invalid for selected CPU"));
3352 /* Dummy options are accepted but have no effect. */
3353 case OPTION_USER_MODE
:
3354 case OPTION_LD_EXT_MASK
:
3357 case OPTION_BARREL_SHIFT
:
3358 case OPTION_MIN_MAX
:
3363 case OPTION_XMAC_D16
:
3364 case OPTION_XMAC_24
:
3365 case OPTION_DSP_PACKA
:
3368 case OPTION_TELEPHONY
:
3369 case OPTION_XYMEMORY
:
3383 md_show_usage (FILE *stream
)
3385 fprintf (stream
, _("ARC-specific assembler options:\n"));
3387 fprintf (stream
, " -mcpu=<cpu name>\t assemble for CPU <cpu name> "
3388 "(default: %s)\n", TARGET_WITH_CPU
);
3389 fprintf (stream
, " -mcpu=nps400\t\t same as -mcpu=arc700 -mnps400\n");
3390 fprintf (stream
, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3391 fprintf (stream
, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3392 fprintf (stream
, " -mEM\t\t\t same as -mcpu=arcem\n");
3393 fprintf (stream
, " -mHS\t\t\t same as -mcpu=archs\n");
3395 fprintf (stream
, " -mnps400\t\t enable NPS-400 extended instructions\n");
3396 fprintf (stream
, " -mspfp\t\t enable single-precision floating point instructions\n");
3397 fprintf (stream
, " -mdpfp\t\t enable double-precision floating point instructions\n");
3398 fprintf (stream
, " -mfpuda\t\t enable double-precision assist floating "
3399 "point\n\t\t\t instructions for ARC EM\n");
3402 " -mcode-density\t enable code density option for ARC EM\n");
3404 fprintf (stream
, _("\
3405 -EB assemble code for a big-endian cpu\n"));
3406 fprintf (stream
, _("\
3407 -EL assemble code for a little-endian cpu\n"));
3408 fprintf (stream
, _("\
3409 -mrelax enable relaxation\n"));
3411 fprintf (stream
, _("The following ARC-specific assembler options are "
3412 "deprecated and are accepted\nfor compatibility only:\n"));
3414 fprintf (stream
, _(" -mEA\n"
3415 " -mbarrel-shifter\n"
3416 " -mbarrel_shifter\n"
3421 " -mld-extension-reg-mask\n"
3437 " -muser-mode-only\n"
3441 /* Find the proper relocation for the given opcode. */
3443 static extended_bfd_reloc_code_real_type
3444 find_reloc (const char *name
,
3445 const char *opcodename
,
3446 const struct arc_flags
*pflags
,
3448 extended_bfd_reloc_code_real_type reloc
)
3452 bfd_boolean found_flag
, tmp
;
3453 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
3455 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
3457 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3459 /* Find the entry. */
3460 if (strcmp (name
, r
->name
))
3462 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3469 unsigned * psflg
= (unsigned *)r
->flags
;
3473 for (j
= 0; j
< nflg
; j
++)
3474 if (!strcmp (pflags
[j
].name
,
3475 arc_flag_operands
[*psflg
].name
))
3496 if (reloc
!= r
->oldreloc
)
3503 if (ret
== BFD_RELOC_UNUSED
)
3504 as_bad (_("Unable to find %s relocation for instruction %s"),
3509 /* All the symbol types that are allowed to be used for
3513 may_relax_expr (expressionS tok
)
3515 /* Check if we have unrelaxable relocs. */
3540 /* Checks if flags are in line with relaxable insn. */
3543 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3544 const struct arc_flags
*pflags
,
3547 unsigned flag_class
,
3552 const struct arc_flag_operand
*flag_opand
;
3553 int i
, counttrue
= 0;
3555 /* Iterate through flags classes. */
3556 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3558 /* Iterate through flags in flag class. */
3559 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3562 flag_opand
= &arc_flag_operands
[flag
];
3563 /* Iterate through flags in ins to compare. */
3564 for (i
= 0; i
< nflgs
; ++i
)
3566 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3577 /* If counttrue == nflgs, then all flags have been found. */
3578 return (counttrue
== nflgs
? TRUE
: FALSE
);
3581 /* Checks if operands are in line with relaxable insn. */
3584 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3585 const expressionS
*tok
,
3588 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3591 while (*operand
!= EMPTY
)
3593 const expressionS
*epr
= &tok
[i
];
3595 if (i
!= 0 && i
>= ntok
)
3601 if (!(epr
->X_op
== O_multiply
3602 || epr
->X_op
== O_divide
3603 || epr
->X_op
== O_modulus
3604 || epr
->X_op
== O_add
3605 || epr
->X_op
== O_subtract
3606 || epr
->X_op
== O_symbol
))
3612 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3616 if (epr
->X_op
!= O_register
)
3621 if (epr
->X_op
!= O_register
)
3624 switch (epr
->X_add_number
)
3626 case 0: case 1: case 2: case 3:
3627 case 12: case 13: case 14: case 15:
3634 case REGISTER_NO_GP
:
3635 if ((epr
->X_op
!= O_register
)
3636 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3641 if (epr
->X_op
!= O_bracket
)
3646 /* Don't understand, bail out. */
3652 operand
= &ins
->operands
[i
];
3655 return (i
== ntok
? TRUE
: FALSE
);
3658 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3661 relax_insn_p (const struct arc_opcode
*opcode
,
3662 const expressionS
*tok
,
3664 const struct arc_flags
*pflags
,
3668 bfd_boolean rv
= FALSE
;
3670 /* Check the relaxation table. */
3671 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3673 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3675 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3676 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3677 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3678 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3681 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3682 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3683 sizeof (expressionS
) * ntok
);
3684 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3685 sizeof (struct arc_flags
) * nflg
);
3686 frag_now
->tc_frag_data
.nflg
= nflg
;
3687 frag_now
->tc_frag_data
.ntok
= ntok
;
3695 /* Turn an opcode description and a set of arguments into
3696 an instruction and a fixup. */
3699 assemble_insn (const struct arc_opcode
*opcode
,
3700 const expressionS
*tok
,
3702 const struct arc_flags
*pflags
,
3704 struct arc_insn
*insn
)
3706 const expressionS
*reloc_exp
= NULL
;
3708 const unsigned char *argidx
;
3711 unsigned char pcrel
= 0;
3712 bfd_boolean needGOTSymbol
;
3713 bfd_boolean has_delay_slot
= FALSE
;
3714 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3716 memset (insn
, 0, sizeof (*insn
));
3717 image
= opcode
->opcode
;
3719 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3720 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3723 /* Handle operands. */
3724 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3726 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3727 const expressionS
*t
= (const expressionS
*) 0;
3729 if ((operand
->flags
& ARC_OPERAND_FAKE
)
3730 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
3733 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3735 /* Duplicate operand, already inserted. */
3747 /* Regardless if we have a reloc or not mark the instruction
3748 limm if it is the case. */
3749 if (operand
->flags
& ARC_OPERAND_LIMM
)
3750 insn
->has_limm
= TRUE
;
3755 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3760 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3762 if (operand
->flags
& ARC_OPERAND_LIMM
)
3763 insn
->limm
= t
->X_add_number
;
3767 /* Ignore brackets. */
3771 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3775 /* Maybe register range. */
3776 if ((t
->X_add_number
== 0)
3777 && contains_register (t
->X_add_symbol
)
3778 && contains_register (t
->X_op_symbol
))
3782 regs
= get_register (t
->X_add_symbol
);
3784 regs
|= get_register (t
->X_op_symbol
);
3785 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3790 /* This operand needs a relocation. */
3791 needGOTSymbol
= FALSE
;
3796 if (opcode
->insn_class
== JUMP
)
3797 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3798 _("Unable to use @plt relocatio for insn %s"),
3800 needGOTSymbol
= TRUE
;
3801 reloc
= find_reloc ("plt", opcode
->name
,
3803 operand
->default_reloc
);
3808 needGOTSymbol
= TRUE
;
3809 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3812 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3813 if (ARC_SHORT (opcode
->mask
) || opcode
->insn_class
== JUMP
)
3814 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3815 _("Unable to use @pcl relocation for insn %s"),
3819 reloc
= find_reloc ("sda", opcode
->name
,
3821 operand
->default_reloc
);
3825 needGOTSymbol
= TRUE
;
3830 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3833 case O_tpoff9
: /*FIXME! Check for the conditionality of
3835 case O_dtpoff9
: /*FIXME! Check for the conditionality of
3837 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3841 /* Just consider the default relocation. */
3842 reloc
= operand
->default_reloc
;
3846 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
3847 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
3854 /* sanity checks. */
3855 reloc_howto_type
*reloc_howto
3856 = bfd_reloc_type_lookup (stdoutput
,
3857 (bfd_reloc_code_real_type
) reloc
);
3858 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
3859 if (reloc_howto
->rightshift
)
3860 reloc_bitsize
-= reloc_howto
->rightshift
;
3861 if (reloc_bitsize
!= operand
->bits
)
3863 as_bad (_("invalid relocation %s for field"),
3864 bfd_get_reloc_code_name (reloc
));
3869 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3870 as_fatal (_("too many fixups"));
3872 struct arc_fixup
*fixup
;
3873 fixup
= &insn
->fixups
[insn
->nfixups
++];
3875 fixup
->reloc
= reloc
;
3876 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
3877 fixup
->pcrel
= pcrel
;
3878 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
3885 for (i
= 0; i
< nflg
; i
++)
3887 const struct arc_flag_operand
*flg_operand
= pflags
[i
].flgp
;
3889 /* Check if the instruction has a delay slot. */
3890 if (!strcmp (flg_operand
->name
, "d"))
3891 has_delay_slot
= TRUE
;
3893 /* There is an exceptional case when we cannot insert a flag
3894 just as it is. The .T flag must be handled in relation with
3895 the relative address. */
3896 if (!strcmp (flg_operand
->name
, "t")
3897 || !strcmp (flg_operand
->name
, "nt"))
3899 unsigned bitYoperand
= 0;
3900 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3901 if (!strcmp (flg_operand
->name
, "t"))
3902 if (!strcmp (opcode
->name
, "bbit0")
3903 || !strcmp (opcode
->name
, "bbit1"))
3904 bitYoperand
= arc_NToperand
;
3906 bitYoperand
= arc_Toperand
;
3908 if (!strcmp (opcode
->name
, "bbit0")
3909 || !strcmp (opcode
->name
, "bbit1"))
3910 bitYoperand
= arc_Toperand
;
3912 bitYoperand
= arc_NToperand
;
3914 gas_assert (reloc_exp
!= NULL
);
3915 if (reloc_exp
->X_op
== O_constant
)
3917 /* Check if we have a constant and solved it
3919 offsetT val
= reloc_exp
->X_add_number
;
3920 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
3925 struct arc_fixup
*fixup
;
3927 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3928 as_fatal (_("too many fixups"));
3930 fixup
= &insn
->fixups
[insn
->nfixups
++];
3931 fixup
->exp
= *reloc_exp
;
3932 fixup
->reloc
= -bitYoperand
;
3933 fixup
->pcrel
= pcrel
;
3934 fixup
->islong
= FALSE
;
3938 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
3939 << flg_operand
->shift
;
3942 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
3944 /* Short instruction? */
3945 insn
->short_insn
= ARC_SHORT (opcode
->mask
) ? TRUE
: FALSE
;
3949 /* Update last insn status. */
3950 arc_last_insns
[1] = arc_last_insns
[0];
3951 arc_last_insns
[0].opcode
= opcode
;
3952 arc_last_insns
[0].has_limm
= insn
->has_limm
;
3953 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
3955 /* Check if the current instruction is legally used. */
3956 if (arc_last_insns
[1].has_delay_slot
3957 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3958 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3959 _("A jump/branch instruction in delay slot."));
3963 arc_handle_align (fragS
* fragP
)
3965 if ((fragP
)->fr_type
== rs_align_code
)
3967 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
3968 valueT count
= ((fragP
)->fr_next
->fr_address
3969 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
3971 (fragP
)->fr_var
= 2;
3973 if (count
& 1)/* Padding in the gap till the next 2-byte
3974 boundary with 0s. */
3979 /* Writing nop_s. */
3980 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
3984 /* Here we decide which fixups can be adjusted to make them relative
3985 to the beginning of the section instead of the symbol. Basically
3986 we need to make sure that the dynamic relocations are done
3987 correctly, so in some cases we force the original symbol to be
3991 tc_arc_fix_adjustable (fixS
*fixP
)
3994 /* Prevent all adjustments to global symbols. */
3995 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
3997 if (S_IS_WEAK (fixP
->fx_addsy
))
4000 /* Adjust_reloc_syms doesn't know about the GOT. */
4001 switch (fixP
->fx_r_type
)
4003 case BFD_RELOC_ARC_GOTPC32
:
4004 case BFD_RELOC_ARC_PLT32
:
4005 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
4006 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
4007 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
4008 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
4018 /* Compute the reloc type of an expression EXP. */
4021 arc_check_reloc (expressionS
*exp
,
4022 bfd_reloc_code_real_type
*r_type_p
)
4024 if (*r_type_p
== BFD_RELOC_32
4025 && exp
->X_op
== O_subtract
4026 && exp
->X_op_symbol
!= NULL
4027 && exp
->X_op_symbol
->bsym
->section
== now_seg
)
4028 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
4032 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4035 arc_cons_fix_new (fragS
*frag
,
4039 bfd_reloc_code_real_type r_type
)
4041 r_type
= BFD_RELOC_UNUSED
;
4046 r_type
= BFD_RELOC_8
;
4050 r_type
= BFD_RELOC_16
;
4054 r_type
= BFD_RELOC_24
;
4058 r_type
= BFD_RELOC_32
;
4059 arc_check_reloc (exp
, &r_type
);
4063 r_type
= BFD_RELOC_64
;
4067 as_bad (_("unsupported BFD relocation size %u"), size
);
4068 r_type
= BFD_RELOC_UNUSED
;
4071 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
4074 /* The actual routine that checks the ZOL conditions. */
4077 check_zol (symbolS
*s
)
4079 switch (arc_mach_type
)
4081 case bfd_mach_arc_arcv2
:
4082 if (arc_target
& ARC_OPCODE_ARCv2EM
)
4085 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
4086 || arc_last_insns
[1].has_delay_slot
)
4087 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4091 case bfd_mach_arc_arc600
:
4093 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
4094 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4097 if (arc_last_insns
[0].has_limm
4098 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
4099 as_bad (_("A jump instruction with long immediate detected at the \
4100 end of the ZOL label @%s"), S_GET_NAME (s
));
4103 case bfd_mach_arc_arc700
:
4104 if (arc_last_insns
[0].has_delay_slot
)
4105 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4114 /* If ZOL end check the last two instruction for illegals. */
4116 arc_frob_label (symbolS
* sym
)
4118 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
4121 dwarf2_emit_label (sym
);
4124 /* Used because generic relaxation assumes a pc-rel value whilst we
4125 also relax instructions that use an absolute value resolved out of
4126 relative values (if that makes any sense). An example: 'add r1,
4127 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4128 but if they're in the same section we can subtract the section
4129 offset relocation which ends up in a resolved value. So if @.L2 is
4130 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4131 .text + 0x40 = 0x10. */
4133 arc_pcrel_adjust (fragS
*fragP
)
4135 if (!fragP
->tc_frag_data
.pcrel
)
4136 return fragP
->fr_address
+ fragP
->fr_fix
;
4141 /* Initialize the DWARF-2 unwind information for this procedure. */
4144 tc_arc_frame_initial_instructions (void)
4146 /* Stack pointer is register 28. */
4147 cfi_add_CFA_def_cfa (28, 0);
4151 tc_arc_regname_to_dw2regnum (char *regname
)
4155 sym
= hash_find (arc_reg_hash
, regname
);
4157 return S_GET_VALUE (sym
);
4162 /* Adjust the symbol table. Delete found AUX register symbols. */
4165 arc_adjust_symtab (void)
4169 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
4171 /* I've created a symbol during parsing process. Now, remove
4172 the symbol as it is found to be an AUX register. */
4173 if (ARC_GET_FLAG (sym
) & ARC_FLAG_AUX
)
4174 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
4177 /* Now do generic ELF adjustments. */
4178 elf_adjust_symtab ();
4182 tokenize_extinsn (extInstruction_t
*einsn
)
4186 unsigned char major_opcode
;
4187 unsigned char sub_opcode
;
4188 unsigned char syntax_class
= 0;
4189 unsigned char syntax_class_modifiers
= 0;
4190 unsigned char suffix_class
= 0;
4195 /* 1st: get instruction name. */
4196 p
= input_line_pointer
;
4197 c
= get_symbol_name (&p
);
4199 insn_name
= xstrdup (p
);
4200 restore_line_pointer (c
);
4202 /* 2nd: get major opcode. */
4203 if (*input_line_pointer
!= ',')
4205 as_bad (_("expected comma after instruction name"));
4206 ignore_rest_of_line ();
4209 input_line_pointer
++;
4210 major_opcode
= get_absolute_expression ();
4212 /* 3rd: get sub-opcode. */
4215 if (*input_line_pointer
!= ',')
4217 as_bad (_("expected comma after major opcode"));
4218 ignore_rest_of_line ();
4221 input_line_pointer
++;
4222 sub_opcode
= get_absolute_expression ();
4224 /* 4th: get suffix class. */
4227 if (*input_line_pointer
!= ',')
4229 as_bad ("expected comma after sub opcode");
4230 ignore_rest_of_line ();
4233 input_line_pointer
++;
4239 for (i
= 0; i
< ARRAY_SIZE (suffixclass
); i
++)
4241 if (!strncmp (suffixclass
[i
].name
, input_line_pointer
,
4242 suffixclass
[i
].len
))
4244 suffix_class
|= suffixclass
[i
].attr_class
;
4245 input_line_pointer
+= suffixclass
[i
].len
;
4250 if (i
== ARRAY_SIZE (suffixclass
))
4252 as_bad ("invalid suffix class");
4253 ignore_rest_of_line ();
4259 if (*input_line_pointer
== '|')
4260 input_line_pointer
++;
4265 /* 5th: get syntax class and syntax class modifiers. */
4266 if (*input_line_pointer
!= ',')
4268 as_bad ("expected comma after suffix class");
4269 ignore_rest_of_line ();
4272 input_line_pointer
++;
4278 for (i
= 0; i
< ARRAY_SIZE (syntaxclassmod
); i
++)
4280 if (!strncmp (syntaxclassmod
[i
].name
,
4282 syntaxclassmod
[i
].len
))
4284 syntax_class_modifiers
|= syntaxclassmod
[i
].attr_class
;
4285 input_line_pointer
+= syntaxclassmod
[i
].len
;
4290 if (i
== ARRAY_SIZE (syntaxclassmod
))
4292 for (i
= 0; i
< ARRAY_SIZE (syntaxclass
); i
++)
4294 if (!strncmp (syntaxclass
[i
].name
,
4296 syntaxclass
[i
].len
))
4298 syntax_class
|= syntaxclass
[i
].attr_class
;
4299 input_line_pointer
+= syntaxclass
[i
].len
;
4304 if (i
== ARRAY_SIZE (syntaxclass
))
4306 as_bad ("missing syntax class");
4307 ignore_rest_of_line ();
4314 if (*input_line_pointer
== '|')
4315 input_line_pointer
++;
4320 demand_empty_rest_of_line ();
4322 einsn
->name
= insn_name
;
4323 einsn
->major
= major_opcode
;
4324 einsn
->minor
= sub_opcode
;
4325 einsn
->syntax
= syntax_class
;
4326 einsn
->modsyn
= syntax_class_modifiers
;
4327 einsn
->suffix
= suffix_class
;
4328 einsn
->flags
= syntax_class
4329 | (syntax_class_modifiers
& ARC_OP1_IMM_IMPLIED
? 0x10 : 0);
4332 /* Generate an extension section. */
4335 arc_set_ext_seg (void)
4337 if (!arcext_section
)
4339 arcext_section
= subseg_new (".arcextmap", 0);
4340 bfd_set_section_flags (stdoutput
, arcext_section
,
4341 SEC_READONLY
| SEC_HAS_CONTENTS
);
4344 subseg_set (arcext_section
, 0);
4348 /* Create an extension instruction description in the arc extension
4349 section of the output file.
4350 The structure for an instruction is like this:
4351 [0]: Length of the record.
4352 [1]: Type of the record.
4356 [4]: Syntax (flags).
4357 [5]+ Name instruction.
4359 The sequence is terminated by an empty entry. */
4362 create_extinst_section (extInstruction_t
*einsn
)
4365 segT old_sec
= now_seg
;
4366 int old_subsec
= now_subseg
;
4368 int name_len
= strlen (einsn
->name
);
4373 *p
= 5 + name_len
+ 1;
4375 *p
= EXT_INSTRUCTION
;
4382 p
= frag_more (name_len
+ 1);
4383 strcpy (p
, einsn
->name
);
4385 subseg_set (old_sec
, old_subsec
);
4388 /* Handler .extinstruction pseudo-op. */
4391 arc_extinsn (int ignore ATTRIBUTE_UNUSED
)
4393 extInstruction_t einsn
;
4394 struct arc_opcode
*arc_ext_opcodes
;
4395 const char *errmsg
= NULL
;
4396 unsigned char moplow
, mophigh
;
4398 memset (&einsn
, 0, sizeof (einsn
));
4399 tokenize_extinsn (&einsn
);
4401 /* Check if the name is already used. */
4402 if (arc_find_opcode (einsn
.name
))
4403 as_warn (_("Pseudocode already used %s"), einsn
.name
);
4405 /* Check the opcode ranges. */
4407 mophigh
= (arc_target
& (ARC_OPCODE_ARCv2EM
4408 | ARC_OPCODE_ARCv2HS
)) ? 0x07 : 0x0a;
4410 if ((einsn
.major
> mophigh
) || (einsn
.major
< moplow
))
4411 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow
, mophigh
);
4413 if ((einsn
.minor
> 0x3f) && (einsn
.major
!= 0x0a)
4414 && (einsn
.major
!= 5) && (einsn
.major
!= 9))
4415 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4417 switch (einsn
.syntax
& ARC_SYNTAX_MASK
)
4419 case ARC_SYNTAX_3OP
:
4420 if (einsn
.modsyn
& ARC_OP1_IMM_IMPLIED
)
4421 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4423 case ARC_SYNTAX_2OP
:
4424 case ARC_SYNTAX_1OP
:
4425 case ARC_SYNTAX_NOP
:
4426 if (einsn
.modsyn
& ARC_OP1_MUST_BE_IMM
)
4427 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4433 arc_ext_opcodes
= arcExtMap_genOpcode (&einsn
, arc_target
, &errmsg
);
4434 if (arc_ext_opcodes
== NULL
)
4437 as_fatal ("%s", errmsg
);
4439 as_fatal (_("Couldn't generate extension instruction opcodes"));
4442 as_warn ("%s", errmsg
);
4444 /* Insert the extension instruction. */
4445 arc_insert_opcode ((const struct arc_opcode
*) arc_ext_opcodes
);
4447 create_extinst_section (&einsn
);
4451 tokenize_extregister (extRegister_t
*ereg
, int opertype
)
4457 int number
, imode
= 0;
4458 bfd_boolean isCore_p
= (opertype
== EXT_CORE_REGISTER
) ? TRUE
: FALSE
;
4459 bfd_boolean isReg_p
= (opertype
== EXT_CORE_REGISTER
4460 || opertype
== EXT_AUX_REGISTER
) ? TRUE
: FALSE
;
4462 /* 1st: get register name. */
4464 p
= input_line_pointer
;
4465 c
= get_symbol_name (&p
);
4468 restore_line_pointer (c
);
4470 /* 2nd: get register number. */
4473 if (*input_line_pointer
!= ',')
4475 as_bad (_("expected comma after register name"));
4476 ignore_rest_of_line ();
4480 input_line_pointer
++;
4481 number
= get_absolute_expression ();
4485 as_bad (_("negative operand number %d"), number
);
4486 ignore_rest_of_line ();
4493 /* 3rd: get register mode. */
4496 if (*input_line_pointer
!= ',')
4498 as_bad (_("expected comma after register number"));
4499 ignore_rest_of_line ();
4504 input_line_pointer
++;
4505 mode
= input_line_pointer
;
4507 if (!strncmp (mode
, "r|w", 3))
4510 input_line_pointer
+= 3;
4512 else if (!strncmp (mode
, "r", 1))
4514 imode
= ARC_REGISTER_READONLY
;
4515 input_line_pointer
+= 1;
4517 else if (strncmp (mode
, "w", 1))
4519 as_bad (_("invalid mode"));
4520 ignore_rest_of_line ();
4526 imode
= ARC_REGISTER_WRITEONLY
;
4527 input_line_pointer
+= 1;
4533 /* 4th: get core register shortcut. */
4535 if (*input_line_pointer
!= ',')
4537 as_bad (_("expected comma after register mode"));
4538 ignore_rest_of_line ();
4543 input_line_pointer
++;
4545 if (!strncmp (input_line_pointer
, "cannot_shortcut", 15))
4547 imode
|= ARC_REGISTER_NOSHORT_CUT
;
4548 input_line_pointer
+= 15;
4550 else if (strncmp (input_line_pointer
, "can_shortcut", 12))
4552 as_bad (_("shortcut designator invalid"));
4553 ignore_rest_of_line ();
4559 input_line_pointer
+= 12;
4562 demand_empty_rest_of_line ();
4565 ereg
->number
= number
;
4566 ereg
->imode
= imode
;
4569 /* Create an extension register/condition description in the arc
4570 extension section of the output file.
4572 The structure for an instruction is like this:
4573 [0]: Length of the record.
4574 [1]: Type of the record.
4576 For core regs and condition codes:
4580 For auxilirary registers:
4584 The sequence is terminated by an empty entry. */
4587 create_extcore_section (extRegister_t
*ereg
, int opertype
)
4589 segT old_sec
= now_seg
;
4590 int old_subsec
= now_subseg
;
4592 int name_len
= strlen (ereg
->name
);
4599 case EXT_CORE_REGISTER
:
4601 *p
= 3 + name_len
+ 1;
4607 case EXT_AUX_REGISTER
:
4609 *p
= 6 + name_len
+ 1;
4611 *p
= EXT_AUX_REGISTER
;
4613 *p
= (ereg
->number
>> 24) & 0xff;
4615 *p
= (ereg
->number
>> 16) & 0xff;
4617 *p
= (ereg
->number
>> 8) & 0xff;
4619 *p
= (ereg
->number
) & 0xff;
4625 p
= frag_more (name_len
+ 1);
4626 strcpy (p
, ereg
->name
);
4628 subseg_set (old_sec
, old_subsec
);
4631 /* Handler .extCoreRegister pseudo-op. */
4634 arc_extcorereg (int opertype
)
4637 struct arc_aux_reg
*auxr
;
4639 struct arc_flag_operand
*ccode
;
4641 memset (&ereg
, 0, sizeof (ereg
));
4642 tokenize_extregister (&ereg
, opertype
);
4646 case EXT_CORE_REGISTER
:
4647 /* Core register. */
4648 if (ereg
.number
> 60)
4649 as_bad (_("core register %s value (%d) too large"), ereg
.name
,
4651 declare_register (ereg
.name
, ereg
.number
);
4653 case EXT_AUX_REGISTER
:
4654 /* Auxiliary register. */
4655 auxr
= XNEW (struct arc_aux_reg
);
4656 auxr
->name
= ereg
.name
;
4657 auxr
->cpu
= arc_target
;
4658 auxr
->subclass
= NONE
;
4659 auxr
->address
= ereg
.number
;
4660 retval
= hash_insert (arc_aux_hash
, auxr
->name
, (void *) auxr
);
4662 as_fatal (_("internal error: can't hash aux register '%s': %s"),
4663 auxr
->name
, retval
);
4666 /* Condition code. */
4667 if (ereg
.number
> 31)
4668 as_bad (_("condition code %s value (%d) too large"), ereg
.name
,
4670 ext_condcode
.size
++;
4671 ext_condcode
.arc_ext_condcode
=
4672 XRESIZEVEC (struct arc_flag_operand
, ext_condcode
.arc_ext_condcode
,
4673 ext_condcode
.size
+ 1);
4674 if (ext_condcode
.arc_ext_condcode
== NULL
)
4675 as_fatal (_("Virtual memory exhausted"));
4677 ccode
= ext_condcode
.arc_ext_condcode
+ ext_condcode
.size
- 1;
4678 ccode
->name
= ereg
.name
;
4679 ccode
->code
= ereg
.number
;
4682 ccode
->favail
= 0; /* not used. */
4684 memset (ccode
, 0, sizeof (struct arc_flag_operand
));
4687 as_bad (_("Unknown extension"));
4690 create_extcore_section (&ereg
, opertype
);
4694 eval: (c-set-style "gnu")