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"
33 /* Defines section. */
35 #define MAX_INSN_FIXUPS 2
36 #define MAX_CONSTR_STR 20
37 #define FRAG_MAX_GROWTH 8
40 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
42 # define pr_debug(fmt, args...)
45 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
46 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
47 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \
48 (SUB_OPCODE (x) == 0x28))
50 /* Equal to MAX_PRECISION in atof-ieee.c. */
51 #define MAX_LITTLENUMS 6
53 /* Enum used to enumerate the relaxable ins operands. */
58 REGISTER_S
, /* Register for short instruction(s). */
59 REGISTER_NO_GP
, /* Is a register but not gp register specifically. */
60 REGISTER_DUP
, /* Duplication of previous operand of type register. */
94 #define regno(x) ((x) & 0x3F)
95 #define is_ir_num(x) (((x) & ~0x3F) == 0)
96 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
97 #define is_spfp_p(op) (((sc) == SPX))
98 #define is_dpfp_p(op) (((sc) == DPX))
99 #define is_fpuda_p(op) (((sc) == DPA))
100 #define is_br_jmp_insn_p(op) (((op)->class == BRANCH || (op)->class == JUMP))
101 #define is_kernel_insn_p(op) (((op)->class == KERNEL))
103 /* Generic assembler global variables which must be defined by all
106 /* Characters which always start a comment. */
107 const char comment_chars
[] = "#;";
109 /* Characters which start a comment at the beginning of a line. */
110 const char line_comment_chars
[] = "#";
112 /* Characters which may be used to separate multiple commands on a
114 const char line_separator_chars
[] = "`";
116 /* Characters which are used to indicate an exponent in a floating
118 const char EXP_CHARS
[] = "eE";
120 /* Chars that mean this number is a floating point constant
121 As in 0f12.456 or 0d1.2345e12. */
122 const char FLT_CHARS
[] = "rRsSfFdD";
125 extern int target_big_endian
;
126 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
127 static int byte_order
= DEFAULT_BYTE_ORDER
;
129 /* By default relaxation is disabled. */
130 static int relaxation_state
= 0;
132 extern int arc_get_mach (char *);
134 /* Forward declarations. */
135 static void arc_lcomm (int);
136 static void arc_option (int);
137 static void arc_extra_reloc (int);
140 const pseudo_typeS md_pseudo_table
[] =
142 /* Make sure that .word is 32 bits. */
145 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
146 { "lcomm", arc_lcomm
, 0 },
147 { "lcommon", arc_lcomm
, 0 },
148 { "cpu", arc_option
, 0 },
150 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
151 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
156 const char *md_shortopts
= "";
160 OPTION_EB
= OPTION_MD_BASE
,
173 /* The following options are deprecated and provided here only for
174 compatibility reasons. */
200 struct option md_longopts
[] =
202 { "EB", no_argument
, NULL
, OPTION_EB
},
203 { "EL", no_argument
, NULL
, OPTION_EL
},
204 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
205 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
206 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
207 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
208 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
209 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
210 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
211 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
212 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
213 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
215 /* The following options are deprecated and provided here only for
216 compatibility reasons. */
217 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
218 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
219 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
220 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
221 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
222 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
223 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
224 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
225 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
226 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
227 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
228 { "mea", no_argument
, NULL
, OPTION_EA
},
229 { "mEA", no_argument
, NULL
, OPTION_EA
},
230 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
231 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
232 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
233 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
234 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
235 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
236 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
237 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
238 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
239 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
240 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
241 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
242 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
243 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
244 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
245 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
246 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
247 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
248 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
249 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
250 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
251 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
252 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
253 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
254 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
255 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
257 { NULL
, no_argument
, NULL
, 0 }
260 size_t md_longopts_size
= sizeof (md_longopts
);
262 /* Local data and data types. */
264 /* Used since new relocation types are introduced in this
265 file (DUMMY_RELOC_LITUSE_*). */
266 typedef int extended_bfd_reloc_code_real_type
;
272 extended_bfd_reloc_code_real_type reloc
;
274 /* index into arc_operands. */
275 unsigned int opindex
;
277 /* PC-relative, used by internals fixups. */
280 /* TRUE if this fixup is for LIMM operand. */
288 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
290 bfd_boolean short_insn
; /* Boolean value: TRUE if current insn is
292 bfd_boolean has_limm
; /* Boolean value: TRUE if limm field is
294 bfd_boolean relax
; /* Boolean value: TRUE if needs
298 /* Structure to hold any last two instructions. */
299 static struct arc_last_insn
301 /* Saved instruction opcode. */
302 const struct arc_opcode
*opcode
;
304 /* Boolean value: TRUE if current insn is short. */
305 bfd_boolean has_limm
;
307 /* Boolean value: TRUE if current insn has delay slot. */
308 bfd_boolean has_delay_slot
;
311 /* Forward declaration. */
312 static void assemble_insn
313 (const struct arc_opcode
*, const expressionS
*, int,
314 const struct arc_flags
*, int, struct arc_insn
*);
316 /* The cpu for which we are generating code. */
317 static unsigned arc_target
;
318 static const char *arc_target_name
;
319 static unsigned arc_features
;
321 /* The default architecture. */
322 static int arc_mach_type
;
324 /* Non-zero if the cpu type has been explicitly specified. */
325 static int mach_type_specified_p
= 0;
327 /* The hash table of instruction opcodes. */
328 static struct hash_control
*arc_opcode_hash
;
330 /* The hash table of register symbols. */
331 static struct hash_control
*arc_reg_hash
;
333 /* A table of CPU names and opcode sets. */
334 static const struct cpu_type
344 { "arc600", ARC_OPCODE_ARC600
, bfd_mach_arc_arc600
,
345 E_ARC_MACH_ARC600
, 0x00},
346 { "arc700", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
347 E_ARC_MACH_ARC700
, 0x00},
348 { "nps400", ARC_OPCODE_ARC700
| ARC_OPCODE_NPS400
, bfd_mach_arc_nps400
,
349 E_ARC_MACH_NPS400
, 0x00},
350 { "arcem", ARC_OPCODE_ARCv2EM
, bfd_mach_arc_arcv2
,
351 EF_ARC_CPU_ARCV2EM
, ARC_CD
},
352 { "archs", ARC_OPCODE_ARCv2HS
, bfd_mach_arc_arcv2
,
353 EF_ARC_CPU_ARCV2HS
, ARC_CD
},
357 /* Used by the arc_reloc_op table. Order is important. */
358 #define O_gotoff O_md1 /* @gotoff relocation. */
359 #define O_gotpc O_md2 /* @gotpc relocation. */
360 #define O_plt O_md3 /* @plt relocation. */
361 #define O_sda O_md4 /* @sda relocation. */
362 #define O_pcl O_md5 /* @pcl relocation. */
363 #define O_tlsgd O_md6 /* @tlsgd relocation. */
364 #define O_tlsie O_md7 /* @tlsie relocation. */
365 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
366 #define O_tpoff O_md9 /* @tpoff relocation. */
367 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
368 #define O_dtpoff O_md11 /* @dtpoff relocation. */
369 #define O_last O_dtpoff
371 /* Used to define a bracket as operand in tokens. */
372 #define O_bracket O_md32
374 /* Dummy relocation, to be sorted out. */
375 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
377 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
379 /* A table to map the spelling of a relocation operand into an appropriate
380 bfd_reloc_code_real_type type. The table is assumed to be ordered such
381 that op-O_literal indexes into it. */
382 #define ARC_RELOC_TABLE(op) \
383 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
385 : (int) (op) - (int) O_gotoff) ])
387 #define DEF(NAME, RELOC, REQ) \
388 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
390 static const struct arc_reloc_op_tag
392 /* String to lookup. */
394 /* Size of the string. */
396 /* Which operator to use. */
398 extended_bfd_reloc_code_real_type reloc
;
399 /* Allows complex relocation expression like identifier@reloc +
401 unsigned int complex_expr
: 1;
405 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
406 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
407 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
408 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
409 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
410 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
411 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
412 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
413 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
414 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
415 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 0),
418 static const int arc_num_reloc_op
419 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
421 /* Structure for relaxable instruction that have to be swapped with a
422 smaller alternative instruction. */
423 struct arc_relaxable_ins
425 /* Mnemonic that should be checked. */
426 const char *mnemonic_r
;
428 /* Operands that should be checked.
429 Indexes of operands from operand array. */
430 enum rlx_operand_type operands
[6];
432 /* Flags that should be checked. */
433 unsigned flag_classes
[5];
435 /* Mnemonic (smaller) alternative to be used later for relaxation. */
436 const char *mnemonic_alt
;
438 /* Index of operand that generic relaxation has to check. */
441 /* Base subtype index used. */
442 enum arc_rlx_types subtype
;
445 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
446 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
447 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
451 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
452 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
453 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
458 /* ARC relaxation table. */
459 const relax_typeS md_relax_table
[] =
466 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL
),
467 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
471 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B
),
472 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
477 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6
),
478 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM
),
479 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
481 /* LD_S a, [b, u7] ->
482 LD<zz><.x><.aa><.di> a, [b, s9] ->
483 LD<zz><.x><.aa><.di> a, [b, limm] */
484 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9
),
485 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM
),
486 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE
),
491 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12
),
492 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM
),
493 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
497 SUB<.f> a, b, limm. */
498 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6
),
499 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM
),
500 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
502 /* MPY<.f> a, b, u6 ->
503 MPY<.f> a, b, limm. */
504 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM
),
505 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
507 /* MOV<.f><.cc> b, u6 ->
508 MOV<.f><.cc> b, limm. */
509 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM
),
510 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
512 /* ADD<.f><.cc> b, b, u6 ->
513 ADD<.f><.cc> b, b, limm. */
514 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM
),
515 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
518 /* Order of this table's entries matters! */
519 const struct arc_relaxable_ins arc_relaxable_insns
[] =
521 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
522 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
523 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
524 2, ARC_RLX_ADD_RRU6
},
525 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
527 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
529 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
530 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
531 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
532 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
533 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
534 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
535 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
536 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
538 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
540 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
544 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
546 /* Flags to set in the elf header. */
547 static flagword arc_eflag
= 0x00;
549 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
550 symbolS
* GOT_symbol
= 0;
552 /* Set to TRUE when we assemble instructions. */
553 static bfd_boolean assembling_insn
= FALSE
;
555 /* Functions implementation. */
557 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
558 is encoded as 'middle-endian' for a little-endian target. FIXME!
559 this function is used for regular 4 byte instructions as well. */
562 md_number_to_chars_midend (char *buf
, valueT val
, int n
)
566 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
567 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
571 md_number_to_chars (buf
, val
, n
);
575 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
576 the relevant static global variables. */
579 arc_select_cpu (const char *arg
)
584 for (i
= 0; cpu_types
[i
].name
; ++i
)
586 if (!strcasecmp (cpu_types
[i
].name
, arg
))
588 arc_target
= cpu_types
[i
].flags
;
589 arc_target_name
= cpu_types
[i
].name
;
590 arc_features
= cpu_types
[i
].features
;
591 arc_mach_type
= cpu_types
[i
].mach
;
592 cpu_flags
= cpu_types
[i
].eflags
;
597 if (!cpu_types
[i
].name
)
598 as_fatal (_("unknown architecture: %s\n"), arg
);
599 gas_assert (cpu_flags
!= 0);
600 arc_eflag
= (arc_eflag
& ~EF_ARC_MACH_MSK
) | cpu_flags
;
603 /* Here ends all the ARCompact extension instruction assembling
607 arc_extra_reloc (int r_type
)
610 symbolS
*sym
, *lab
= NULL
;
612 if (*input_line_pointer
== '@')
613 input_line_pointer
++;
614 c
= get_symbol_name (&sym_name
);
615 sym
= symbol_find_or_make (sym_name
);
616 restore_line_pointer (c
);
617 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
619 ++input_line_pointer
;
621 c
= get_symbol_name (&lab_name
);
622 lab
= symbol_find_or_make (lab_name
);
623 restore_line_pointer (c
);
626 /* These relocations exist as a mechanism for the compiler to tell the
627 linker how to patch the code if the tls model is optimised. However,
628 the relocation itself does not require any space within the assembler
629 fragment, and so we pass a size of 0.
631 The lines that generate these relocations look like this:
633 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
635 The '.tls_gd_ld @.tdata' is processed first and generates the
636 additional relocation, while the 'bl __tls_get_addr@plt' is processed
637 second and generates the additional branch.
639 It is possible that the additional relocation generated by the
640 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
641 while the 'bl __tls_get_addr@plt' will be generated as the first thing
642 in the next fragment. This will be fine; both relocations will still
643 appear to be at the same address in the generated object file.
644 However, this only works as the additional relocation is generated
645 with size of 0 bytes. */
647 = fix_new (frag_now
, /* Which frag? */
648 frag_now_fix (), /* Where in that frag? */
649 0, /* size: 1, 2, or 4 usually. */
650 sym
, /* X_add_symbol. */
651 0, /* X_add_number. */
652 FALSE
, /* TRUE if PC-relative relocation. */
653 r_type
/* Relocation type. */);
654 fixP
->fx_subsy
= lab
;
658 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
659 symbolS
*symbolP
, addressT size
)
664 if (*input_line_pointer
== ',')
666 align
= parse_align (1);
668 if (align
== (addressT
) -1)
683 bss_alloc (symbolP
, size
, align
);
684 S_CLEAR_EXTERNAL (symbolP
);
690 arc_lcomm (int ignore
)
692 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
695 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
698 /* Select the cpu we're assembling for. */
701 arc_option (int ignore ATTRIBUTE_UNUSED
)
707 c
= get_symbol_name (&cpu
);
708 mach
= arc_get_mach (cpu
);
713 if (!mach_type_specified_p
)
715 if ((!strcmp ("ARC600", cpu
))
716 || (!strcmp ("ARC601", cpu
))
717 || (!strcmp ("A6", cpu
)))
719 md_parse_option (OPTION_MCPU
, "arc600");
721 else if ((!strcmp ("ARC700", cpu
))
722 || (!strcmp ("A7", cpu
)))
724 md_parse_option (OPTION_MCPU
, "arc700");
726 else if (!strcmp ("EM", cpu
))
728 md_parse_option (OPTION_MCPU
, "arcem");
730 else if (!strcmp ("HS", cpu
))
732 md_parse_option (OPTION_MCPU
, "archs");
735 as_fatal ("could not find the architecture");
737 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, mach
))
738 as_fatal ("could not set architecture and machine");
741 if (arc_mach_type
!= mach
)
742 as_warn ("Command-line value overrides \".cpu\" directive");
744 restore_line_pointer (c
);
745 demand_empty_rest_of_line ();
749 restore_line_pointer (c
);
750 as_bad ("invalid identifier for \".cpu\"");
751 ignore_rest_of_line ();
754 /* Smartly print an expression. */
757 debug_exp (expressionS
*t
)
759 const char *name ATTRIBUTE_UNUSED
;
760 const char *namemd ATTRIBUTE_UNUSED
;
762 pr_debug ("debug_exp: ");
766 default: name
= "unknown"; break;
767 case O_illegal
: name
= "O_illegal"; break;
768 case O_absent
: name
= "O_absent"; break;
769 case O_constant
: name
= "O_constant"; break;
770 case O_symbol
: name
= "O_symbol"; break;
771 case O_symbol_rva
: name
= "O_symbol_rva"; break;
772 case O_register
: name
= "O_register"; break;
773 case O_big
: name
= "O_big"; break;
774 case O_uminus
: name
= "O_uminus"; break;
775 case O_bit_not
: name
= "O_bit_not"; break;
776 case O_logical_not
: name
= "O_logical_not"; break;
777 case O_multiply
: name
= "O_multiply"; break;
778 case O_divide
: name
= "O_divide"; break;
779 case O_modulus
: name
= "O_modulus"; break;
780 case O_left_shift
: name
= "O_left_shift"; break;
781 case O_right_shift
: name
= "O_right_shift"; break;
782 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
783 case O_bit_or_not
: name
= "O_bit_or_not"; break;
784 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
785 case O_bit_and
: name
= "O_bit_and"; break;
786 case O_add
: name
= "O_add"; break;
787 case O_subtract
: name
= "O_subtract"; break;
788 case O_eq
: name
= "O_eq"; break;
789 case O_ne
: name
= "O_ne"; break;
790 case O_lt
: name
= "O_lt"; break;
791 case O_le
: name
= "O_le"; break;
792 case O_ge
: name
= "O_ge"; break;
793 case O_gt
: name
= "O_gt"; break;
794 case O_logical_and
: name
= "O_logical_and"; break;
795 case O_logical_or
: name
= "O_logical_or"; break;
796 case O_index
: name
= "O_index"; break;
797 case O_bracket
: name
= "O_bracket"; break;
802 default: namemd
= "unknown"; break;
803 case O_gotoff
: namemd
= "O_gotoff"; break;
804 case O_gotpc
: namemd
= "O_gotpc"; break;
805 case O_plt
: namemd
= "O_plt"; break;
806 case O_sda
: namemd
= "O_sda"; break;
807 case O_pcl
: namemd
= "O_pcl"; break;
808 case O_tlsgd
: namemd
= "O_tlsgd"; break;
809 case O_tlsie
: namemd
= "O_tlsie"; break;
810 case O_tpoff9
: namemd
= "O_tpoff9"; break;
811 case O_tpoff
: namemd
= "O_tpoff"; break;
812 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
813 case O_dtpoff
: namemd
= "O_dtpoff"; break;
816 pr_debug ("%s (%s, %s, %d, %s)", name
,
817 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
818 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
819 (int) t
->X_add_number
,
820 (t
->X_md
) ? namemd
: "--");
825 /* Parse the arguments to an opcode. */
828 tokenize_arguments (char *str
,
832 char *old_input_line_pointer
;
833 bfd_boolean saw_comma
= FALSE
;
834 bfd_boolean saw_arg
= FALSE
;
839 const struct arc_reloc_op_tag
*r
;
843 memset (tok
, 0, sizeof (*tok
) * ntok
);
845 /* Save and restore input_line_pointer around this function. */
846 old_input_line_pointer
= input_line_pointer
;
847 input_line_pointer
= str
;
849 while (*input_line_pointer
)
852 switch (*input_line_pointer
)
858 input_line_pointer
++;
859 if (saw_comma
|| !saw_arg
)
866 ++input_line_pointer
;
870 tok
->X_op
= O_bracket
;
877 input_line_pointer
++;
881 tok
->X_op
= O_bracket
;
887 /* We have labels, function names and relocations, all
888 starting with @ symbol. Sort them out. */
889 if (saw_arg
&& !saw_comma
)
893 tok
->X_op
= O_symbol
;
894 tok
->X_md
= O_absent
;
896 if (*input_line_pointer
!= '@')
897 goto normalsymbol
; /* This is not a relocation. */
901 /* A relocation opernad has the following form
902 @identifier@relocation_type. The identifier is already
904 if (tok
->X_op
!= O_symbol
)
906 as_bad (_("No valid label relocation operand"));
910 /* Parse @relocation_type. */
911 input_line_pointer
++;
912 c
= get_symbol_name (&reloc_name
);
913 len
= input_line_pointer
- reloc_name
;
916 as_bad (_("No relocation operand"));
920 /* Go through known relocation and try to find a match. */
921 r
= &arc_reloc_op
[0];
922 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
924 && memcmp (reloc_name
, r
->name
, len
) == 0)
928 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
932 *input_line_pointer
= c
;
933 SKIP_WHITESPACE_AFTER_NAME ();
934 /* Extra check for TLS: base. */
935 if (*input_line_pointer
== '@')
938 if (tok
->X_op_symbol
!= NULL
939 || tok
->X_op
!= O_symbol
)
941 as_bad (_("Unable to parse TLS base: %s"),
945 input_line_pointer
++;
947 c
= get_symbol_name (&sym_name
);
948 base
= symbol_find_or_make (sym_name
);
949 tok
->X_op
= O_subtract
;
950 tok
->X_op_symbol
= base
;
951 restore_line_pointer (c
);
952 tmpE
.X_add_number
= 0;
954 else if ((*input_line_pointer
!= '+')
955 && (*input_line_pointer
!= '-'))
957 tmpE
.X_add_number
= 0;
961 /* Parse the constant of a complex relocation expression
962 like @identifier@reloc +/- const. */
963 if (! r
->complex_expr
)
965 as_bad (_("@%s is not a complex relocation."), r
->name
);
969 if (tmpE
.X_op
!= O_constant
)
971 as_bad (_("Bad expression: @%s + %s."),
972 r
->name
, input_line_pointer
);
978 tok
->X_add_number
= tmpE
.X_add_number
;
989 /* Can be a register. */
990 ++input_line_pointer
;
994 if (saw_arg
&& !saw_comma
)
997 tok
->X_op
= O_absent
;
998 tok
->X_md
= O_absent
;
1001 /* Legacy: There are cases when we have
1002 identifier@relocation_type, if it is the case parse the
1003 relocation type as well. */
1004 if (*input_line_pointer
== '@')
1010 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1022 if (saw_comma
|| brk_lvl
)
1024 input_line_pointer
= old_input_line_pointer
;
1030 as_bad (_("Brackets in operand field incorrect"));
1032 as_bad (_("extra comma"));
1034 as_bad (_("missing argument"));
1036 as_bad (_("missing comma or colon"));
1037 input_line_pointer
= old_input_line_pointer
;
1041 /* Parse the flags to a structure. */
1044 tokenize_flags (const char *str
,
1045 struct arc_flags flags
[],
1048 char *old_input_line_pointer
;
1049 bfd_boolean saw_flg
= FALSE
;
1050 bfd_boolean saw_dot
= FALSE
;
1054 memset (flags
, 0, sizeof (*flags
) * nflg
);
1056 /* Save and restore input_line_pointer around this function. */
1057 old_input_line_pointer
= input_line_pointer
;
1058 input_line_pointer
= (char *) str
;
1060 while (*input_line_pointer
)
1062 switch (*input_line_pointer
)
1069 input_line_pointer
++;
1077 if (saw_flg
&& !saw_dot
)
1080 if (num_flags
>= nflg
)
1083 flgnamelen
= strspn (input_line_pointer
, "abcdefghilmnopqrstvwxz");
1084 if (flgnamelen
> MAX_FLAG_NAME_LENGTH
)
1087 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1089 input_line_pointer
+= flgnamelen
;
1099 input_line_pointer
= old_input_line_pointer
;
1104 as_bad (_("extra dot"));
1106 as_bad (_("unrecognized flag"));
1108 as_bad (_("failed to parse flags"));
1109 input_line_pointer
= old_input_line_pointer
;
1113 /* Apply the fixups in order. */
1116 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1120 for (i
= 0; i
< insn
->nfixups
; i
++)
1122 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1123 int size
, pcrel
, offset
= 0;
1125 /* FIXME! the reloc size is wrong in the BFD file.
1126 When it is fixed please delete me. */
1127 size
= (insn
->short_insn
&& !fixup
->islong
) ? 2 : 4;
1130 offset
= (insn
->short_insn
) ? 2 : 4;
1132 /* Some fixups are only used internally, thus no howto. */
1133 if ((int) fixup
->reloc
== 0)
1134 as_fatal (_("Unhandled reloc type"));
1136 if ((int) fixup
->reloc
< 0)
1138 /* FIXME! the reloc size is wrong in the BFD file.
1139 When it is fixed please enable me.
1140 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1141 pcrel
= fixup
->pcrel
;
1145 reloc_howto_type
*reloc_howto
=
1146 bfd_reloc_type_lookup (stdoutput
,
1147 (bfd_reloc_code_real_type
) fixup
->reloc
);
1148 gas_assert (reloc_howto
);
1150 /* FIXME! the reloc size is wrong in the BFD file.
1151 When it is fixed please enable me.
1152 size = bfd_get_reloc_size (reloc_howto); */
1153 pcrel
= reloc_howto
->pc_relative
;
1156 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1158 fragP
->fr_file
, fragP
->fr_line
,
1159 (fixup
->reloc
< 0) ? "Internal" :
1160 bfd_get_reloc_code_name (fixup
->reloc
),
1163 fix_new_exp (fragP
, fix
+ offset
,
1164 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1166 /* Check for ZOLs, and update symbol info if any. */
1167 if (LP_INSN (insn
->insn
))
1169 gas_assert (fixup
->exp
.X_add_symbol
);
1170 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1175 /* Actually output an instruction with its fixup. */
1178 emit_insn0 (struct arc_insn
*insn
, char *where
, bfd_boolean relax
)
1182 pr_debug ("Emit insn : 0x%x\n", insn
->insn
);
1183 pr_debug ("\tShort : 0x%d\n", insn
->short_insn
);
1184 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1186 /* Write out the instruction. */
1187 if (insn
->short_insn
)
1193 md_number_to_chars (f
, insn
->insn
, 2);
1194 md_number_to_chars_midend (f
+ 2, insn
->limm
, 4);
1195 dwarf2_emit_insn (6);
1201 md_number_to_chars (f
, insn
->insn
, 2);
1202 dwarf2_emit_insn (2);
1211 md_number_to_chars_midend (f
, insn
->insn
, 4);
1212 md_number_to_chars_midend (f
+ 4, insn
->limm
, 4);
1213 dwarf2_emit_insn (8);
1219 md_number_to_chars_midend (f
, insn
->insn
, 4);
1220 dwarf2_emit_insn (4);
1225 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1229 emit_insn1 (struct arc_insn
*insn
)
1231 /* How frag_var's args are currently configured:
1232 - rs_machine_dependent, to dictate it's a relaxation frag.
1233 - FRAG_MAX_GROWTH, maximum size of instruction
1234 - 0, variable size that might grow...unused by generic relaxation.
1235 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1236 - s, opand expression.
1237 - 0, offset but it's unused.
1238 - 0, opcode but it's unused. */
1239 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1240 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1242 if (frag_room () < FRAG_MAX_GROWTH
)
1244 /* Handle differently when frag literal memory is exhausted.
1245 This is used because when there's not enough memory left in
1246 the current frag, a new frag is created and the information
1247 we put into frag_now->tc_frag_data is disregarded. */
1249 struct arc_relax_type relax_info_copy
;
1250 relax_substateT subtype
= frag_now
->fr_subtype
;
1252 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1253 sizeof (struct arc_relax_type
));
1255 frag_wane (frag_now
);
1256 frag_grow (FRAG_MAX_GROWTH
);
1258 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1259 sizeof (struct arc_relax_type
));
1261 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1265 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1266 frag_now
->fr_subtype
, s
, 0, 0);
1270 emit_insn (struct arc_insn
*insn
)
1275 emit_insn0 (insn
, NULL
, FALSE
);
1278 /* Check whether a symbol involves a register. */
1281 contains_register (symbolS
*sym
)
1285 expressionS
*ex
= symbol_get_value_expression (sym
);
1287 return ((O_register
== ex
->X_op
)
1288 && !contains_register (ex
->X_add_symbol
)
1289 && !contains_register (ex
->X_op_symbol
));
1295 /* Returns the register number within a symbol. */
1298 get_register (symbolS
*sym
)
1300 if (!contains_register (sym
))
1303 expressionS
*ex
= symbol_get_value_expression (sym
);
1304 return regno (ex
->X_add_number
);
1307 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1308 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1311 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1318 case BFD_RELOC_ARC_SDA_LDST
:
1319 case BFD_RELOC_ARC_SDA_LDST1
:
1320 case BFD_RELOC_ARC_SDA_LDST2
:
1321 case BFD_RELOC_ARC_SDA16_LD
:
1322 case BFD_RELOC_ARC_SDA16_LD1
:
1323 case BFD_RELOC_ARC_SDA16_LD2
:
1324 case BFD_RELOC_ARC_SDA16_ST2
:
1325 case BFD_RELOC_ARC_SDA32_ME
:
1332 /* Allocates a tok entry. */
1335 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1337 if (ntok
> MAX_INSN_ARGS
- 2)
1338 return 0; /* No space left. */
1341 return 0; /* Incorect args. */
1343 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1346 return 1; /* Success. */
1347 return allocate_tok (tok
, ntok
- 1, cidx
);
1350 /* Check if an particular ARC feature is enabled. */
1353 check_cpu_feature (insn_subclass_t sc
)
1355 if (!(arc_features
& ARC_CD
)
1356 && is_code_density_p (sc
))
1359 if (!(arc_features
& ARC_SPFP
)
1363 if (!(arc_features
& ARC_DPFP
)
1367 if (!(arc_features
& ARC_FPUDA
)
1374 /* Search forward through all variants of an opcode looking for a
1377 static const struct arc_opcode
*
1378 find_opcode_match (const struct arc_opcode
*first_opcode
,
1381 struct arc_flags
*first_pflag
,
1385 const struct arc_opcode
*opcode
= first_opcode
;
1387 int got_cpu_match
= 0;
1388 expressionS bktok
[MAX_INSN_ARGS
];
1392 memset (&emptyE
, 0, sizeof (emptyE
));
1393 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1398 const unsigned char *opidx
;
1399 const unsigned char *flgidx
;
1400 int tokidx
= 0, lnflg
, i
;
1401 const expressionS
*t
= &emptyE
;
1403 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1404 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1406 /* Don't match opcodes that don't exist on this
1408 if (!(opcode
->cpu
& arc_target
))
1411 if (!check_cpu_feature (opcode
->subclass
))
1417 /* Check the operands. */
1418 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1420 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1422 /* Only take input from real operands. */
1423 if ((operand
->flags
& ARC_OPERAND_FAKE
)
1424 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
1427 /* When we expect input, make sure we have it. */
1431 /* Match operand type with expression type. */
1432 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1434 case ARC_OPERAND_IR
:
1435 /* Check to be a register. */
1436 if ((tok
[tokidx
].X_op
!= O_register
1437 || !is_ir_num (tok
[tokidx
].X_add_number
))
1438 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1441 /* If expect duplicate, make sure it is duplicate. */
1442 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1444 /* Check for duplicate. */
1445 if (t
->X_op
!= O_register
1446 || !is_ir_num (t
->X_add_number
)
1447 || (regno (t
->X_add_number
) !=
1448 regno (tok
[tokidx
].X_add_number
)))
1452 /* Special handling? */
1453 if (operand
->insert
)
1455 const char *errmsg
= NULL
;
1456 (*operand
->insert
)(0,
1457 regno (tok
[tokidx
].X_add_number
),
1461 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1463 /* Missing argument, create one. */
1464 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1467 tok
[tokidx
].X_op
= O_absent
;
1478 case ARC_OPERAND_BRAKET
:
1479 /* Check if bracket is also in opcode table as
1481 if (tok
[tokidx
].X_op
!= O_bracket
)
1485 case ARC_OPERAND_LIMM
:
1486 case ARC_OPERAND_SIGNED
:
1487 case ARC_OPERAND_UNSIGNED
:
1488 switch (tok
[tokidx
].X_op
)
1496 /* Got an (too) early bracket, check if it is an
1497 ignored operand. N.B. This procedure works only
1498 when bracket is the last operand! */
1499 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1501 /* Insert the missing operand. */
1502 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1505 tok
[tokidx
].X_op
= O_absent
;
1510 /* Check the range. */
1511 if (operand
->bits
!= 32
1512 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1514 offsetT min
, max
, val
;
1515 val
= tok
[tokidx
].X_add_number
;
1517 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1519 max
= (1 << (operand
->bits
- 1)) - 1;
1520 min
= -(1 << (operand
->bits
- 1));
1524 max
= (1 << operand
->bits
) - 1;
1528 if (val
< min
|| val
> max
)
1531 /* Check alignmets. */
1532 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1536 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1540 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1542 if (operand
->insert
)
1544 const char *errmsg
= NULL
;
1545 (*operand
->insert
)(0,
1546 tok
[tokidx
].X_add_number
,
1557 /* Check if it is register range. */
1558 if ((tok
[tokidx
].X_add_number
== 0)
1559 && contains_register (tok
[tokidx
].X_add_symbol
)
1560 && contains_register (tok
[tokidx
].X_op_symbol
))
1564 regs
= get_register (tok
[tokidx
].X_add_symbol
);
1566 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
1567 if (operand
->insert
)
1569 const char *errmsg
= NULL
;
1570 (*operand
->insert
)(0,
1581 if (operand
->default_reloc
== 0)
1582 goto match_failed
; /* The operand needs relocation. */
1584 /* Relocs requiring long immediate. FIXME! make it
1585 generic and move it to a function. */
1586 switch (tok
[tokidx
].X_md
)
1595 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
1598 if (!generic_reloc_p (operand
->default_reloc
))
1605 /* If expect duplicate, make sure it is duplicate. */
1606 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1608 if (t
->X_op
== O_illegal
1609 || t
->X_op
== O_absent
1610 || t
->X_op
== O_register
1611 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
1618 /* Everything else should have been fake. */
1626 /* Setup ready for flag parsing. */
1628 for (i
= 0; i
< nflgs
; i
++)
1629 first_pflag
[i
].code
= 0;
1631 /* Check the flags. Iterate over the valid flag classes. */
1632 for (flgidx
= opcode
->flags
; *flgidx
; ++flgidx
)
1634 /* Get a valid flag class. */
1635 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1636 const unsigned *flgopridx
;
1639 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1641 const struct arc_flag_operand
*flg_operand
;
1642 struct arc_flags
*pflag
= first_pflag
;
1644 flg_operand
= &arc_flag_operands
[*flgopridx
];
1645 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1647 /* Match against the parsed flags. */
1648 if (!strcmp (flg_operand
->name
, pflag
->name
))
1650 if (pflag
->code
!= 0)
1653 pflag
->code
= *flgopridx
;
1655 break; /* goto next flag class and parsed flag. */
1660 if (cl_flags
->class == F_CLASS_REQUIRED
&& cl_matches
== 0)
1662 if (cl_flags
->class == F_CLASS_OPTIONAL
&& cl_matches
> 1)
1665 /* Did I check all the parsed flags? */
1670 /* Possible match -- did we use all of our input? */
1680 /* Restore the original parameters. */
1681 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
1684 while (++opcode
- arc_opcodes
< (int) arc_num_opcodes
1685 && !strcmp (opcode
->name
, first_opcode
->name
));
1688 *pcpumatch
= got_cpu_match
;
1693 /* Swap operand tokens. */
1696 swap_operand (expressionS
*operand_array
,
1698 unsigned destination
)
1700 expressionS cpy_operand
;
1701 expressionS
*src_operand
;
1702 expressionS
*dst_operand
;
1705 if (source
== destination
)
1708 src_operand
= &operand_array
[source
];
1709 dst_operand
= &operand_array
[destination
];
1710 size
= sizeof (expressionS
);
1712 /* Make copy of operand to swap with and swap. */
1713 memcpy (&cpy_operand
, dst_operand
, size
);
1714 memcpy (dst_operand
, src_operand
, size
);
1715 memcpy (src_operand
, &cpy_operand
, size
);
1718 /* Check if *op matches *tok type.
1719 Returns FALSE if they don't match, TRUE if they match. */
1722 pseudo_operand_match (const expressionS
*tok
,
1723 const struct arc_operand_operation
*op
)
1725 offsetT min
, max
, val
;
1727 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
1733 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
1735 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
1737 val
= tok
->X_add_number
+ op
->count
;
1738 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
1740 max
= (1 << (operand_real
->bits
- 1)) - 1;
1741 min
= -(1 << (operand_real
->bits
- 1));
1745 max
= (1 << operand_real
->bits
) - 1;
1748 if (min
<= val
&& val
<= max
)
1754 /* Handle all symbols as long immediates or signed 9. */
1755 if (operand_real
->flags
& ARC_OPERAND_LIMM
||
1756 ((operand_real
->flags
& ARC_OPERAND_SIGNED
) && operand_real
->bits
== 9))
1761 if (operand_real
->flags
& ARC_OPERAND_IR
)
1766 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
1777 /* Find pseudo instruction in array. */
1779 static const struct arc_pseudo_insn
*
1780 find_pseudo_insn (const char *opname
,
1782 const expressionS
*tok
)
1784 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
1785 const struct arc_operand_operation
*op
;
1789 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
1791 pseudo_insn
= &arc_pseudo_insns
[i
];
1792 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
1794 op
= pseudo_insn
->operand
;
1795 for (j
= 0; j
< ntok
; ++j
)
1796 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
1799 /* Found the right instruction. */
1807 /* Assumes the expressionS *tok is of sufficient size. */
1809 static const struct arc_opcode
*
1810 find_special_case_pseudo (const char *opname
,
1814 struct arc_flags
*pflags
)
1816 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
1817 const struct arc_operand_operation
*operand_pseudo
;
1818 const struct arc_operand
*operand_real
;
1820 char construct_operand
[MAX_CONSTR_STR
];
1822 /* Find whether opname is in pseudo instruction array. */
1823 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
1825 if (pseudo_insn
== NULL
)
1828 /* Handle flag, Limited to one flag at the moment. */
1829 if (pseudo_insn
->flag_r
!= NULL
)
1830 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
1831 MAX_INSN_FLGS
- *nflgs
);
1833 /* Handle operand operations. */
1834 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
1836 operand_pseudo
= &pseudo_insn
->operand
[i
];
1837 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
1839 if (operand_real
->flags
& ARC_OPERAND_BRAKET
&&
1840 !operand_pseudo
->needs_insert
)
1843 /* Has to be inserted (i.e. this token does not exist yet). */
1844 if (operand_pseudo
->needs_insert
)
1846 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
1848 tok
[i
].X_op
= O_bracket
;
1853 /* Check if operand is a register or constant and handle it
1855 if (operand_real
->flags
& ARC_OPERAND_IR
)
1856 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
1857 operand_pseudo
->count
);
1859 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
1860 operand_pseudo
->count
);
1862 tokenize_arguments (construct_operand
, &tok
[i
], 1);
1866 else if (operand_pseudo
->count
)
1868 /* Operand number has to be adjusted accordingly (by operand
1870 switch (tok
[i
].X_op
)
1873 tok
[i
].X_add_number
+= operand_pseudo
->count
;
1886 /* Swap operands if necessary. Only supports one swap at the
1888 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
1890 operand_pseudo
= &pseudo_insn
->operand
[i
];
1892 if (operand_pseudo
->swap_operand_idx
== i
)
1895 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
1897 /* Prevent a swap back later by breaking out. */
1901 return (const struct arc_opcode
*)
1902 hash_find (arc_opcode_hash
, pseudo_insn
->mnemonic_r
);
1905 static const struct arc_opcode
*
1906 find_special_case_flag (const char *opname
,
1908 struct arc_flags
*pflags
)
1912 unsigned flag_idx
, flag_arr_idx
;
1913 size_t flaglen
, oplen
;
1914 const struct arc_flag_special
*arc_flag_special_opcode
;
1915 const struct arc_opcode
*opcode
;
1917 /* Search for special case instruction. */
1918 for (i
= 0; i
< arc_num_flag_special
; i
++)
1920 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
1921 oplen
= strlen (arc_flag_special_opcode
->name
);
1923 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
1926 /* Found a potential special case instruction, now test for
1928 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
1930 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
1932 break; /* End of array, nothing found. */
1934 flagnm
= arc_flag_operands
[flag_idx
].name
;
1935 flaglen
= strlen (flagnm
);
1936 if (strcmp (opname
+ oplen
, flagnm
) == 0)
1938 opcode
= (const struct arc_opcode
*)
1939 hash_find (arc_opcode_hash
,
1940 arc_flag_special_opcode
->name
);
1942 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
1944 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
1945 pflags
[*nflgs
].name
[flaglen
] = '\0';
1954 /* Used to find special case opcode. */
1956 static const struct arc_opcode
*
1957 find_special_case (const char *opname
,
1959 struct arc_flags
*pflags
,
1963 const struct arc_opcode
*opcode
;
1965 opcode
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
1968 opcode
= find_special_case_flag (opname
, nflgs
, pflags
);
1974 preprocess_operands (const struct arc_opcode
*opcode
,
1982 const struct arc_aux_reg
*auxr
;
1984 for (i
= 0; i
< ntok
; i
++)
1986 switch (tok
[i
].X_op
)
1990 break; /* Throw and error. */
1993 if (opcode
->class != AUXREG
)
1995 /* Convert the symbol to a constant if possible. */
1996 p
= S_GET_NAME (tok
[i
].X_add_symbol
);
1999 auxr
= &arc_aux_regs
[0];
2000 for (j
= 0; j
< arc_num_aux_regs
; j
++, auxr
++)
2001 if (len
== auxr
->length
2002 && (strcasecmp (auxr
->name
, p
) == 0)
2003 && ((auxr
->subclass
== NONE
)
2004 || check_cpu_feature (auxr
->subclass
)))
2006 tok
[i
].X_op
= O_constant
;
2007 tok
[i
].X_add_number
= auxr
->address
;
2017 /* Given an opcode name, pre-tockenized set of argumenst and the
2018 opcode flags, take it all the way through emission. */
2021 assemble_tokens (const char *opname
,
2024 struct arc_flags
*pflags
,
2027 bfd_boolean found_something
= FALSE
;
2028 const struct arc_opcode
*opcode
;
2031 /* Search opcodes. */
2032 opcode
= (const struct arc_opcode
*) hash_find (arc_opcode_hash
, opname
);
2034 /* Couldn't find opcode conventional way, try special cases. */
2036 opcode
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
2040 pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
2041 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
2044 preprocess_operands (opcode
, tok
, ntok
);
2046 found_something
= TRUE
;
2047 opcode
= find_opcode_match (opcode
, tok
, &ntok
, pflags
, nflgs
, &cpumatch
);
2050 struct arc_insn insn
;
2051 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
2057 if (found_something
)
2060 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
2062 as_bad (_("opcode '%s' not supported for target %s"), opname
,
2066 as_bad (_("unknown opcode '%s'"), opname
);
2069 /* The public interface to the instruction assembler. */
2072 md_assemble (char *str
)
2075 expressionS tok
[MAX_INSN_ARGS
];
2078 struct arc_flags flags
[MAX_INSN_FLGS
];
2080 /* Split off the opcode. */
2081 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
2082 opname
= xmalloc (opnamelen
+ 1);
2083 memcpy (opname
, str
, opnamelen
);
2084 opname
[opnamelen
] = '\0';
2086 /* Signalize we are assmbling the instructions. */
2087 assembling_insn
= TRUE
;
2089 /* Tokenize the flags. */
2090 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2092 as_bad (_("syntax error"));
2096 /* Scan up to the end of the mnemonic which must end in space or end
2099 for (; *str
!= '\0'; str
++)
2103 /* Tokenize the rest of the line. */
2104 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2106 as_bad (_("syntax error"));
2110 /* Finish it off. */
2111 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2112 assembling_insn
= FALSE
;
2115 /* Callback to insert a register into the hash table. */
2118 declare_register (const char *name
, int number
)
2121 symbolS
*regS
= symbol_create (name
, reg_section
,
2122 number
, &zero_address_frag
);
2124 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
2126 as_fatal ("Inserting \"%s\" into register table failed: %s",
2130 /* Construct symbols for each of the general registers. */
2133 declare_register_set (void)
2136 for (i
= 0; i
< 64; ++i
)
2140 sprintf (name
, "r%d", i
);
2141 declare_register (name
, i
);
2142 if ((i
& 0x01) == 0)
2144 sprintf (name
, "r%dr%d", i
, i
+1);
2145 declare_register (name
, i
);
2150 /* Port-specific assembler initialization. This function is called
2151 once, at assembler startup time. */
2158 if (!mach_type_specified_p
)
2159 arc_select_cpu ("arc700");
2161 /* The endianness can be chosen "at the factory". */
2162 target_big_endian
= byte_order
== BIG_ENDIAN
;
2164 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, arc_mach_type
))
2165 as_warn (_("could not set architecture and machine"));
2167 /* Set elf header flags. */
2168 bfd_set_private_flags (stdoutput
, arc_eflag
);
2170 /* Set up a hash table for the instructions. */
2171 arc_opcode_hash
= hash_new ();
2172 if (arc_opcode_hash
== NULL
)
2173 as_fatal (_("Virtual memory exhausted"));
2175 /* Initialize the hash table with the insns. */
2176 for (i
= 0; i
< arc_num_opcodes
;)
2178 const char *name
, *retval
;
2180 name
= arc_opcodes
[i
].name
;
2181 retval
= hash_insert (arc_opcode_hash
, name
, (void *) &arc_opcodes
[i
]);
2183 as_fatal (_("internal error: can't hash opcode '%s': %s"),
2186 while (++i
< arc_num_opcodes
2187 && (arc_opcodes
[i
].name
== name
2188 || !strcmp (arc_opcodes
[i
].name
, name
)))
2192 /* Register declaration. */
2193 arc_reg_hash
= hash_new ();
2194 if (arc_reg_hash
== NULL
)
2195 as_fatal (_("Virtual memory exhausted"));
2197 declare_register_set ();
2198 declare_register ("gp", 26);
2199 declare_register ("fp", 27);
2200 declare_register ("sp", 28);
2201 declare_register ("ilink", 29);
2202 declare_register ("ilink1", 29);
2203 declare_register ("ilink2", 30);
2204 declare_register ("blink", 31);
2206 declare_register ("mlo", 57);
2207 declare_register ("mmid", 58);
2208 declare_register ("mhi", 59);
2210 declare_register ("acc1", 56);
2211 declare_register ("acc2", 57);
2213 declare_register ("lp_count", 60);
2214 declare_register ("pcl", 63);
2216 /* Initialize the last instructions. */
2217 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2220 /* Write a value out to the object file, using the appropriate
2224 md_number_to_chars (char *buf
,
2228 if (target_big_endian
)
2229 number_to_chars_bigendian (buf
, val
, n
);
2231 number_to_chars_littleendian (buf
, val
, n
);
2234 /* Round up a section size to the appropriate boundary. */
2237 md_section_align (segT segment
,
2240 int align
= bfd_get_section_alignment (stdoutput
, segment
);
2242 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2245 /* The location from which a PC relative jump should be calculated,
2246 given a PC relative reloc. */
2249 md_pcrel_from_section (fixS
*fixP
,
2252 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2254 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2256 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2257 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2258 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2260 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2262 /* The symbol is undefined (or is defined but not in this section).
2263 Let the linker figure it out. */
2267 if ((int) fixP
->fx_r_type
< 0)
2269 /* These are the "internal" relocations. Align them to
2270 32 bit boundary (PCL), for the moment. */
2275 switch (fixP
->fx_r_type
)
2277 case BFD_RELOC_ARC_PC32
:
2278 /* The hardware calculates relative to the start of the
2279 insn, but this relocation is relative to location of the
2280 LIMM, compensate. The base always needs to be
2281 substracted by 4 as we do not support this type of PCrel
2282 relocation for short instructions. */
2285 case BFD_RELOC_ARC_PLT32
:
2286 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2287 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2288 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2289 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2291 case BFD_RELOC_ARC_S21H_PCREL
:
2292 case BFD_RELOC_ARC_S25H_PCREL
:
2293 case BFD_RELOC_ARC_S13_PCREL
:
2294 case BFD_RELOC_ARC_S21W_PCREL
:
2295 case BFD_RELOC_ARC_S25W_PCREL
:
2299 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2300 _("unhandled reloc %s in md_pcrel_from_section"),
2301 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2306 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
2307 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
2308 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2309 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
2314 /* Given a BFD relocation find the coresponding operand. */
2316 static const struct arc_operand
*
2317 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2321 for (i
= 0; i
< arc_num_operands
; i
++)
2322 if (arc_operands
[i
].default_reloc
== reloc
)
2323 return &arc_operands
[i
];
2327 /* Insert an operand value into an instruction. */
2330 insert_operand (unsigned insn
,
2331 const struct arc_operand
*operand
,
2336 offsetT min
= 0, max
= 0;
2338 if (operand
->bits
!= 32
2339 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2340 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2342 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2344 max
= (1 << (operand
->bits
- 1)) - 1;
2345 min
= -(1 << (operand
->bits
- 1));
2349 max
= (1 << operand
->bits
) - 1;
2353 if (val
< min
|| val
> max
)
2354 as_bad_value_out_of_range (_("operand"),
2355 val
, min
, max
, file
, line
);
2358 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2359 min
, val
, max
, insn
);
2361 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2363 as_bad_where (file
, line
,
2364 _("Unaligned operand. Needs to be 32bit aligned"));
2366 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2368 as_bad_where (file
, line
,
2369 _("Unaligned operand. Needs to be 16bit aligned"));
2371 if (operand
->insert
)
2373 const char *errmsg
= NULL
;
2375 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2377 as_warn_where (file
, line
, "%s", errmsg
);
2381 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2383 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2385 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2388 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2393 /* Apply a fixup to the object code. At this point all symbol values
2394 should be fully resolved, and we attempt to completely resolve the
2395 reloc. If we can not do that, we determine the correct reloc code
2396 and put it back in the fixup. To indicate that a fixup has been
2397 eliminated, set fixP->fx_done. */
2400 md_apply_fix (fixS
*fixP
,
2404 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2405 valueT value
= *valP
;
2407 symbolS
*fx_addsy
, *fx_subsy
;
2409 segT add_symbol_segment
= absolute_section
;
2410 segT sub_symbol_segment
= absolute_section
;
2411 const struct arc_operand
*operand
= NULL
;
2412 extended_bfd_reloc_code_real_type reloc
;
2414 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2415 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2416 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2417 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2420 fx_addsy
= fixP
->fx_addsy
;
2421 fx_subsy
= fixP
->fx_subsy
;
2426 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2430 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2431 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2432 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2434 resolve_symbol_value (fx_subsy
);
2435 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2437 if (sub_symbol_segment
== absolute_section
)
2439 /* The symbol is really a constant. */
2440 fx_offset
-= S_GET_VALUE (fx_subsy
);
2445 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2446 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2447 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
2448 segment_name (add_symbol_segment
),
2449 S_GET_NAME (fx_subsy
),
2450 segment_name (sub_symbol_segment
));
2456 && !S_IS_WEAK (fx_addsy
))
2458 if (add_symbol_segment
== seg
2461 value
+= S_GET_VALUE (fx_addsy
);
2462 value
-= md_pcrel_from_section (fixP
, seg
);
2464 fixP
->fx_pcrel
= FALSE
;
2466 else if (add_symbol_segment
== absolute_section
)
2468 value
= fixP
->fx_offset
;
2469 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2471 fixP
->fx_pcrel
= FALSE
;
2476 fixP
->fx_done
= TRUE
;
2481 && ((S_IS_DEFINED (fx_addsy
)
2482 && S_GET_SEGMENT (fx_addsy
) != seg
)
2483 || S_IS_WEAK (fx_addsy
)))
2484 value
+= md_pcrel_from_section (fixP
, seg
);
2486 switch (fixP
->fx_r_type
)
2488 case BFD_RELOC_ARC_32_ME
:
2489 /* This is a pc-relative value in a LIMM. Adjust it to the
2490 address of the instruction not to the address of the
2491 LIMM. Note: it is not anylonger valid this afirmation as
2492 the linker consider ARC_PC32 a fixup to entire 64 bit
2494 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
2497 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
2499 case BFD_RELOC_ARC_PC32
:
2500 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2503 if ((int) fixP
->fx_r_type
< 0)
2504 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2510 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2511 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2512 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2513 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2517 /* Now check for TLS relocations. */
2518 reloc
= fixP
->fx_r_type
;
2521 case BFD_RELOC_ARC_TLS_DTPOFF
:
2522 case BFD_RELOC_ARC_TLS_LE_32
:
2526 case BFD_RELOC_ARC_TLS_GD_GOT
:
2527 case BFD_RELOC_ARC_TLS_IE_GOT
:
2528 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2531 case BFD_RELOC_ARC_TLS_GD_LD
:
2532 gas_assert (!fixP
->fx_offset
);
2535 = (S_GET_VALUE (fixP
->fx_subsy
)
2536 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
2537 fixP
->fx_subsy
= NULL
;
2539 case BFD_RELOC_ARC_TLS_GD_CALL
:
2540 /* These two relocs are there just to allow ld to change the tls
2541 model for this symbol, by patching the code. The offset -
2542 and scale, if any - will be installed by the linker. */
2543 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2546 case BFD_RELOC_ARC_TLS_LE_S9
:
2547 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
2548 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2560 /* Addjust the value if we have a constant. */
2563 /* For hosts with longs bigger than 32-bits make sure that the top
2564 bits of a 32-bit negative value read in by the parser are set,
2565 so that the correct comparisons are made. */
2566 if (value
& 0x80000000)
2567 value
|= (-1L << 31);
2569 reloc
= fixP
->fx_r_type
;
2577 case BFD_RELOC_ARC_32_PCREL
:
2578 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
2581 case BFD_RELOC_ARC_GOTPC32
:
2582 /* I cannot fix an GOTPC relocation because I need to relax it
2583 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2584 as_bad (_("Unsupported operation on reloc"));
2587 case BFD_RELOC_ARC_TLS_DTPOFF
:
2588 case BFD_RELOC_ARC_TLS_LE_32
:
2589 gas_assert (!fixP
->fx_addsy
);
2590 gas_assert (!fixP
->fx_subsy
);
2592 case BFD_RELOC_ARC_GOTOFF
:
2593 case BFD_RELOC_ARC_32_ME
:
2594 case BFD_RELOC_ARC_PC32
:
2595 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2598 case BFD_RELOC_ARC_PLT32
:
2599 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2602 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2603 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2606 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2607 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
2610 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2611 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2614 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2615 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
2617 case BFD_RELOC_ARC_S25W_PCREL
:
2618 case BFD_RELOC_ARC_S21W_PCREL
:
2619 case BFD_RELOC_ARC_S21H_PCREL
:
2620 case BFD_RELOC_ARC_S25H_PCREL
:
2621 case BFD_RELOC_ARC_S13_PCREL
:
2623 operand
= find_operand_for_reloc (reloc
);
2624 gas_assert (operand
);
2629 if ((int) fixP
->fx_r_type
>= 0)
2630 as_fatal (_("unhandled relocation type %s"),
2631 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2633 /* The rest of these fixups needs to be completely resolved as
2635 if (fixP
->fx_addsy
!= 0
2636 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
2637 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2638 _("non-absolute expression in constant field"));
2640 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
2641 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
2646 if (target_big_endian
)
2648 switch (fixP
->fx_size
)
2651 insn
= bfd_getb32 (fixpos
);
2654 insn
= bfd_getb16 (fixpos
);
2657 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2658 _("unknown fixup size"));
2664 switch (fixP
->fx_size
)
2667 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
2670 insn
= bfd_getl16 (fixpos
);
2673 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2674 _("unknown fixup size"));
2678 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
2679 fixP
->fx_file
, fixP
->fx_line
);
2681 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
2684 /* Prepare machine-dependent frags for relaxation.
2686 Called just before relaxation starts. Any symbol that is now undefined
2687 will not become defined.
2689 Return the correct fr_subtype in the frag.
2691 Return the initial "guess for fr_var" to caller. The guess for fr_var
2692 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
2693 or fr_var contributes to our returned value.
2695 Although it may not be explicit in the frag, pretend
2696 fr_var starts with a value. */
2699 md_estimate_size_before_relax (fragS
*fragP
,
2704 /* If the symbol is not located within the same section AND it's not
2705 an absolute section, use the maximum. OR if the symbol is a
2706 constant AND the insn is by nature not pc-rel, use the maximum.
2707 OR if the symbol is being equated against another symbol, use the
2708 maximum. OR if the symbol is weak use the maximum. */
2709 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
2710 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2711 || (symbol_constant_p (fragP
->fr_symbol
)
2712 && !fragP
->tc_frag_data
.pcrel
)
2713 || symbol_equated_p (fragP
->fr_symbol
)
2714 || S_IS_WEAK (fragP
->fr_symbol
))
2716 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
2717 ++fragP
->fr_subtype
;
2720 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2721 fragP
->fr_var
= growth
;
2723 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
2724 fragP
->fr_file
, fragP
->fr_line
, growth
);
2729 /* Translate internal representation of relocation info to BFD target
2733 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
2737 bfd_reloc_code_real_type code
;
2739 reloc
= (arelent
*) xmalloc (sizeof (* reloc
));
2740 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2741 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
2742 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2744 /* Make sure none of our internal relocations make it this far.
2745 They'd better have been fully resolved by this point. */
2746 gas_assert ((int) fixP
->fx_r_type
> 0);
2748 code
= fixP
->fx_r_type
;
2750 /* if we have something like add gp, pcl,
2751 _GLOBAL_OFFSET_TABLE_@gotpc. */
2752 if (code
== BFD_RELOC_ARC_GOTPC32
2754 && fixP
->fx_addsy
== GOT_symbol
)
2755 code
= BFD_RELOC_ARC_GOTPC
;
2757 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2758 if (reloc
->howto
== NULL
)
2760 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2761 _("cannot represent `%s' relocation in object file"),
2762 bfd_get_reloc_code_name (code
));
2766 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
2767 as_fatal (_("internal error? cannot generate `%s' relocation"),
2768 bfd_get_reloc_code_name (code
));
2770 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
2772 if (code
== BFD_RELOC_ARC_TLS_DTPOFF
2773 || code
== BFD_RELOC_ARC_TLS_DTPOFF_S9
)
2776 = fixP
->fx_subsy
? symbol_get_bfdsym (fixP
->fx_subsy
) : NULL
;
2777 /* We just want to store a 24 bit index, but we have to wait
2778 till after write_contents has been called via
2779 bfd_map_over_sections before we can get the index from
2780 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
2781 function is elf32-arc.c has to pick up the slack.
2782 Unfortunately, this leads to problems with hosts that have
2783 pointers wider than long (bfd_vma). There would be various
2784 ways to handle this, all error-prone :-( */
2785 reloc
->addend
= (bfd_vma
) sym
;
2786 if ((asymbol
*) reloc
->addend
!= sym
)
2788 as_bad ("Can't store pointer\n");
2793 reloc
->addend
= fixP
->fx_offset
;
2798 /* Perform post-processing of machine-dependent frags after relaxation.
2799 Called after relaxation is finished.
2800 In: Address of frag.
2801 fr_type == rs_machine_dependent.
2802 fr_subtype is what the address relaxed to.
2804 Out: Any fixS:s and constants are set up. */
2807 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
2808 segT segment ATTRIBUTE_UNUSED
,
2811 const relax_typeS
*table_entry
;
2813 const struct arc_opcode
*opcode
;
2814 struct arc_insn insn
;
2816 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
2818 fix
= (fragP
->fr_fix
< 0 ? 0 : fragP
->fr_fix
);
2819 dest
= fragP
->fr_literal
+ fix
;
2820 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
2822 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
2823 fragP
->fr_file
, fragP
->fr_line
,
2824 fragP
->fr_subtype
, fix
, fragP
->fr_var
);
2826 if (fragP
->fr_subtype
<= 0
2827 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
2828 as_fatal (_("no relaxation found for this instruction."));
2830 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
2832 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
2833 relax_arg
->nflg
, &insn
);
2835 apply_fixups (&insn
, fragP
, fix
);
2837 size
= insn
.short_insn
? (insn
.has_limm
? 6 : 2) : (insn
.has_limm
? 8 : 4);
2838 gas_assert (table_entry
->rlx_length
== size
);
2839 emit_insn0 (&insn
, dest
, TRUE
);
2841 fragP
->fr_fix
+= table_entry
->rlx_length
;
2845 /* We have no need to default values of symbols. We could catch
2846 register names here, but that is handled by inserting them all in
2847 the symbol table to begin with. */
2850 md_undefined_symbol (char *name
)
2852 /* The arc abi demands that a GOT[0] should be referencible as
2853 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
2854 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
2856 && (*(name
+1) == 'G')
2857 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0))
2859 && (*(name
+1) == 'D')
2860 && (strcmp (name
, DYNAMIC_STRUCT_NAME
) == 0)))
2864 if (symbol_find (name
))
2865 as_bad ("GOT already in symbol table");
2867 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
2868 (valueT
) 0, &zero_address_frag
);
2875 /* Turn a string in input_line_pointer into a floating point constant
2876 of type type, and store the appropriate bytes in *litP. The number
2877 of LITTLENUMS emitted is stored in *sizeP. An error message is
2878 returned, or NULL on OK. */
2881 md_atof (int type
, char *litP
, int *sizeP
)
2883 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
2886 /* Called for any expression that can not be recognized. When the
2887 function is called, `input_line_pointer' will point to the start of
2891 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2893 char *p
= input_line_pointer
;
2896 input_line_pointer
++;
2897 expressionP
->X_op
= O_symbol
;
2898 expression (expressionP
);
2902 /* This function is called from the function 'expression', it attempts
2903 to parse special names (in our case register names). It fills in
2904 the expression with the identified register. It returns TRUE if
2905 it is a register and FALSE otherwise. */
2908 arc_parse_name (const char *name
,
2909 struct expressionS
*e
)
2913 if (!assembling_insn
)
2916 /* Handle only registers. */
2917 if (e
->X_op
!= O_absent
)
2920 sym
= hash_find (arc_reg_hash
, name
);
2923 e
->X_op
= O_register
;
2924 e
->X_add_number
= S_GET_VALUE (sym
);
2931 Invocation line includes a switch not recognized by the base assembler.
2932 See if it's a processor-specific option.
2934 New options (supported) are:
2936 -mcpu=<cpu name> Assemble for selected processor
2937 -EB/-mbig-endian Big-endian
2938 -EL/-mlittle-endian Little-endian
2939 -mrelax Enable relaxation
2941 The following CPU names are recognized:
2942 arc700, av2em, av2hs. */
2945 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
2951 return md_parse_option (OPTION_MCPU
, "arc600");
2954 return md_parse_option (OPTION_MCPU
, "arc700");
2957 return md_parse_option (OPTION_MCPU
, "arcem");
2960 return md_parse_option (OPTION_MCPU
, "archs");
2964 arc_select_cpu (arg
);
2965 mach_type_specified_p
= 1;
2970 arc_target_format
= "elf32-bigarc";
2971 byte_order
= BIG_ENDIAN
;
2975 arc_target_format
= "elf32-littlearc";
2976 byte_order
= LITTLE_ENDIAN
;
2980 /* This option has an effect only on ARC EM. */
2981 if (arc_target
& ARC_OPCODE_ARCv2EM
)
2982 arc_features
|= ARC_CD
;
2984 as_warn (_("Code density option invalid for selected CPU"));
2988 relaxation_state
= 1;
2991 case OPTION_USER_MODE
:
2992 case OPTION_LD_EXT_MASK
:
2995 case OPTION_BARREL_SHIFT
:
2996 case OPTION_MIN_MAX
:
3001 /* Dummy options are accepted but have no effect. */
3005 arc_features
|= ARC_SPFP
;
3009 arc_features
|= ARC_DPFP
;
3012 case OPTION_XMAC_D16
:
3013 case OPTION_XMAC_24
:
3014 case OPTION_DSP_PACKA
:
3017 case OPTION_TELEPHONY
:
3018 case OPTION_XYMEMORY
:
3022 /* Dummy options are accepted but have no effect. */
3026 /* This option has an effect only on ARC EM. */
3027 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3028 arc_features
|= ARC_FPUDA
;
3030 as_warn (_("FPUDA invalid for selected CPU"));
3041 md_show_usage (FILE *stream
)
3043 fprintf (stream
, _("ARC-specific assembler options:\n"));
3045 fprintf (stream
, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
3047 " -mcode-density\t enable code density option for ARC EM\n");
3049 fprintf (stream
, _("\
3050 -EB assemble code for a big-endian cpu\n"));
3051 fprintf (stream
, _("\
3052 -EL assemble code for a little-endian cpu\n"));
3053 fprintf (stream
, _("\
3054 -mrelax Enable relaxation\n"));
3058 /* Find the proper relocation for the given opcode. */
3060 static extended_bfd_reloc_code_real_type
3061 find_reloc (const char *name
,
3062 const char *opcodename
,
3063 const struct arc_flags
*pflags
,
3065 extended_bfd_reloc_code_real_type reloc
)
3069 bfd_boolean found_flag
, tmp
;
3070 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
3072 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
3074 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3076 /* Find the entry. */
3077 if (strcmp (name
, r
->name
))
3079 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3086 unsigned * psflg
= (unsigned *)r
->flags
;
3090 for (j
= 0; j
< nflg
; j
++)
3091 if (!strcmp (pflags
[j
].name
,
3092 arc_flag_operands
[*psflg
].name
))
3113 if (reloc
!= r
->oldreloc
)
3120 if (ret
== BFD_RELOC_UNUSED
)
3121 as_bad (_("Unable to find %s relocation for instruction %s"),
3126 /* All the symbol types that are allowed to be used for
3130 may_relax_expr (expressionS tok
)
3132 /* Check if we have unrelaxable relocs. */
3157 /* Checks if flags are in line with relaxable insn. */
3160 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3161 const struct arc_flags
*pflags
,
3164 unsigned flag_class
,
3169 const struct arc_flag_operand
*flag_opand
;
3170 int i
, counttrue
= 0;
3172 /* Iterate through flags classes. */
3173 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3175 /* Iterate through flags in flag class. */
3176 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3179 flag_opand
= &arc_flag_operands
[flag
];
3180 /* Iterate through flags in ins to compare. */
3181 for (i
= 0; i
< nflgs
; ++i
)
3183 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3194 /* If counttrue == nflgs, then all flags have been found. */
3195 return (counttrue
== nflgs
? TRUE
: FALSE
);
3198 /* Checks if operands are in line with relaxable insn. */
3201 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3202 const expressionS
*tok
,
3205 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3208 while (*operand
!= EMPTY
)
3210 const expressionS
*epr
= &tok
[i
];
3212 if (i
!= 0 && i
>= ntok
)
3218 if (!(epr
->X_op
== O_multiply
3219 || epr
->X_op
== O_divide
3220 || epr
->X_op
== O_modulus
3221 || epr
->X_op
== O_add
3222 || epr
->X_op
== O_subtract
3223 || epr
->X_op
== O_symbol
))
3229 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3233 if (epr
->X_op
!= O_register
)
3238 if (epr
->X_op
!= O_register
)
3241 switch (epr
->X_add_number
)
3243 case 0: case 1: case 2: case 3:
3244 case 12: case 13: case 14: case 15:
3251 case REGISTER_NO_GP
:
3252 if ((epr
->X_op
!= O_register
)
3253 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3258 if (epr
->X_op
!= O_bracket
)
3263 /* Don't understand, bail out. */
3269 operand
= &ins
->operands
[i
];
3272 return (i
== ntok
? TRUE
: FALSE
);
3275 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3278 relax_insn_p (const struct arc_opcode
*opcode
,
3279 const expressionS
*tok
,
3281 const struct arc_flags
*pflags
,
3285 bfd_boolean rv
= FALSE
;
3287 /* Check the relaxation table. */
3288 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3290 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3292 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3293 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3294 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3295 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3298 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3299 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3300 sizeof (expressionS
) * ntok
);
3301 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3302 sizeof (struct arc_flags
) * nflg
);
3303 frag_now
->tc_frag_data
.nflg
= nflg
;
3304 frag_now
->tc_frag_data
.ntok
= ntok
;
3312 /* Turn an opcode description and a set of arguments into
3313 an instruction and a fixup. */
3316 assemble_insn (const struct arc_opcode
*opcode
,
3317 const expressionS
*tok
,
3319 const struct arc_flags
*pflags
,
3321 struct arc_insn
*insn
)
3323 const expressionS
*reloc_exp
= NULL
;
3325 const unsigned char *argidx
;
3328 unsigned char pcrel
= 0;
3329 bfd_boolean needGOTSymbol
;
3330 bfd_boolean has_delay_slot
= FALSE
;
3331 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3333 memset (insn
, 0, sizeof (*insn
));
3334 image
= opcode
->opcode
;
3336 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3337 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3340 /* Handle operands. */
3341 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3343 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3344 const expressionS
*t
= (const expressionS
*) 0;
3346 if ((operand
->flags
& ARC_OPERAND_FAKE
)
3347 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
3350 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3352 /* Duplicate operand, already inserted. */
3364 /* Regardless if we have a reloc or not mark the instruction
3365 limm if it is the case. */
3366 if (operand
->flags
& ARC_OPERAND_LIMM
)
3367 insn
->has_limm
= TRUE
;
3372 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3377 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3379 if (operand
->flags
& ARC_OPERAND_LIMM
)
3380 insn
->limm
= t
->X_add_number
;
3384 /* Ignore brackets. */
3388 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3392 /* Maybe register range. */
3393 if ((t
->X_add_number
== 0)
3394 && contains_register (t
->X_add_symbol
)
3395 && contains_register (t
->X_op_symbol
))
3399 regs
= get_register (t
->X_add_symbol
);
3401 regs
|= get_register (t
->X_op_symbol
);
3402 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3407 /* This operand needs a relocation. */
3408 needGOTSymbol
= FALSE
;
3413 if (opcode
->class == JUMP
)
3414 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3415 _("Unable to use @plt relocatio for insn %s"),
3417 needGOTSymbol
= TRUE
;
3418 reloc
= find_reloc ("plt", opcode
->name
,
3420 operand
->default_reloc
);
3425 needGOTSymbol
= TRUE
;
3426 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3429 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3430 if (ARC_SHORT (opcode
->mask
) || opcode
->class == JUMP
)
3431 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3432 _("Unable to use @pcl relocation for insn %s"),
3436 reloc
= find_reloc ("sda", opcode
->name
,
3438 operand
->default_reloc
);
3442 needGOTSymbol
= TRUE
;
3447 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3450 case O_tpoff9
: /*FIXME! Check for the conditionality of
3452 case O_dtpoff9
: /*FIXME! Check for the conditionality of
3454 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3458 /* Just consider the default relocation. */
3459 reloc
= operand
->default_reloc
;
3463 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
3464 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
3471 /* sanity checks. */
3472 reloc_howto_type
*reloc_howto
3473 = bfd_reloc_type_lookup (stdoutput
,
3474 (bfd_reloc_code_real_type
) reloc
);
3475 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
3476 if (reloc_howto
->rightshift
)
3477 reloc_bitsize
-= reloc_howto
->rightshift
;
3478 if (reloc_bitsize
!= operand
->bits
)
3480 as_bad (_("invalid relocation %s for field"),
3481 bfd_get_reloc_code_name (reloc
));
3486 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3487 as_fatal (_("too many fixups"));
3489 struct arc_fixup
*fixup
;
3490 fixup
= &insn
->fixups
[insn
->nfixups
++];
3492 fixup
->reloc
= reloc
;
3493 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
3494 fixup
->pcrel
= pcrel
;
3495 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
3502 for (i
= 0; i
< nflg
; i
++)
3504 const struct arc_flag_operand
*flg_operand
=
3505 &arc_flag_operands
[pflags
[i
].code
];
3507 /* Check if the instruction has a delay slot. */
3508 if (!strcmp (flg_operand
->name
, "d"))
3509 has_delay_slot
= TRUE
;
3511 /* There is an exceptional case when we cannot insert a flag
3512 just as it is. The .T flag must be handled in relation with
3513 the relative address. */
3514 if (!strcmp (flg_operand
->name
, "t")
3515 || !strcmp (flg_operand
->name
, "nt"))
3517 unsigned bitYoperand
= 0;
3518 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3519 if (!strcmp (flg_operand
->name
, "t"))
3520 if (!strcmp (opcode
->name
, "bbit0")
3521 || !strcmp (opcode
->name
, "bbit1"))
3522 bitYoperand
= arc_NToperand
;
3524 bitYoperand
= arc_Toperand
;
3526 if (!strcmp (opcode
->name
, "bbit0")
3527 || !strcmp (opcode
->name
, "bbit1"))
3528 bitYoperand
= arc_Toperand
;
3530 bitYoperand
= arc_NToperand
;
3532 gas_assert (reloc_exp
!= NULL
);
3533 if (reloc_exp
->X_op
== O_constant
)
3535 /* Check if we have a constant and solved it
3537 offsetT val
= reloc_exp
->X_add_number
;
3538 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
3543 struct arc_fixup
*fixup
;
3545 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3546 as_fatal (_("too many fixups"));
3548 fixup
= &insn
->fixups
[insn
->nfixups
++];
3549 fixup
->exp
= *reloc_exp
;
3550 fixup
->reloc
= -bitYoperand
;
3551 fixup
->pcrel
= pcrel
;
3552 fixup
->islong
= FALSE
;
3556 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
3557 << flg_operand
->shift
;
3560 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
3562 /* Short instruction? */
3563 insn
->short_insn
= ARC_SHORT (opcode
->mask
) ? TRUE
: FALSE
;
3567 /* Update last insn status. */
3568 arc_last_insns
[1] = arc_last_insns
[0];
3569 arc_last_insns
[0].opcode
= opcode
;
3570 arc_last_insns
[0].has_limm
= insn
->has_limm
;
3571 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
3573 /* Check if the current instruction is legally used. */
3574 if (arc_last_insns
[1].has_delay_slot
3575 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3576 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3577 _("A jump/branch instruction in delay slot."));
3581 arc_handle_align (fragS
* fragP
)
3583 if ((fragP
)->fr_type
== rs_align_code
)
3585 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
3586 valueT count
= ((fragP
)->fr_next
->fr_address
3587 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
3589 (fragP
)->fr_var
= 2;
3591 if (count
& 1)/* Padding in the gap till the next 2-byte
3592 boundary with 0s. */
3597 /* Writing nop_s. */
3598 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
3602 /* Here we decide which fixups can be adjusted to make them relative
3603 to the beginning of the section instead of the symbol. Basically
3604 we need to make sure that the dynamic relocations are done
3605 correctly, so in some cases we force the original symbol to be
3609 tc_arc_fix_adjustable (fixS
*fixP
)
3612 /* Prevent all adjustments to global symbols. */
3613 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
3615 if (S_IS_WEAK (fixP
->fx_addsy
))
3618 /* Adjust_reloc_syms doesn't know about the GOT. */
3619 switch (fixP
->fx_r_type
)
3621 case BFD_RELOC_ARC_GOTPC32
:
3622 case BFD_RELOC_ARC_PLT32
:
3623 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
3624 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
3625 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
3626 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
3636 /* Compute the reloc type of an expression EXP. */
3639 arc_check_reloc (expressionS
*exp
,
3640 bfd_reloc_code_real_type
*r_type_p
)
3642 if (*r_type_p
== BFD_RELOC_32
3643 && exp
->X_op
== O_subtract
3644 && exp
->X_op_symbol
!= NULL
3645 && exp
->X_op_symbol
->bsym
->section
== now_seg
)
3646 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
3650 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3653 arc_cons_fix_new (fragS
*frag
,
3657 bfd_reloc_code_real_type r_type
)
3659 r_type
= BFD_RELOC_UNUSED
;
3664 r_type
= BFD_RELOC_8
;
3668 r_type
= BFD_RELOC_16
;
3672 r_type
= BFD_RELOC_24
;
3676 r_type
= BFD_RELOC_32
;
3677 arc_check_reloc (exp
, &r_type
);
3681 r_type
= BFD_RELOC_64
;
3685 as_bad (_("unsupported BFD relocation size %u"), size
);
3686 r_type
= BFD_RELOC_UNUSED
;
3689 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
3692 /* The actual routine that checks the ZOL conditions. */
3695 check_zol (symbolS
*s
)
3697 switch (arc_mach_type
)
3699 case bfd_mach_arc_arcv2
:
3700 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3703 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
3704 || arc_last_insns
[1].has_delay_slot
)
3705 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3709 case bfd_mach_arc_arc600
:
3711 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
3712 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3715 if (arc_last_insns
[0].has_limm
3716 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3717 as_bad (_("A jump instruction with long immediate detected at the \
3718 end of the ZOL label @%s"), S_GET_NAME (s
));
3721 case bfd_mach_arc_nps400
:
3722 case bfd_mach_arc_arc700
:
3723 if (arc_last_insns
[0].has_delay_slot
)
3724 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3733 /* If ZOL end check the last two instruction for illegals. */
3735 arc_frob_label (symbolS
* sym
)
3737 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
3740 dwarf2_emit_label (sym
);
3743 /* Used because generic relaxation assumes a pc-rel value whilst we
3744 also relax instructions that use an absolute value resolved out of
3745 relative values (if that makes any sense). An example: 'add r1,
3746 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
3747 but if they're in the same section we can subtract the section
3748 offset relocation which ends up in a resolved value. So if @.L2 is
3749 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
3750 .text + 0x40 = 0x10. */
3752 arc_pcrel_adjust (fragS
*fragP
)
3754 if (!fragP
->tc_frag_data
.pcrel
)
3755 return fragP
->fr_address
+ fragP
->fr_fix
;
3760 /* Initialize the DWARF-2 unwind information for this procedure. */
3763 tc_arc_frame_initial_instructions (void)
3765 /* Stack pointer is register 28. */
3766 cfi_add_CFA_def_cfa_register (28);
3770 tc_arc_regname_to_dw2regnum (char *regname
)
3774 sym
= hash_find (arc_reg_hash
, regname
);
3776 return S_GET_VALUE (sym
);